Merge branch 'prepare_for_master' of https://git.trustie.net/xuos/xiuos into control_framework

This commit is contained in:
Liu_Weichao 2022-12-09 13:55:45 +08:00
commit 6ef80903ce
167 changed files with 17166 additions and 2117 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

@ -11,4 +11,27 @@ config HC32F4A0_BOARD
---help---
Select if you are using the HC32F4A0 base board with the HC32F4A0.
config HC32_ROMFS
bool "Automount baked-in ROMFS image"
default n
depends on FS_ROMFS
---help---
Select HC32_ROMFS_IMAGEFILE, HC32_ROMFS_DEV_MINOR, HC32_ROMFS_MOUNTPOINT
config HC32_ROMFS_DEV_MINOR
int "Minor for the block device backing the data"
depends on HC32_ROMFS
default 64
config HC32_ROMFS_MOUNTPOINT
string "Mountpoint of the custom romfs image"
depends on HC32_ROMFS
default "/rom"
config HC32_ROMFS_IMAGEFILE
string "ROMFS image file to include into build"
depends on HC32_ROMFS
default "../../../../../rom.img"
endif

View File

@ -57,38 +57,42 @@
/* for lowputc device output */
/* UART RX/TX Port/Pin definition */
#define LP_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */
#define LP_RX_PIN (GPIO_PIN_06)
#define LP_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX)
#define DBG_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */
#define DBG_RX_PIN (GPIO_PIN_06)
#define DBG_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX)
#define LP_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */
#define LP_TX_PIN (GPIO_PIN_06)
#define LP_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX)
#define DBG_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */
#define DBG_TX_PIN (GPIO_PIN_06)
#define DBG_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX)
/* UART unit definition */
#define LP_UNIT (M4_USART6)
#define LP_FUNCTION_CLK_GATE (PWC_FCG3_USART6)
#define DBG_UNIT (M4_USART6)
#define DBG_BAUDRATE (115200UL)
#define DBG_FUNCTION_CLK_GATE (PWC_FCG3_USART6)
/* UART unit interrupt definition */
#define LP_UNIT_ERR_INT_SRC (INT_USART6_EI)
#define LP_UNIT_ERR_INT_IRQn (Int015_IRQn + HC32_IRQ_FIRST)
#define DBG_UNIT_ERR_INT_SRC (INT_USART6_EI)
#define DBG_UNIT_ERR_INT_IRQn (Int010_IRQn)
#define LP_UNIT_RX_INT_SRC (INT_USART6_RI)
#define LP_UNIT_RX_INT_IRQn (Int103_IRQn + HC32_IRQ_FIRST)
#define DBG_UNIT_RX_INT_SRC (INT_USART6_RI)
#define DBG_UNIT_RX_INT_IRQn (Int011_IRQn)
#define LP_UNIT_TX_INT_SRC (INT_USART6_TI)
#define LP_UNIT_TX_INT_IRQn (Int102_IRQn + HC32_IRQ_FIRST)
#define DBG_RXTO_INT_SRC (INT_USART6_RTO)
#define DBG_RXTO_INT_IRQn (Int012_IRQn)
#define LP_UNIT_TCI_INT_SRC (INT_USART6_TCI)
#define LP_UNIT_TCI_INT_IRQn (Int099_IRQn + HC32_IRQ_FIRST)
#define DBG_UNIT_TX_INT_SRC (INT_USART6_TI)
#define DBG_UNIT_TX_INT_IRQn (Int013_IRQn)
#define DBG_UNIT_TCI_INT_SRC (INT_USART6_TCI)
#define DBG_UNIT_TCI_INT_IRQn (Int014_IRQn)
/* printf device s*/
#define BSP_PRINTF_DEVICE LP_UNIT
#define BSP_PRINTF_BAUDRATE (115200)
#define BSP_PRINTF_DEVICE DBG_UNIT
#define BSP_PRINTF_BAUDRATE DBG_BAUDRATE
#define BSP_PRINTF_PORT LP_TX_PORT
#define BSP_PRINTF_PORT DBG_TX_PORT
#define BSP_PRINTF_PIN LP_TX_PIN
#define BSP_PRINTF_PORT_FUNC LP_TX_GPIO_FUNC
#define BSP_PRINTF_PIN DBG_TX_PIN
#define BSP_PRINTF_PORT_FUNC DBG_TX_GPIO_FUNC
#endif /* __BOARDS_ARM_HC32_HC32F4A0_INCLUDE_BOARD_H */

View File

@ -41,7 +41,7 @@ USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}"
# Source files
CSRCS = stm32_userspace.c
CSRCS = hc32_userspace.c
COBJS = $(CSRCS:.c=$(OBJEXT))
OBJS = $(COBJS)

View File

@ -52,7 +52,7 @@
# error "CONFIG_NUTTX_USERSPACE not defined"
#endif
#if CONFIG_NUTTX_USERSPACE != 0x20060000
#if CONFIG_NUTTX_USERSPACE != 0x20062000
# error "CONFIG_NUTTX_USERSPACE must be 0x20060000 to match memory.ld"
#endif

View File

@ -1,5 +1,5 @@
/****************************************************************************
* boards/arm/stm32/aiit-arm32-board/scripts/gnu-elf.ld
* boards/arm/hc32/hc32f4a0/scripts/gnu-elf.ld
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with

View File

@ -1,5 +1,5 @@
/****************************************************************************
* boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld
* boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with

View File

@ -32,7 +32,7 @@
* For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of
* FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which
* should fit into 64KB and, of course, can be optimized as needed (See
* also boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld). Allowing the
* also boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld). Allowing the
* additional does permit addition debug instrumentation to be added to the
* kernel space without overflowing the partition.
*
@ -73,13 +73,13 @@ MEMORY
{
/* 2Mb FLASH */
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 2M
uflash (rx) : ORIGIN = 0x00200000, LENGTH = 128K
xflash (rx) : ORIGIN = 0x00220000, LENGTH = 768K
kflash (rx) : ORIGIN = 0x00000000, LENGTH = 64K
uflash (rx) : ORIGIN = 0x00010000, LENGTH = 1M
xflash (rx) : ORIGIN = 0x00110000, LENGTH = 128K
/* 512Kb of contiguous SRAM */
ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 512K
usram (rwx) : ORIGIN = 0x20060000, LENGTH = 4K
xsram (rwx) : ORIGIN = 0x20062000, LENGTH = 4K
ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 64K
usram (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 448K
xsram (rwx) : ORIGIN = 0x20070000, LENGTH = 4K
}

View File

@ -48,16 +48,16 @@ SECTIONS
_sinit = ABSOLUTE(.);
*(.init_array .init_array.*)
_einit = ABSOLUTE(.);
} > kflash
} > uflash
.ARM.extab : {
*(.ARM.extab*)
} > kflash
} > uflash
__exidx_start = ABSOLUTE(.);
.ARM.exidx : {
*(.ARM.exidx*)
} > kflash
} > uflash
__exidx_end = ABSOLUTE(.);
@ -70,7 +70,7 @@ SECTIONS
CONSTRUCTORS
. = ALIGN(4);
_edata = ABSOLUTE(.);
} > ksram AT > kflash
} > usram AT > uflash
.bss : {
_sbss = ABSOLUTE(.);
@ -79,7 +79,7 @@ SECTIONS
*(COMMON)
. = ALIGN(4);
_ebss = ABSOLUTE(.);
} > ksram
} > usram
/* Stabs debugging sections */

View File

@ -26,6 +26,10 @@ ifeq ($(CONFIG_ARCH_LEDS),y)
CSRCS +=
endif
ifeq ($(CONFIG_STM32_ROMFS),y)
CSRCS += hc32_romfs_initialize.c
endif
DEPPATH += --dep-path board
VPATH += :board
CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board)

View File

@ -38,6 +38,7 @@
****************************************************************************/
extern int hc32_bringup(void);
extern int hc32_spidev_initialized;
/****************************************************************************
* Name: hc32_boardinitialize
@ -52,57 +53,57 @@ extern int hc32_bringup(void);
void hc32_boardinitialize(void)
{
//#ifdef CONFIG_SCHED_CRITMONITOR
// /* Enable ITM and DWT resources, if not left enabled by debugger. */
//
// modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA);
//
// /* Make sure the high speed cycle counter is running. It will be started
// * automatically only if a debugger is connected.
// */
//
// putreg32(0xc5acce55, ITM_LAR);
// modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK);
//#endif
//
//#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3)
// /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak
// * function hc32_spidev_initialize() has been brought into the link.
// */
//
// if (hc32_spidev_initialize)
// {
// hc32_spidev_initialize();
// }
//#endif
//
//#ifdef CONFIG_HC32_OTGFS
// /* Initialize USB if the 1) OTG FS controller is in the configuration and
// * 2) disabled, and 3) the weak function hc32_usbinitialize() has been
// * brought into the build. Presumably either CONFIG_USBDEV or
// * CONFIG_USBHOST is also selected.
// */
//
// if (hc32_usbinitialize)
// {
// hc32_usbinitialize();
// }
//#endif
//
//#ifdef HAVE_NETMONITOR
// /* Configure board resources to support networking. */
//
// if (hc32_netinitialize)
// {
// hc32_netinitialize();
// }
//#endif
//
//#ifdef CONFIG_ARCH_LEDS
// /* Configure on-board LEDs if LED support has been selected. */
//
// board_autoled_initialize();
//#endif
#ifdef CONFIG_SCHED_CRITMONITOR
/* Enable ITM and DWT resources, if not left enabled by debugger. */
modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA);
/* Make sure the high speed cycle counter is running. It will be started
* automatically only if a debugger is connected.
*/
putreg32(0xc5acce55, ITM_LAR);
modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK);
#endif
#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3)
/* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak
* function hc32_spidev_initialize() has been brought into the link.
*/
if (hc32_spidev_initialized)
{
hc32_spidev_initialize();
}
#endif
#ifdef CONFIG_HC32_OTGFS
/* Initialize USB if the 1) OTG FS controller is in the configuration and
* 2) disabled, and 3) the weak function hc32_usbinitialize() has been
* brought into the build. Presumably either CONFIG_USBDEV or
* CONFIG_USBHOST is also selected.
*/
if (hc32_usbinitialize)
{
hc32_usbinitialize();
}
#endif
#ifdef HAVE_NETMONITOR
/* Configure board resources to support networking. */
if (hc32_netinitialize)
{
hc32_netinitialize();
}
#endif
#ifdef CONFIG_ARCH_LEDS
/* Configure on-board LEDs if LED support has been selected. */
board_autoled_initialize();
#endif
}
/****************************************************************************

View File

@ -31,6 +31,8 @@
#include <nuttx/fs/fs.h>
#include <hc32_common.h>
/****************************************************************************
* Name: hc32_bringup
*
@ -48,6 +50,27 @@
int hc32_bringup(void)
{
int ret = 0;
#ifdef CONFIG_FS_PROCFS
/* Mount the procfs file system */
ret = nx_mount(NULL, HC32_PROCFS_MOUNTPOINT, "procfs", 0, NULL);
if (ret < 0)
{
serr("ERROR: Failed to mount procfs at %s: %d\n",
HC32_PROCFS_MOUNTPOINT, ret);
}
#endif
#ifdef CONFIG_HC32_ROMFS
ret = hc32_romfs_initialize();
if (ret < 0)
{
serr("ERROR: Failed to mount romfs at %s: %d\n",
CONFIG_HC32_ROMFS_MOUNTPOINT, ret);
}
#endif
printf("start %s\n", __func__);
return ret;
}

View File

@ -0,0 +1,76 @@
/****************************************************************************
* boards/arm/hc32/hc32f4a0/src/hc32_romfs.h
*
* Copyright (C) 2017 Tomasz Wozniak. All rights reserved.
* Author: Tomasz Wozniak <t.wozniak@samsung.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
#ifndef __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H
#define __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#ifdef CONFIG_HC32_ROMFS
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define ROMFS_SECTOR_SIZE 64
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
/****************************************************************************
* Name: stm32_romfs_initialize
*
* Description:
* Registers built-in ROMFS image as block device and mounts it.
*
* Returned Value:
* Zero (OK) on success, a negated errno value on error.
*
* Assumptions/Limitations:
* Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain
* ROMFS volume data, as included in the assembly snippet above (l. 84).
*
****************************************************************************/
int hc32_romfs_initialize(void);
#endif /* CONFIG_STM32_ROMFS */
#endif /* __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H */

View File

@ -0,0 +1,158 @@
/****************************************************************************
* boards/arm/hc32/hc32f4a0/src/hc32_romfs_initialize.c
* This file provides contents of an optional ROMFS volume, mounted at boot.
*
* Copyright (C) 2017 Tomasz Wozniak. All rights reserved.
* Author: Tomasz Wozniak <t.wozniak@samsung.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <stdint.h>
#include <debug.h>
#include <errno.h>
#include <nuttx/fs/fs.h>
#include <nuttx/drivers/ramdisk.h>
#include "hc32_romfs.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifndef CONFIG_HC32_ROMFS
# error "CONFIG_HC32_ROMFS must be defined"
#else
#ifndef CONFIG_HC32_ROMFS_IMAGEFILE
# error "CONFIG_HC32_ROMFS_IMAGEFILE must be defined"
#endif
#ifndef CONFIG_HC32_ROMFS_DEV_MINOR
# error "CONFIG_HC32_ROMFS_DEV_MINOR must be defined"
#endif
#ifndef CONFIG_HC32_ROMFS_MOUNTPOINT
# error "CONFIG_HC32_ROMFS_MOUNTPOINT must be defined"
#endif
#define NSECTORS(size) (((size) + ROMFS_SECTOR_SIZE - 1)/ROMFS_SECTOR_SIZE)
#define STR2(m) #m
#define STR(m) STR2(m)
#define MKMOUNT_DEVNAME(m) "/dev/ram" STR(m)
#define MOUNT_DEVNAME MKMOUNT_DEVNAME(CONFIG_HC32_ROMFS_DEV_MINOR)
/****************************************************************************
* Private Data
****************************************************************************/
__asm__ (
".section .rodata\n"
".balign 16\n"
".globl romfs_data_begin\n"
"romfs_data_begin:\n"
".incbin " STR(CONFIG_HC32_ROMFS_IMAGEFILE) "\n"\
\
".balign " STR(ROMFS_SECTOR_SIZE) "\n"
".globl romfs_data_end\n"
"romfs_data_end:\n"
".globl romfs_data_size\n"
"romfs_data_size:\n"
".word romfs_data_end - romfs_data_begin\n"
".previous\n");
extern const char romfs_data_begin;
extern const char romfs_data_end;
extern const int romfs_data_size;
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: hc32_romfs_initialize
*
* Description:
* Registers the aboveincluded binary file as block device.
* Then mounts the block device as ROMFS filesystems.
*
* Returned Value:
* Zero (OK) on success, a negated errno value on error.
*
* Assumptions/Limitations:
* Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain
* ROMFS volume data, as included in the assembly snippet above (l. 84).
*
****************************************************************************/
int hc32_romfs_initialize(void)
{
uintptr_t romfs_data_len;
int ret;
/* Create a ROM disk for the /etc filesystem */
romfs_data_len = (uintptr_t)&romfs_data_end - (uintptr_t)&romfs_data_begin;
ret = romdisk_register(CONFIG_HC32_ROMFS_DEV_MINOR, &romfs_data_begin,
NSECTORS(romfs_data_len), ROMFS_SECTOR_SIZE);
if (ret < 0)
{
ferr("ERROR: romdisk_register failed: %d\n", -ret);
return ret;
}
/* Mount the file system */
finfo("Mounting ROMFS filesystem at target=%s with source=%s\n",
CONFIG_HC32_ROMFS_MOUNTPOINT, MOUNT_DEVNAME);
ret = nx_mount(MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT,
"romfs", MS_RDONLY, NULL);
if (ret < 0)
{
ferr("ERROR: nx_mount(%s,%s,romfs) failed: %d\n",
MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT, ret);
return ret;
}
return OK;
}
#endif /* CONFIG_HC32_ROMFS */

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

@ -172,3 +172,26 @@ config HC32_UART8
endmenu # HC32 U[S]ART Selection
config HC32_SPI1
bool "SPI1"
default n
select SPI
select HC32_SPI
config HC32_SPI2
bool "SPI2"
default n
depends on HC32_HAVE_SPI2
select SPI
select HC32_SPI
config HC32_SPI
bool
config HC32_I2C
bool
config HC32_CAN
bool

View File

@ -44,7 +44,6 @@ CMN_ASRCS += arm_lazyexception.S
else
CMN_ASRCS += arm_exception.S
endif
CMN_CSRCS += arm_vectors.c
ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
CMN_CSRCS += arm_ramvec_initialize.c arm_ramvec_attach.c
@ -77,12 +76,19 @@ ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y)
CMN_CSRCS += arm_tls.c
endif
CMN_CSRCS += hc32_vectors.c
CHIP_CSRCS = hc32_allocateheap.c hc32_gpio.c
CHIP_CSRCS += hc32_irq.c hc32_idle.c hc32_mpuinit.c
CHIP_CSRCS += hc32_rcc.c hc32_start.c hc32_serial.c
CHIP_CSRCS += hc32_pm.c hc32_timerisr.c hc32_lowputc.c
CHIP_CSRCS += hc32_console.c
CHIP_CSRCS += hc32f4a0_clk.c hc32f4a0_efm.c hc32f4a0_gpio.c
CHIP_CSRCS += hc32f4a0_interrupts.c hc32f4a0_usart.c hc32f4a0_utility.c
CHIP_CSRCS += hc32f4a0_sram.c hc32f4a0_pwc.c
CHIP_CSRCS += hc32f4a0_spi.c
CHIP_CSRCS += hc32_spiflash.c hc32_spi.c

View File

@ -89,7 +89,7 @@ extern "C"
#define DDL_RTC_ENABLE (DDL_OFF)
#define DDL_SDIOC_ENABLE (DDL_OFF)
#define DDL_SMC_ENABLE (DDL_OFF)
#define DDL_SPI_ENABLE (DDL_OFF)
#define DDL_SPI_ENABLE (DDL_ON)
#define DDL_SRAM_ENABLE (DDL_ON)
#define DDL_SWDT_ENABLE (DDL_OFF)
#define DDL_TMR0_ENABLE (DDL_OFF)
@ -134,7 +134,7 @@ extern "C"
#define BSP_OV5640_ENABLE (BSP_OFF)
#define BSP_S29GL064N90TFI03_ENABLE (BSP_OFF)
#define BSP_TCA9539_ENABLE (BSP_OFF)
#define BSP_W25QXX_ENABLE (BSP_ON)
#define BSP_W25QXX_ENABLE (BSP_OFF)
#define BSP_WM8731_ENABLE (BSP_OFF)
/**

View File

@ -83,20 +83,20 @@
/* The HC32 F4A0 have no CCM SRAM */
# if defined(CONFIG_HC32_HC32F4A0)
# if defined(CONFIG_HC32_HC32F4A0)
# undef CONFIG_HC32_CCMEXCLUDE
# define CONFIG_HC32_CCMEXCLUDE 1
# endif
/* Set the end of system SRAM */
#define SRAM1_END 0x20073880
#define SRAM1_END 0x1FFF0000
/* Set the range of CCM SRAM as well (although we may not use it) */
#define SRAM2_START 0x1FE00000
#define SRAM2_END 0x20073880
#define SRAM2_START 0x1FFF0000
#define SRAM2_END 0x20070000
/* There are 4 possible SRAM configurations:

View File

@ -37,6 +37,15 @@ extern "C"
#define HC32F4A0 1
#define USE_DDL_DRIVER 1
#ifdef CONFIG_FS_PROCFS
# ifdef CONFIG_NSH_PROC_MOUNTPOINT
# define HC32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT
# else
# define HC32_PROCFS_MOUNTPOINT "/proc"
# endif
#endif
#define getreg32(a) (*(volatile uint32_t *)(a))
#define putreg32(v,a) (*(volatile uint32_t *)(a) = (v))
#define getreg16(a) (*(volatile uint16_t *)(a))

View File

@ -0,0 +1,46 @@
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <debug.h>
#include <arch/board/board.h>
#include "chip.h"
#include "hc32_uart.h"
#include "hc32_spi.h"
void hc32_test_console(void)
{
char *dev_str = "/dev/console";
char *test_chr = "test";
int fd = 0, ret;
fd = open(dev_str, 0x6);
hc32_print("%s: open <%s> ret = %d\n", __func__, dev_str, fd);
ret = write(fd, test_chr, strlen(test_chr));
hc32_print("%s: open %d ret %d\n", __func__, fd, ret);
close(fd);
}
void hc32_console_handle(char *buf)
{
if(strncmp(buf, "console", 7) == 0)
{
hc32_test_console();
}
else if(strncmp(buf, "spi", 7) == 0)
{
hc32_print("start flash test ...\n");
hc32_spiflash_test();
}
}

View File

@ -0,0 +1,43 @@
#ifndef __HC32_CONSOLE_H_
#define __HC32_CONSOLE_H_
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#include <nuttx/irq.h>
#include <nuttx/arch.h>
#include <nuttx/fs/ioctl.h>
#include <nuttx/serial/serial.h>
#include <nuttx/power/pm.h>
#ifdef CONFIG_SERIAL_TERMIOS
# include <termios.h>
#endif
#include <arch/board/board.h>
#include "chip.h"
#include "hc32_uart.h"
#include "hc32_rcc.h"
#include "hc32_gpio.h"
#include "arm_internal.h"
#include "hc32f4a0.h"
#include "hc32f4a0_usart.h"
#include "hc32f4a0_gpio.h"
#include "hc32f4a0_interrupts.h"
#include "hc32f4a0_sram.h"
#include "hc32f4a0_pwc.h"
#include "hc32f4a0_efm.h"
void hc32_console_handle(char *buf);
#endif

View File

@ -119,7 +119,7 @@ void hc32_gpioinit(void)
****************************************************************************/
/****************************************************************************
* Name: hc32_configgpio (for the HC32F10xxx family)
* Name: hc32_configgpio (for the HC32F4A0)
****************************************************************************/
int hc32_configgpio(uint32_t cfgset)

View File

@ -152,6 +152,12 @@ static void up_idlepm(void)
void up_idle(void)
{
#if defined (CONFIG_HC32F4A0_BOARD)
extern void hc32_uart_handle(void);
hc32_uart_handle();
#endif
#if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS)
/* If the system is idle and there are no timer interrupts, then process
* "fake" timer interrupts. Hopefully, something will wake up.

View File

@ -37,34 +37,12 @@
#include "hc32_lowputc.h"
#include "hc32f4a0_usart.h"
#include "hc32_ddl.h"
#include "hc32_uart.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* UART multiple processor ID definition */
#define UART_MASTER_STATION_ID (0x20U)
#define UART_SLAVE_STATION_ID (0x21U)
/* Ring buffer size */
#define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
/* Multi-processor silence mode */
#define LP_UART_NORMAL_MODE (0U)
#define LP_UART_SILENCE_MODE (1U)
/**
* @brief Ring buffer structure definition
*/
typedef struct
{
uint16_t u16Capacity;
__IO uint16_t u16UsedSize;
uint16_t u16InIdx;
uint16_t u16OutIdx;
uint8_t au8Buf[50];
} stc_ring_buffer_t;
/****************************************************************************
* Private Types
****************************************************************************/
@ -81,212 +59,10 @@ typedef struct
* Private Data
****************************************************************************/
static uint8_t m_u8UartSilenceMode = LP_UART_NORMAL_MODE;
static stc_ring_buffer_t m_stcRingBuf = {
.u16InIdx = 0U,
.u16OutIdx = 0U,
.u16UsedSize = 0U,
.u16Capacity = sizeof (m_stcRingBuf.au8Buf),
};
/****************************************************************************
* Private Functions
****************************************************************************/
/**
* @brief Set silence mode.
* @param [in] u8Mode Silence mode
* This parameter can be one of the following values:
* @arg LP_UART_SILENCE_MODE: UART silence mode
* @arg LP_UART_NORMAL_MODE: UART normal mode
* @retval None
*/
static void UsartSetSilenceMode(uint8_t u8Mode)
{
m_u8UartSilenceMode = u8Mode;
}
/**
* @brief Get silence mode.
* @param [in] None
* @retval Returned value can be one of the following values:
* @arg LP_UART_SILENCE_MODE: UART silence mode
* @arg LP_UART_NORMAL_MODE: UART normal mode
*/
static uint8_t UsartGetSilenceMode(void)
{
return m_u8UartSilenceMode;
}
/**
* @brief Instal IRQ handler.
* @param [in] pstcConfig Pointer to struct @ref stc_irq_signin_config_t
* @param [in] u32Priority Interrupt priority
* @retval None
*/
static void InstalIrqHandler(const stc_irq_signin_config_t *pstcConfig,
uint32_t u32Priority)
{
if (NULL != pstcConfig)
{
(void)INTC_IrqSignIn(pstcConfig);
NVIC_ClearPendingIRQ(pstcConfig->enIRQn);
NVIC_SetPriority(pstcConfig->enIRQn, u32Priority);
NVIC_EnableIRQ(pstcConfig->enIRQn);
}
}
/**
* @brief Write ring buffer.
* @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
* @param [in] pu8Data Pointer to data buffer to read
* @retval An en_result_t enumeration value:
* - Ok: Write success.
* - ErrorNotReady: Buffer is empty.
*/
static en_result_t RingBufRead(stc_ring_buffer_t *pstcBuffer, uint8_t *pu8Data)
{
en_result_t enRet = Ok;
if (pstcBuffer->u16UsedSize == 0U)
{
enRet = ErrorNotReady;
}
else
{
*pu8Data = pstcBuffer->au8Buf[pstcBuffer->u16OutIdx++];
pstcBuffer->u16OutIdx %= pstcBuffer->u16Capacity;
pstcBuffer->u16UsedSize--;
}
return enRet;
}
/**
* @brief UART TX Empty IRQ callback.
* @param None
* @retval None
*/
static void USART_TxEmpty_IrqCallback(void)
{
uint8_t u8Data = 0U;
en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_TXE);
en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_TXE);
if ((Set == enFlag) && (Enable == enState))
{
USART_SendId(LP_UNIT, UART_SLAVE_STATION_ID);
while (Reset == USART_GetStatus(LP_UNIT, USART_FLAG_TC)) /* Wait Tx data register empty */
{
}
if (Ok == RingBufRead(&m_stcRingBuf, &u8Data))
{
USART_SendData(LP_UNIT, (uint16_t)u8Data);
}
if (IS_RING_BUFFER_EMPTY(&m_stcRingBuf))
{
USART_FuncCmd(LP_UNIT, USART_INT_TXE, Disable);
USART_FuncCmd(LP_UNIT, USART_INT_TC, Enable);
}
}
}
/**
* @brief UART TX Complete IRQ callback.
* @param None
* @retval None
*/
static void USART_TxComplete_IrqCallback(void)
{
en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_TC);
en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_TC);
if ((Set == enFlag) && (Enable == enState))
{
/* Disable TX function */
USART_FuncCmd(LP_UNIT, (USART_TX | USART_RX | USART_INT_TC), Disable);
/* Enable RX function */
USART_FuncCmd(LP_UNIT, (USART_RX | USART_INT_RX), Enable);
}
}
/**
* @brief Write ring buffer.
* @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure
* @param [in] u8Data Data to write
* @retval An en_result_t enumeration value:
* - Ok: Write success.
* - ErrorBufferFull: Buffer is full.
*/
static en_result_t write_ring_buf(stc_ring_buffer_t *pstcBuffer, uint8_t u8Data)
{
en_result_t enRet = Ok;
if (pstcBuffer->u16UsedSize >= pstcBuffer->u16Capacity)
{
enRet = ErrorBufferFull;
}
else
{
pstcBuffer->au8Buf[pstcBuffer->u16InIdx++] = u8Data;
pstcBuffer->u16InIdx %= pstcBuffer->u16Capacity;
pstcBuffer->u16UsedSize++;
}
return enRet;
}
/**
* @brief UART RX IRQ callback.
* @param None
* @retval None
*/
static void USART_Rx_IrqCallback(void)
{
uint8_t u8RxData;
en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_RXNE);
en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_RX);
if ((Set == enFlag) && (Enable == enState))
{
u8RxData = (uint8_t)USART_RecData(LP_UNIT);
if ((Reset == USART_GetStatus(LP_UNIT, USART_FLAG_MPB)) &&
(LP_UART_NORMAL_MODE == UsartGetSilenceMode()))
{
write_ring_buf(&m_stcRingBuf, u8RxData);
}
else
{
if (UART_MASTER_STATION_ID != u8RxData)
{
USART_SilenceCmd(LP_UNIT, Enable);
UsartSetSilenceMode(LP_UART_SILENCE_MODE);
}
else
{
UsartSetSilenceMode(LP_UART_NORMAL_MODE);
}
}
}
}
/**
* @brief UART RX Error IRQ callback.
* @param None
* @retval None
*/
static void USART_RxErr_IrqCallback(void)
{
USART_ClearStatus(LP_UNIT, (USART_CLEAR_FLAG_FE | USART_CLEAR_FLAG_PE | USART_CLEAR_FLAG_ORE));
}
void hc32_unlock(void)
{
/* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
@ -342,30 +118,19 @@ void hc32_print_portinit(void)
void arm_lowputc(char ch)
{
while(Set != USART_GetStatus(LP_UNIT, USART_FLAG_TXE));
USART_SendData(LP_UNIT, ch);
while(Set != USART_GetStatus(DBG_UNIT, USART_FLAG_TXE));
USART_SendData(DBG_UNIT, ch);
}
/****************************************************************************
* Name: hc32_lowsetup
*
* Description:
* This performs basic initialization of the USART used for the serial
* console. Its purpose is to get the console output available as soon
* as possible.
*
****************************************************************************/
void hc32_lowsetup(void)
{
stc_irq_signin_config_t stcIrqSigninCfg;
const stc_usart_multiprocessor_init_t stcUartMultiProcessorInit = {
.u32Baudrate = 115200UL,
const stc_usart_uart_init_t stcUartInit = {
.u32Baudrate = BSP_PRINTF_BAUDRATE,
.u32BitDirection = USART_LSB,
.u32StopBit = USART_STOPBIT_1BIT,
.u32Parity = USART_PARITY_NONE,
.u32DataWidth = USART_DATA_LENGTH_8BIT,
.u32ClkMode = USART_INTERNCLK_NONE_OUTPUT,
.u32ClkMode = USART_INTERNCLK_OUTPUT,
.u32PclkDiv = USART_PCLK_DIV64,
.u32OversamplingBits = USART_OVERSAMPLING_8BIT,
.u32NoiseFilterState = USART_NOISE_FILTER_DISABLE,
@ -380,42 +145,18 @@ void hc32_lowsetup(void)
DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, hc32_print_portinit);
/* Configure USART RX/TX pin. */
GPIO_SetFunc(LP_RX_PORT, LP_RX_PIN, LP_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
GPIO_SetFunc(LP_TX_PORT, LP_TX_PIN, LP_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
GPIO_SetFunc(DBG_RX_PORT, DBG_RX_PIN, DBG_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
GPIO_SetFunc(DBG_TX_PORT, DBG_TX_PIN, DBG_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE);
hc32_lock();
/* Enable peripheral clock */
PWC_Fcg3PeriphClockCmd(LP_FUNCTION_CLK_GATE, Enable);
/* Set silence mode */
UsartSetSilenceMode(LP_UART_SILENCE_MODE);
PWC_Fcg3PeriphClockCmd(DBG_FUNCTION_CLK_GATE, Enable);
/* Initialize UART function. */
(void)USART_MultiProcessorInit(LP_UNIT, &stcUartMultiProcessorInit);
/* Register error IRQ handler && configure NVIC. */
stcIrqSigninCfg.enIRQn = LP_UNIT_ERR_INT_IRQn;
stcIrqSigninCfg.enIntSrc = LP_UNIT_ERR_INT_SRC;
stcIrqSigninCfg.pfnCallback = &USART_RxErr_IrqCallback;
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT);
/* Register RX IRQ handler && configure NVIC. */
stcIrqSigninCfg.enIRQn = LP_UNIT_RX_INT_IRQn;
stcIrqSigninCfg.enIntSrc = LP_UNIT_RX_INT_SRC;
stcIrqSigninCfg.pfnCallback = &USART_Rx_IrqCallback;
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_00);
/* Register TX IRQ handler && configure NVIC. */
stcIrqSigninCfg.enIRQn = LP_UNIT_TX_INT_IRQn;
stcIrqSigninCfg.enIntSrc = LP_UNIT_TX_INT_SRC;
stcIrqSigninCfg.pfnCallback = &USART_TxEmpty_IrqCallback;
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT);
/* Register TC IRQ handler && configure NVIC. */
stcIrqSigninCfg.enIRQn = LP_UNIT_TCI_INT_IRQn;
stcIrqSigninCfg.enIntSrc = LP_UNIT_TCI_INT_SRC;
stcIrqSigninCfg.pfnCallback = &USART_TxComplete_IrqCallback;
InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT);
if (Ok != USART_UartInit(DBG_UNIT, &stcUartInit))
{
for (;;);
}
}

View File

@ -0,0 +1,189 @@
/**
*******************************************************************************
* @file arch/arm/src/hc32/hc32_spi.c
* @brief SPI write read flash API for the Device Driver Library.
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Wangmin First version
2020-10-13 Wangmin Modify spelling mistake
@endverbatim
*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"
#include "hc32_spi.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
* @brief MCU Peripheral registers write unprotected.
* @param None
* @retval None
* @note Comment/uncomment each API depending on APP requires.
*/
static void Peripheral_WE(void)
{
/* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
GPIO_Unlock();
/* Unlock PWC register: FCG0 */
PWC_FCG0_Unlock();
/* Unlock PWC, CLK, PVD registers, @ref PWC_REG_Write_Unlock_Code for details */
PWC_Unlock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1 | PWC_UNLOCK_CODE_2);
/* Unlock SRAM register: WTCR */
SRAM_WTCR_Unlock();
/* Unlock SRAM register: CKCR */
//SRAM_CKCR_Unlock();
/* Unlock all EFM registers */
EFM_Unlock();
/* Unlock EFM register: FWMC */
//EFM_FWMC_Unlock();
/* Unlock EFM OTP write protect registers */
//EFM_OTP_WP_Unlock();
/* Unlock all MPU registers */
// MPU_Unlock();
}
/**
* @brief MCU Peripheral registers write protected.
* @param None
* @retval None
* @note Comment/uncomment each API depending on APP requires.
*/
static __attribute__((unused)) void Peripheral_WP(void)
{
/* Lock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */
GPIO_Lock();
/* Lock PWC register: FCG0 */
PWC_FCG0_Lock();
/* Lock PWC, CLK, PVD registers, @ref PWC_REG_Write_Unlock_Code for details */
PWC_Lock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1 | PWC_UNLOCK_CODE_2);
/* Lock SRAM register: WTCR */
SRAM_WTCR_Lock();
/* Lock SRAM register: CKCR */
//SRAM_CKCR_Lock();
/* Lock EFM OTP write protect registers */
//EFM_OTP_WP_Lock();
/* Lock EFM register: FWMC */
//EFM_FWMC_Lock();
/* Lock all EFM registers */
EFM_Lock();
/* Lock all MPU registers */
// MPU_Lock();
}
/**
* @brief Configure SPI peripheral function
*
* @param [in] None
*
* @retval None
*/
static void Spi_Config(void)
{
stc_spi_init_t stcSpiInit;
stc_spi_delay_t stcSpiDelayCfg;
/* Clear initialize structure */
(void)SPI_StructInit(&stcSpiInit);
(void)SPI_DelayStructInit(&stcSpiDelayCfg);
/* Configure peripheral clock */
PWC_Fcg1PeriphClockCmd(SPI_UNIT_CLOCK, Enable);
/* SPI De-initialize */
SPI_DeInit(SPI_UNIT);
/* Configuration SPI structure */
stcSpiInit.u32WireMode = SPI_WIRE_3;
stcSpiInit.u32TransMode = SPI_FULL_DUPLEX;
stcSpiInit.u32MasterSlave = SPI_MASTER;
stcSpiInit.u32SuspMode = SPI_COM_SUSP_FUNC_OFF;
stcSpiInit.u32Modfe = SPI_MODFE_DISABLE;
stcSpiInit.u32Parity = SPI_PARITY_INVALID;
stcSpiInit.u32SpiMode = SPI_MODE_0;
stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV256;
stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT;
stcSpiInit.u32FirstBit = SPI_FIRST_MSB;
(void)SPI_Init(SPI_UNIT, &stcSpiInit);
stcSpiDelayCfg.u32IntervalDelay = SPI_INTERVAL_TIME_8SCK_2PCLK1;
stcSpiDelayCfg.u32ReleaseDelay = SPI_RELEASE_TIME_8SCK;
stcSpiDelayCfg.u32SetupDelay = SPI_SETUP_TIME_1SCK;
(void)SPI_DelayTimeCfg(SPI_UNIT, &stcSpiDelayCfg);
SPI_FunctionCmd(SPI_UNIT, Enable);
}
int hc32_spi_init(void)
{
stc_gpio_init_t stcGpioCfg;
Peripheral_WE();
/* Port configurate */
(void)GPIO_StructInit(&stcGpioCfg);
/* High driving capacity for output pin. */
stcGpioCfg.u16PinDir = PIN_DIR_OUT;
stcGpioCfg.u16PinDrv = PIN_DRV_HIGH;
stcGpioCfg.u16PinState = PIN_STATE_SET;
(void)GPIO_Init(SPI_NSS_PORT, SPI_NSS_PIN, &stcGpioCfg);
(void)GPIO_StructInit(&stcGpioCfg);
stcGpioCfg.u16PinDrv = PIN_DRV_HIGH;
(void)GPIO_Init(SPI_SCK_PORT, SPI_SCK_PIN, &stcGpioCfg);
(void)GPIO_Init(SPI_MOSI_PORT, SPI_MOSI_PIN, &stcGpioCfg);
/* CMOS input for input pin */
stcGpioCfg.u16PinDrv = PIN_DRV_LOW;
stcGpioCfg.u16PinIType = PIN_ITYPE_CMOS;
(void)GPIO_Init(SPI_MISO_PORT, SPI_MISO_PIN, &stcGpioCfg);
/* Configure SPI Port function for master */
GPIO_SetFunc(SPI_SCK_PORT, SPI_SCK_PIN, SPI_SCK_FUNC, PIN_SUBFUNC_DISABLE);
GPIO_SetFunc(SPI_MOSI_PORT, SPI_MOSI_PIN, SPI_MOSI_FUNC, PIN_SUBFUNC_DISABLE);
GPIO_SetFunc(SPI_MISO_PORT, SPI_MISO_PIN, SPI_MISO_FUNC, PIN_SUBFUNC_DISABLE);
/* Configure SPI for SPI flash */
Spi_Config();
Peripheral_WP();
return OK;
}

View File

@ -0,0 +1,77 @@
/**
*******************************************************************************
* @file arch/arm/src/hc32/hc32_spi.h
* @brief SPI write read flash API for the Device Driver Library.
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Wangmin First version
2020-10-13 Wangmin Modify spelling mistake
@endverbatim
*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* SPI unit and clock definition */
#define SPI_UNIT (M4_SPI1)
#define SPI_UNIT_CLOCK (PWC_FCG1_SPI1)
/* SPI port definition for master */
#define SPI_NSS_PORT (GPIO_PORT_C)
#define SPI_NSS_PIN (GPIO_PIN_07)
#define SPI_SCK_PORT (GPIO_PORT_C)
#define SPI_SCK_PIN (GPIO_PIN_06)
#define SPI_SCK_FUNC (GPIO_FUNC_40_SPI1_SCK)
#define SPI_MOSI_PORT (GPIO_PORT_D)
#define SPI_MOSI_PIN (GPIO_PIN_08)
#define SPI_MOSI_FUNC (GPIO_FUNC_41_SPI1_MOSI)
#define SPI_MISO_PORT (GPIO_PORT_D)
#define SPI_MISO_PIN (GPIO_PIN_09)
#define SPI_MISO_FUNC (GPIO_FUNC_42_SPI1_MISO)
/* NSS pin control */
#define SPI_NSS_HIGH() (GPIO_SetPins(SPI_NSS_PORT, SPI_NSS_PIN))
#define SPI_NSS_LOW() (GPIO_ResetPins(SPI_NSS_PORT, SPI_NSS_PIN))
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
int hc32_spi_init(void);
void hc32_spiflash_test(void);

View File

@ -0,0 +1,350 @@
/**
*******************************************************************************
* @file arch/arm/src/hc32/hc32_spiflash.c
* @brief SPI write read flash API for the Device Driver Library.
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Wangmin First version
2020-10-13 Wangmin Modify spelling mistake
@endverbatim
*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_ddl.h"
#include "hc32_spi.h"
#include "hc32_uart.h"
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/* FLASH parameters */
#define FLASH_PAGE_SIZE (0x100U)
#define FLASH_SECTOR_SIZE (0x1000U)
#define FLASH_MAX_ADDR (0x800000UL)
#define FLASH_DUMMY_BYTE_VALUE (0xffU)
#define FLASH_BUSY_BIT_MASK (0x01U)
/* FLASH instruction */
#define FLASH_INSTR_WRITE_ENABLE (0x06U)
#define FLASH_INSTR_PAGE_PROGRAM (0x02U)
#define FLASH_INSTR_STANDARD_READ (0x03U)
#define FLASH_INSTR_ERASE_4KB_SECTOR (0x20U)
#define FLASH_INSTR_READ_SR1 (0x05U)
#define FLASH_READ_MANUFACTURER_ID (0x90U)
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
* @brief SPI flash write byte function
*
* @param [in] u8Data SPI write data to flash
*
* @retval uint8_t SPI receive data from flash
*/
static uint8_t SpiFlash_WriteReadByte(uint8_t u8Data)
{
uint8_t u8Byte;
/* Wait tx buffer empty */
while (Reset == SPI_GetStatus(SPI_UNIT, SPI_FLAG_TX_BUFFER_EMPTY))
{
}
/* Send data */
SPI_WriteDataReg(SPI_UNIT, (uint32_t)u8Data);
/* Wait rx buffer full */
while (Reset == SPI_GetStatus(SPI_UNIT, SPI_FLAG_RX_BUFFER_FULL))
{
}
/* Receive data */
u8Byte = (uint8_t)SPI_ReadDataReg(SPI_UNIT);
return u8Byte;
}
/**
* @brief SPI flash write enable function
*
* @param [in] None
*
* @retval None
*/
static void SpiFlash_WriteEnable(void)
{
SPI_NSS_LOW();
(void)SpiFlash_WriteReadByte(FLASH_INSTR_WRITE_ENABLE);
SPI_NSS_HIGH();
}
/**
* @brief SPI flash wait for write operation end function
*
* @param [in] None
*
* @retval Ok Flash internal operation finish
* @retval ErrorTimeout Flash internal operation timeout
*/
static en_result_t SpiFlash_WaitForWriteEnd(void)
{
en_result_t enRet = Ok;
uint8_t u8Status;
uint32_t u32Timeout;
stc_clk_freq_t stcClkFreq;
(void)CLK_GetClockFreq(&stcClkFreq);
u32Timeout = stcClkFreq.sysclkFreq / 1000U;
SPI_NSS_LOW();
(void)SpiFlash_WriteReadByte(FLASH_INSTR_READ_SR1);
do
{
u8Status = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE);
u32Timeout--;
} while ((u32Timeout != 0UL) &&
((u8Status & FLASH_BUSY_BIT_MASK) == FLASH_BUSY_BIT_MASK));
if (FLASH_BUSY_BIT_MASK == u8Status)
{
enRet = ErrorTimeout;
}
SPI_NSS_HIGH();
return enRet;
}
/**
* @brief SPI flash page write program function
*
* @param [in] u32Addr Valid flash address
* @param [in] pData Pointer to send data buffer
* @param [in] len Send data length
*
* @retval Error Page write program failed
* @retval Ok Page write program success
*/
static en_result_t SpiFlash_WritePage(uint32_t u32Addr, const uint8_t pData[], uint16_t len)
{
en_result_t enRet;
uint16_t u16Index = 0U;
if ((u32Addr > FLASH_MAX_ADDR) || (NULL == pData) || (len > FLASH_PAGE_SIZE))
{
enRet = Error;
}
else
{
SpiFlash_WriteEnable();
/* Send data to flash */
SPI_NSS_LOW();
(void)SpiFlash_WriteReadByte(FLASH_INSTR_PAGE_PROGRAM);
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U));
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U));
(void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU));
while (0U != (len--))
{
(void)SpiFlash_WriteReadByte(pData[u16Index]);
u16Index++;
}
SPI_NSS_HIGH();
/* Wait for flash idle */
enRet = SpiFlash_WaitForWriteEnd();
}
return enRet;
}
/**
* @brief SPI flash read data function
*
* @param [in] u32Addr Valid flash address
* @param [out] pData Pointer to receive data buffer
*
* @param [in] len Read data length
*
* @retval Error Read data program failed
* @retval Ok Read data program success
*/
static en_result_t SpiFlash_ReadData(uint32_t u32Addr, uint8_t pData[], uint16_t len)
{
en_result_t enRet = Ok;
uint16_t u16Index = 0U;
if ((u32Addr > FLASH_MAX_ADDR) || (NULL == pData))
{
enRet = Error;
}
else
{
SpiFlash_WriteEnable();
/* Send data to flash */
SPI_NSS_LOW();
(void)SpiFlash_WriteReadByte(FLASH_INSTR_STANDARD_READ);
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U));
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U));
(void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU));
while (0U != (len--))
{
pData[u16Index] = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE);
u16Index++;
}
SPI_NSS_HIGH();
}
return enRet;
}
/**
* @brief SPI flash read ID for test
*
* @param [in] None
*
* @retval uint8_t Flash ID
*/
static uint8_t SpiFlash_ReadID(void)
{
uint8_t u8IdRead;
SPI_NSS_LOW();
(void)SpiFlash_WriteReadByte(FLASH_READ_MANUFACTURER_ID);
(void)SpiFlash_WriteReadByte((uint8_t)0x00U);
(void)SpiFlash_WriteReadByte((uint8_t)0x00U);
(void)SpiFlash_WriteReadByte((uint8_t)0x00U);
u8IdRead = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE);
SPI_NSS_HIGH();
return u8IdRead;
}
/**
* @brief SPI flash erase 4Kb sector function
*
* @param [in] u32Addr Valid flash address
*
* @retval Error Sector erase failed
* @retval Ok Sector erase success
*/
static en_result_t SpiFlash_Erase4KbSector(uint32_t u32Addr)
{
en_result_t enRet;
if (u32Addr >= FLASH_MAX_ADDR)
{
enRet = Error;
}
else
{
SpiFlash_WriteEnable();
/* Send instruction to flash */
SPI_NSS_LOW();
(void)SpiFlash_WriteReadByte(FLASH_INSTR_ERASE_4KB_SECTOR);
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U));
(void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U));
(void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU));
//SPI_GetStatus(const M4_SPI_TypeDef *SPIx, uint32_t u32Flag) //todo
SPI_NSS_HIGH();
/* Wait for flash idle */
enRet = SpiFlash_WaitForWriteEnd();
}
return enRet;
}
/**
* @brief Main function of spi_master_base project
* @param None
* @retval int32_t return value, if needed
*/
void hc32_spiflash_test(void)
{
uint32_t flashAddr = 0UL;
uint16_t bufferLen;
char txBuffer[] = "SPI read and write flash example: Welcome to use HDSC micro chip";
char rxBuffer[128];
uint8_t flash_id = 0;
hc32_spi_init();
/* Get tx buffer length */
bufferLen = (uint16_t)sizeof(txBuffer);
flash_id = SpiFlash_ReadID();
hc32_print("SPI Flash id: %#x\n", flash_id);
(void)memset(rxBuffer, 0L, sizeof(rxBuffer));
/* Erase sector */
(void)SpiFlash_Erase4KbSector(flashAddr);
/* Write data to flash */
(void)SpiFlash_WritePage(flashAddr, (uint8_t*)&txBuffer[0], bufferLen);
/* Read data from flash */
(void)SpiFlash_ReadData(flashAddr, (uint8_t*)&rxBuffer[0], bufferLen);
/* Compare txBuffer and rxBuffer */
if (memcmp(txBuffer, rxBuffer, (uint32_t)bufferLen) != 0)
{
hc32_print("spi failed!!!\n");
}
else
{
hc32_print("spi ok!!!\n");
}
/* Flash address offset */
flashAddr += FLASH_SECTOR_SIZE;
if (flashAddr >= FLASH_MAX_ADDR)
{
flashAddr = 0U;
}
}
int hc32_spidev_initialized = 1;
void hc32_spidev_initialize(void)
{
hc32_spi_init();
hc32_spidev_initialized = 0;
}
/**
* @}
*/
/**
* @}
*/
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@ -27,7 +27,6 @@
#include <nuttx/config.h>
#include <nuttx/serial/serial.h>
#include "chip.h"
#define CONSOLE_UART 6
@ -43,9 +42,35 @@
* Pre-processor Definitions
****************************************************************************/
/* Make sure that we have not enabled more U[S]ARTs than are supported by the
* device.
typedef enum en_uart_state
{
UART_STATE_IDLE = 0U, /*!< No data */
UART_STATE_RXEND = 1U, /*!< UART RX End */
} uart_state_t;
/**
* @brief Ring buffer structure definition
*/
typedef struct
{
uint16_t u16Capacity;
volatile uint16_t u16UsedSize;
uint16_t u16InIdx;
uint16_t u16OutIdx;
uint8_t au8Buf[50];
} uart_ring_buffer_t;
/* UART multiple processor ID definition */
#define UART_MASTER_STATION_ID (0x20U)
#define UART_SLAVE_STATION_ID (0x21U)
/* Ring buffer size */
#define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize))
/* Multi-processor silence mode */
#define DBG_UART_NORMAL_MODE (0U)
#define DBG_UART_SILENCE_MODE (1U)
/****************************************************************************
* Public Types
@ -80,7 +105,9 @@ extern "C"
FAR uart_dev_t *hc32_serial_get_uart(int uart_num);
void hc32_print(const char *fmt, ...);
int hc32_print(const char *fmt, ...);
void hc32_console_handle(char *buf);
#undef EXTERN
#if defined(__cplusplus)

View File

@ -0,0 +1,266 @@
/****************************************************************************
* arch/arm/src/armv7-m/arm_vectors.c
*
* Copyright (C) 2012 Michael Smith. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name NuttX nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include "chip.h"
#include "arm_internal.h"
#include "hc32f4a0_interrupts.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define IDLE_STACK ((unsigned)&_ebss+CONFIG_IDLETHREAD_STACKSIZE)
#ifndef ARMV7M_PERIPHERAL_INTERRUPTS
# error ARMV7M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/* Chip-specific entrypoint */
extern void __start(void);
/* Common exception entrypoint */
extern void exception_common(void);
/****************************************************************************
* Public data
****************************************************************************/
/* The v7m vector table consists of an array of function pointers, with the
* first slot (vector zero) used to hold the initial stack pointer.
*
* As all exceptions (interrupts) are routed via exception_common, we just
* need to fill this array with pointers to it.
*
* Note that the [ ... ] designated initializer is a GCC extension.
*/
#if 0
unsigned _vectors[] locate_data(".vectors") =
{
/* Initial stack */
IDLE_STACK,
/* Reset exception handler */
(unsigned)&__start,
/* Vectors 2 - n point directly at the generic handler */
[2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common
};
#else
unsigned _vectors[] locate_data(".vectors") =
{
/* Initial stack */
IDLE_STACK,
/* Reset exception handler */
(unsigned)&__start,
(unsigned)&NMI_Handler,
(unsigned)&HardFault_Handler,
(unsigned)&MemManage_Handler,
(unsigned)&BusFault_Handler,
(unsigned)&UsageFault_Handler,
(unsigned)&exception_common,
(unsigned)&exception_common,
(unsigned)&exception_common,
(unsigned)&exception_common,
(unsigned)&SVC_Handler, /* SVC */
(unsigned)&DebugMon_Handler, /* DebugMon */
(unsigned)&exception_common,
(unsigned)&PendSV_Handler,
(unsigned)&SysTick_Handler, /* SysTick */
(unsigned)&IRQ000_Handler,
(unsigned)&IRQ001_Handler,
(unsigned)&IRQ002_Handler,
(unsigned)&IRQ003_Handler,
(unsigned)&IRQ004_Handler,
(unsigned)&IRQ005_Handler,
(unsigned)&IRQ006_Handler,
(unsigned)&IRQ007_Handler,
(unsigned)&IRQ008_Handler,
(unsigned)&IRQ009_Handler,
(unsigned)&IRQ010_Handler,
(unsigned)&IRQ011_Handler,
(unsigned)&IRQ012_Handler,
(unsigned)&IRQ013_Handler,
(unsigned)&IRQ014_Handler,
(unsigned)&IRQ015_Handler,
(unsigned)&IRQ016_Handler,
(unsigned)&IRQ017_Handler,
(unsigned)&IRQ018_Handler,
(unsigned)&IRQ019_Handler,
(unsigned)&IRQ020_Handler,
(unsigned)&IRQ021_Handler,
(unsigned)&IRQ022_Handler,
(unsigned)&IRQ023_Handler,
(unsigned)&IRQ024_Handler,
(unsigned)&IRQ025_Handler,
(unsigned)&IRQ026_Handler,
(unsigned)&IRQ027_Handler,
(unsigned)&IRQ028_Handler,
(unsigned)&IRQ029_Handler,
(unsigned)&IRQ030_Handler,
(unsigned)&IRQ031_Handler,
(unsigned)&IRQ032_Handler,
(unsigned)&IRQ033_Handler,
(unsigned)&IRQ034_Handler,
(unsigned)&IRQ035_Handler,
(unsigned)&IRQ036_Handler,
(unsigned)&IRQ037_Handler,
(unsigned)&IRQ038_Handler,
(unsigned)&IRQ039_Handler,
(unsigned)&IRQ040_Handler,
(unsigned)&IRQ041_Handler,
(unsigned)&IRQ042_Handler,
(unsigned)&IRQ043_Handler,
(unsigned)&IRQ044_Handler,
(unsigned)&IRQ045_Handler,
(unsigned)&IRQ046_Handler,
(unsigned)&IRQ047_Handler,
(unsigned)&IRQ048_Handler,
(unsigned)&IRQ049_Handler,
(unsigned)&IRQ050_Handler,
(unsigned)&IRQ051_Handler,
(unsigned)&IRQ052_Handler,
(unsigned)&IRQ053_Handler,
(unsigned)&IRQ054_Handler,
(unsigned)&IRQ055_Handler,
(unsigned)&IRQ056_Handler,
(unsigned)&IRQ057_Handler,
(unsigned)&IRQ058_Handler,
(unsigned)&IRQ059_Handler,
(unsigned)&IRQ060_Handler,
(unsigned)&IRQ061_Handler,
(unsigned)&IRQ062_Handler,
(unsigned)&IRQ063_Handler,
(unsigned)&IRQ064_Handler,
(unsigned)&IRQ065_Handler,
(unsigned)&IRQ066_Handler,
(unsigned)&IRQ067_Handler,
(unsigned)&IRQ068_Handler,
(unsigned)&IRQ069_Handler,
(unsigned)&IRQ070_Handler,
(unsigned)&IRQ071_Handler,
(unsigned)&IRQ072_Handler,
(unsigned)&IRQ073_Handler,
(unsigned)&IRQ074_Handler,
(unsigned)&IRQ075_Handler,
(unsigned)&IRQ076_Handler,
(unsigned)&IRQ077_Handler,
(unsigned)&IRQ078_Handler,
(unsigned)&IRQ079_Handler,
(unsigned)&IRQ080_Handler,
(unsigned)&IRQ081_Handler,
(unsigned)&IRQ082_Handler,
(unsigned)&IRQ083_Handler,
(unsigned)&IRQ084_Handler,
(unsigned)&IRQ085_Handler,
(unsigned)&IRQ086_Handler,
(unsigned)&IRQ087_Handler,
(unsigned)&IRQ088_Handler,
(unsigned)&IRQ089_Handler,
(unsigned)&IRQ090_Handler,
(unsigned)&IRQ091_Handler,
(unsigned)&IRQ092_Handler,
(unsigned)&IRQ093_Handler,
(unsigned)&IRQ094_Handler,
(unsigned)&IRQ095_Handler,
(unsigned)&IRQ096_Handler,
(unsigned)&IRQ097_Handler,
(unsigned)&IRQ098_Handler,
(unsigned)&IRQ099_Handler,
(unsigned)&IRQ100_Handler,
(unsigned)&IRQ101_Handler,
(unsigned)&IRQ102_Handler,
(unsigned)&IRQ103_Handler,
(unsigned)&IRQ104_Handler,
(unsigned)&IRQ105_Handler,
(unsigned)&IRQ106_Handler,
(unsigned)&IRQ107_Handler,
(unsigned)&IRQ108_Handler,
(unsigned)&IRQ109_Handler,
(unsigned)&IRQ110_Handler,
(unsigned)&IRQ111_Handler,
(unsigned)&IRQ112_Handler,
(unsigned)&IRQ113_Handler,
(unsigned)&IRQ114_Handler,
(unsigned)&IRQ115_Handler,
(unsigned)&IRQ116_Handler,
(unsigned)&IRQ117_Handler,
(unsigned)&IRQ118_Handler,
(unsigned)&IRQ119_Handler,
(unsigned)&IRQ120_Handler,
(unsigned)&IRQ121_Handler,
(unsigned)&IRQ122_Handler,
(unsigned)&IRQ123_Handler,
(unsigned)&IRQ124_Handler,
(unsigned)&IRQ125_Handler,
(unsigned)&IRQ126_Handler,
(unsigned)&IRQ127_Handler,
(unsigned)&IRQ128_Handler,
(unsigned)&IRQ129_Handler,
(unsigned)&IRQ130_Handler,
(unsigned)&IRQ131_Handler,
(unsigned)&IRQ132_Handler,
(unsigned)&IRQ133_Handler,
(unsigned)&IRQ134_Handler,
(unsigned)&IRQ135_Handler,
(unsigned)&IRQ136_Handler,
(unsigned)&IRQ137_Handler,
(unsigned)&IRQ138_Handler,
(unsigned)&IRQ139_Handler,
(unsigned)&IRQ140_Handler,
(unsigned)&IRQ141_Handler,
(unsigned)&IRQ142_Handler,
(unsigned)&IRQ143_Handler
// [2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common
};
#endif

View File

@ -137,6 +137,8 @@ typedef struct
#define GPIO_PORT_SHIFT 16
#define GPIO_PINSET(_port, _pin) ((uint32_t)(_port << GPIO_PORT_SHIFT) | _pin)
#define GPIO_PIN(_pinset) ((_pinset >> GPIO_PIN_SHIFT) & GPIO_PIN_MASK)
#define GPIO_PORT(_pinset) ((_pinset >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK)
/**
* @}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,446 @@
/**
*******************************************************************************
* @file hc32f4a0_spi.h
* @brief This file contains all the functions prototypes of the SPI driver
* library.
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Wangmin First version
@endverbatim
*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
#ifndef __HC32F4A0_SPI_H__
#define __HC32F4A0_SPI_H__
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_common.h"
#include "ddl_config.h"
/**
* @addtogroup HC32F4A0_DDL_Driver
* @{
*/
/**
* @addtogroup DDL_SPI
* @{
*/
#if (DDL_SPI_ENABLE == DDL_ON)
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/**
* @defgroup SPI_Global_Types SPI Global Types
* @{
*/
/**
* @brief Structure definition of SPI initialization.
*/
typedef struct
{
uint32_t u32WireMode; /*!< SPI wire mode, 3 wire mode or 4 wire mode.
This parameter can be a value of @ref SPI_Wire_Mode_Define */
uint32_t u32TransMode; /*!< SPI transfer mode, send only or full duplex.
This parameter can be a value of @ref SPI_Transfer_Mode_Define */
uint32_t u32MasterSlave; /*!< SPI master/slave mode.
This parameter can be a value of @ref SPI_Master_Slave_Mode_Define */
uint32_t u32SuspMode; /*!< SPI communication suspend function.
This parameter can be a value of @ref SPI_Communication_Suspend_Function_Define */
uint32_t u32Modfe; /*!< SPI mode fault detect command.
This parameter can be a value of @ref SPI_Mode_Fault_Dectet_Command_Define */
uint32_t u32Parity; /*!< SPI parity check selection.
This parameter can be a value of @ref SPI_Parity_Check_Define */
uint32_t u32SpiMode; /*!< SPI mode.
This parameter can be a value of @ref SPI_Mode_Define */
uint32_t u32BaudRatePrescaler; /*!< SPI baud rate prescaler.
This parameter can be a value of @ref SPI_Baud_Rate_Prescaler_Define */
uint32_t u32DataBits; /*!< SPI data bits, 4 bits ~ 32 bits.
This parameter can be a value of @ref SPI_Data_Size_Define */
uint32_t u32FirstBit; /*!< MSB first or LSB first.
This parameter can be a value of @ref SPI_First_Bit_Define */
uint32_t u32FrameLevel; /*!< SPI frame level, SPI_FRAME_1 ~ SPI_FRAME_4.
This parameter can be a value of @ref SPI_Frame_Level_Define */
} stc_spi_init_t;
/**
* @brief Structure definition of SPI delay time configuration.
*/
typedef struct
{
uint32_t u32IntervalDelay; /*!< SPI interval time delay (Next access delay time)
This parameter can be a value of @ref SPI_Interval_Delay_Time_define */
uint32_t u32ReleaseDelay; /*!< SPI release time delay (SCK invalid delay time)
This parameter can be a value of @ref SPI_Release_Delay_Time_define */
uint32_t u32SetupDelay; /*!< SPI Setup time delay (SCK valid delay time) define
This parameter can be a value of @ref SPI_Setup_Delay_Time_define */
} stc_spi_delay_t;
/**
* @}
*/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/**
* @defgroup SPI_Global_Macros SPI Global Macros
* @{
*/
/**
* @defgroup SPI_Wire_Mode_Define SPI wire mode define
* @{
*/
#define SPI_WIRE_4 (0UL)
#define SPI_WIRE_3 (SPI_CR1_SPIMDS)
/**
* @}
*/
/**
* @defgroup SPI_Transfer_Mode_Define SPI transfer mode define
* @{
*/
#define SPI_FULL_DUPLEX (0UL) /*!< Full duplex. */
#define SPI_SEND_ONLY (SPI_CR1_TXMDS) /*!< Send only. */
/**
* @}
*/
/**
* @defgroup SPI_Master_Slave_Mode_Define SPI master slave mode define
* @{
*/
#define SPI_SLAVE (0UL)
#define SPI_MASTER (SPI_CR1_MSTR)
/**
* @}
*/
/**
* @defgroup SPI_Loopback_Selection_Define SPI loopback selection define
* @note Loopback mode is mainly used for parity self-diagnosis in 4-wire full-duplex mode.
* @{
*/
#define SPI_SPLPBK_INVALID (0UL)
#define SPI_SPLPBK_MOSI_INVERT (SPI_CR1_SPLPBK) /*!< MISO data is the inverse of the data output by MOSI. */
#define SPI_SPLPBK_MOSI (SPI_CR1_SPLPBK2) /*!< MISO data is the data output by MOSI. */
/**
* @}
*/
/**
* @defgroup SPI_Communication_Suspend_Function_Define SPI communication suspend function define
* @{
*/
#define SPI_COM_SUSP_FUNC_OFF (0UL)
#define SPI_COM_SUSP_FUNC_ON (SPI_CR1_CSUSPE)
/**
* @}
*/
/**
* @defgroup SPI_Interrupt_Type_Define SPI interrupt type define
* @{
*/
#define SPI_INT_ERROR (SPI_CR1_EIE) /*!< Including overload, underload and parity error. */
#define SPI_INT_TX_BUFFER_EMPTY (SPI_CR1_TXIE)
#define SPI_INT_RX_BUFFER_FULL (SPI_CR1_RXIE)
#define SPI_INT_IDLE (SPI_CR1_IDIE)
/**
* @}
*/
/**
* @defgroup SPI_Mode_Fault_Dectet_Command_Define SPI mode fault dectect command define
* @{
*/
#define SPI_MODFE_DISABLE (0UL) /*!< Disable mode fault detection. */
#define SPI_MODFE_ENABLE (SPI_CR1_MODFE) /*!< Enable mode fault detection. */
/**
* @}
*/
/**
* @defgroup SPI_Parity_Check_Error_Self_Diagnosis_Define SPI parity check error self diagnosis define
* @{
*/
#define SPI_PATE_DISABLE (0UL) /*!< Disable self diagnosis of parity check. */
#define SPI_PATE_ENABLE (SPI_CR1_PATE) /*!< Enable self diagnosis of parity check. */
/**
* @}
*/
/**
* @defgroup SPI_Parity_Check_Define SPI parity check mode define
* @{
*/
#define SPI_PARITY_INVALID (0UL) /*!< Parity check invalid. */
#define SPI_PARITY_EVEN (SPI_CR1_PAE) /*!< Parity check selection even parity. */
#define SPI_PARITY_ODD (SPI_CR1_PAE | SPI_CR1_PAOE) /*!< Parity check selection odd parity. */
/**
* @}
*/
/**
* @defgroup SPI_Interval_Delay_Time_define SPI interval time delay (Next access delay time) define
* @{
*/
#define SPI_INTERVAL_TIME_1SCK_2PCLK1 (0UL)
#define SPI_INTERVAL_TIME_2SCK_2PCLK1 (SPI_CFG1_MIDI_0)
#define SPI_INTERVAL_TIME_3SCK_2PCLK1 (SPI_CFG1_MIDI_1)
#define SPI_INTERVAL_TIME_4SCK_2PCLK1 (SPI_CFG1_MIDI_1 | SPI_CFG1_MIDI_0)
#define SPI_INTERVAL_TIME_5SCK_2PCLK1 (SPI_CFG1_MIDI_2)
#define SPI_INTERVAL_TIME_6SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_0)
#define SPI_INTERVAL_TIME_7SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_1)
#define SPI_INTERVAL_TIME_8SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_1 | SPI_CFG1_MIDI_0)
/**
* @}
*/
/**
* @defgroup SPI_Release_Delay_Time_define SPI release time delay (SCK invalid delay time) define
* @{
*/
#define SPI_RELEASE_TIME_1SCK (0UL)
#define SPI_RELEASE_TIME_2SCK (SPI_CFG1_MSSDL_0)
#define SPI_RELEASE_TIME_3SCK (SPI_CFG1_MSSDL_1)
#define SPI_RELEASE_TIME_4SCK (SPI_CFG1_MSSDL_1 | SPI_CFG1_MSSDL_0)
#define SPI_RELEASE_TIME_5SCK (SPI_CFG1_MSSDL_2)
#define SPI_RELEASE_TIME_6SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_0)
#define SPI_RELEASE_TIME_7SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_1)
#define SPI_RELEASE_TIME_8SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_1 | SPI_CFG1_MSSDL_0)
/**
* @}
*/
/**
* @defgroup SPI_Setup_Delay_Time_define SPI Setup time delay (SCK valid delay time) define
* @{
*/
#define SPI_SETUP_TIME_1SCK (0UL)
#define SPI_SETUP_TIME_2SCK (SPI_CFG1_MSSI_0)
#define SPI_SETUP_TIME_3SCK (SPI_CFG1_MSSI_1)
#define SPI_SETUP_TIME_4SCK (SPI_CFG1_MSSI_1 | SPI_CFG1_MSSI_0)
#define SPI_SETUP_TIME_5SCK (SPI_CFG1_MSSI_2)
#define SPI_SETUP_TIME_6SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_0)
#define SPI_SETUP_TIME_7SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_1)
#define SPI_SETUP_TIME_8SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_1 | SPI_CFG1_MSSI_0)
/**
* @}
*/
/**
* @defgroup SPI_SS_Pin_Define SPI SSx define
* @{
*/
#define SPI_PIN_SS0 (SPI_CFG1_SS0PV)
#define SPI_PIN_SS1 (SPI_CFG1_SS1PV)
#define SPI_PIN_SS2 (SPI_CFG1_SS2PV)
#define SPI_PIN_SS3 (SPI_CFG1_SS3PV)
/**
* @}
*/
/**
* @defgroup SPI_SS_Active_Level_Define SPI SSx Active Level define
* @{
*/
#define SPI_SS_ACTIVE_LOW (0UL) /*!< SS pin active low. */
#define SPI_SS_ACTIVE_HIGH (1UL) /*!< SS pin active high. */
/**
* @}
*/
/**
* @defgroup SPI_Read_Target_Buffer_Define SPI read data register target buffer define
* @{
*/
#define SPI_RD_TARGET_RD_BUF (0UL) /*!< Read RX buffer. */
#define SPI_RD_TARGET_WR_BUF (SPI_CFG1_SPRDTD) /*!< Read TX buffer. */
/**
* @}
*/
/**
* @defgroup SPI_Frame_Level_Define SPI data frame level define, The Data in the
* SPI_DR register will be send to TX_BUFF after
* enough data frame write to the SPI_DR
* @{
*/
#define SPI_FRAME_1 (0UL) /*!< Data 1 frame */
#define SPI_FRAME_2 (SPI_CFG1_FTHLV_0) /*!< Data 2 frame.*/
#define SPI_FRAME_3 (SPI_CFG1_FTHLV_1) /*!< Data 3 frame.*/
#define SPI_FRAME_4 (SPI_CFG1_FTHLV_0 | SPI_CFG1_FTHLV_1) /*!< Data 4 frame.*/
/**
* @}
*/
/**
* @defgroup SPI_Mode_Define SPI Mode define
* @{
*/
/* SCK pin output low in idle state; MOSI/MISO pin data valid in odd edge , MOSI/MISO pin data change in even edge */
#define SPI_MODE_0 (0UL)
/* SCK pin output low in idle state; MOSI/MISO pin data valid in even edge , MOSI/MISO pin data change in odd edge */
#define SPI_MODE_1 (SPI_CFG2_CPHA)
/* SCK pin output high in idle state; MOSI/MISO pin data valid in odd edge , MOSI/MISO pin data change in even edge */
#define SPI_MODE_2 (SPI_CFG2_CPOL)
/* SCK pin output high in idle state; MOSI/MISO pin data valid in even edge , MOSI/MISO pin data change in odd edge */
#define SPI_MODE_3 (SPI_CFG2_CPOL | SPI_CFG2_CPHA)
/**
* @}
*/
/**
* @defgroup SPI_Baud_Rate_Prescaler_Define SPI baudrate prescaler define
* @{
*/
#define SPI_BR_PCLK1_DIV2 (0UL) /*!< SPI baud rate is the pclk1 divided by 2. */
#define SPI_BR_PCLK1_DIV4 (SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 4. */
#define SPI_BR_PCLK1_DIV8 (SPI_CFG2_MBR_1) /*!< SPI baud rate is the pclk1 clock divided by 8. */
#define SPI_BR_PCLK1_DIV16 (SPI_CFG2_MBR_1 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 16. */
#define SPI_BR_PCLK1_DIV32 (SPI_CFG2_MBR_2) /*!< SPI baud rate is the pclk1 clock divided by 32. */
#define SPI_BR_PCLK1_DIV64 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 64. */
#define SPI_BR_PCLK1_DIV128 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_1) /*!< SPI baud rate is the pclk1 clock divided by 128. */
#define SPI_BR_PCLK1_DIV256 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_1 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 divided by 256. */
/**
* @}
*/
/**
* @defgroup SPI_Data_Size_Define SPI data size define
* @{
*/
#define SPI_DATA_SIZE_4BIT (0UL)
#define SPI_DATA_SIZE_5BIT (SPI_CFG2_DSIZE_0)
#define SPI_DATA_SIZE_6BIT (SPI_CFG2_DSIZE_1)
#define SPI_DATA_SIZE_7BIT (SPI_CFG2_DSIZE_0 | SPI_CFG2_DSIZE_1)
#define SPI_DATA_SIZE_8BIT (SPI_CFG2_DSIZE_2)
#define SPI_DATA_SIZE_9BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_0)
#define SPI_DATA_SIZE_10BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1)
#define SPI_DATA_SIZE_11BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0)
#define SPI_DATA_SIZE_12BIT (SPI_CFG2_DSIZE_3)
#define SPI_DATA_SIZE_13BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_0)
#define SPI_DATA_SIZE_14BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_1)
#define SPI_DATA_SIZE_15BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0)
#define SPI_DATA_SIZE_16BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2)
#define SPI_DATA_SIZE_20BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_0)
#define SPI_DATA_SIZE_24BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1)
#define SPI_DATA_SIZE_32BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0)
/**
* @}
*/
/**
* @defgroup SPI_First_Bit_Define SPI first bit define
* @{
*/
#define SPI_FIRST_MSB (0UL)
#define SPI_FIRST_LSB (SPI_CFG2_LSBF)
/**
* @}
*/
/**
* @defgroup SPI_State_Flag_Define SPI state flag define
* @{
*/
#define SPI_FLAG_OVERLOAD (SPI_SR_OVRERF)
#define SPI_FLAG_IDLE (SPI_SR_IDLNF)
#define SPI_FLAG_MODE_FAULT (SPI_SR_MODFERF)
#define SPI_FLAG_PARITY_ERROR (SPI_SR_PERF)
#define SPI_FLAG_UNDERLOAD (SPI_SR_UDRERF)
#define SPI_FLAG_TX_BUFFER_EMPTY (SPI_SR_TDEF) /*!< This flag is set when the data in the data register \
is copied into the shift register, but the transmission \
of the data bit may not have been completed. */
#define SPI_FLAG_RX_BUFFER_FULL (SPI_SR_RDFF) /*!< When this flag is set, it indicates that a data was received. */
/**
* @}
*/
/**
* @}
*/
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
/**
* @addtogroup SPI_Global_Functions
* @{
*/
en_result_t SPI_StructInit(stc_spi_init_t *pstcInit);
en_result_t SPI_DelayStructInit(stc_spi_delay_t *pstcDelayCfg);
en_result_t SPI_Init(M4_SPI_TypeDef *SPIx, const stc_spi_init_t *pstcInit);
void SPI_DeInit(M4_SPI_TypeDef *SPIx);
void SPI_IntCmd(M4_SPI_TypeDef *SPIx, uint32_t u32IntType, en_functional_state_t enNewState);
void SPI_FunctionCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState);
void SPI_WriteDataReg(M4_SPI_TypeDef *SPIx, uint32_t u32Data);
uint32_t SPI_ReadDataReg(const M4_SPI_TypeDef *SPIx);
en_flag_status_t SPI_GetStatus(const M4_SPI_TypeDef *SPIx, uint32_t u32Flag);
void SPI_ClearFlag(M4_SPI_TypeDef *SPIx, uint32_t u32Flag);
void SPI_LoopbackModeCfg(M4_SPI_TypeDef *SPIx, uint32_t u32Mode);
void SPI_PateCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState);
en_result_t SPI_DelayTimeCfg(M4_SPI_TypeDef *SPIx, const stc_spi_delay_t *pstcDelayCfg);
void SPI_SSValidLevelCfg(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin, en_functional_state_t enNewState);
void SPI_SSPinSel(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin);
void SPI_ReadBufCfg(M4_SPI_TypeDef *SPIx, uint32_t u32ReadBuf);
en_result_t SPI_Transmit(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, uint32_t u32TxLength);
en_result_t SPI_Receive(M4_SPI_TypeDef *SPIx, void *pvRxBuf, uint32_t u32RxLength);
en_result_t SPI_TransmitReceive(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, void *pvRxBuf, uint32_t u32Length);
/**
* @}
*/
#endif /* DDL_SPI_ENABLE */
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __HC32F4A0_SPI_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@ -1,575 +0,0 @@
/**
*******************************************************************************
* @file w25qxx.c
* @brief This midware file provides firmware functions to W25QXX group spi flash.
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Wangmin First version
2020-08-31 Wangmin Modify for MISRAC2012
@endverbatim
*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
/*******************************************************************************
* Include files
******************************************************************************/
#include "w25qxx.h"
#include "ev_hc32f4a0_lqfp176_w25qxx.h"
/**
* @addtogroup BSP
* @{
*/
/**
* @addtogroup Components
* @{
*/
/** @defgroup W25QXX Flash Driver for W25QXX
* @{
*/
#if (BSP_W25QXX_ENABLE == BSP_ON)
/*******************************************************************************
* Local type definitions ('typedef')
******************************************************************************/
/*******************************************************************************
* Local pre-processor symbols/macros ('#define')
******************************************************************************/
/**
* @defgroup W25QXX_Local_Macros W25QXX Local Macros
* @{
*/
#define W25Q_BIT_0 (1UL << 0U)
#define W25Q_BIT_1 (1UL << 1U)
#define W25Q_BIT_2 (1UL << 2U)
#define W25Q_BIT_3 (1UL << 3U)
#define W25Q_BIT_4 (1UL << 4U)
#define W25Q_BIT_5 (1UL << 5U)
#define W25Q_BIT_6 (1UL << 6U)
#define W25Q_BIT_7 (1UL << 7U)
#define W25Q_BIT_8 (1UL << 8U)
#define W25Q_BIT_9 (1UL << 9U)
#define W25Q_BIT_10 (1UL << 10U)
#define W25Q_BIT_11 (1UL << 11U)
#define W25Q_BIT_12 (1UL << 12U)
#define W25Q_BIT_13 (1UL << 13U)
#define W25Q_BIT_14 (1UL << 14U)
#define W25Q_BIT_15 (1UL << 15U)
#define W25Q_ST_BUSY ((uint16_t)W25Q_BIT_0)
#define W25Q_ST_WEL ((uint16_t)W25Q_BIT_1) /*<! Write enable latch. */
#define LOAD_CMD(a, cmd, addr) do { \
(a)[0U] = (cmd); \
(a)[1U] = (uint8_t)((addr) >> 16U); \
(a)[2U] = (uint8_t)((addr) >> 8U); \
(a)[3U] = (uint8_t)(addr); \
} while (0U)
/**
* @}
*/
/*******************************************************************************
* Global variable definitions (declared in header file with 'extern')
******************************************************************************/
/*******************************************************************************
* Local function prototypes ('static')
******************************************************************************/
/**
* @defgroup W25QXX_Local_Functions W25QXX Local Functions
* @{
*/
static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength);
static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength,
uint8_t *pu8Info, uint8_t u8InfoLength);
static void W25QXX_Wt(uint8_t u8Cmd, uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength);
static void W25QXX_Rd(uint8_t u8Cmd, uint32_t u32Address, uint8_t *pu8Data, uint32_t u32DataLength);
static void W25QXX_WaitBusy(void);
static void W25QXX_WriteEnable(void);
static void W25QXX_WriteDisable(void);
static void W25QXX_WritePage(uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength);
static void W25QXX_Write_NoCheck(const uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength);
static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength,
uint8_t *pu8Info, uint8_t u8InfoLength);
/**
* @}
*/
/*******************************************************************************
* Local variable definitions ('static')
******************************************************************************/
static uint8_t W25QXX_BUFFER[4096U];
/*******************************************************************************
* Function implementation - global ('extern') and local ('static')
******************************************************************************/
/**
* @defgroup W25QXX_Global_Functions W25QXX Global Functions
* @{
*/
/**
* @brief Initializes W25QXX.
* @param [out] pstcW25qxx Pointer to a stc_w25qxx_t structure which contains the information of the SPI flash.
* @retval None
*/
void W25QXX_Init(stc_w25qxx_t *pstcW25qxx)
{
BSP_W25Q_SPI_Init();
if (pstcW25qxx != NULL)
{
/* Read Flash ID */
pstcW25qxx->u16ManId = W25QXX_ReadManDeviceId();
switch (pstcW25qxx->u16ManId)
{
case W25Q64:
pstcW25qxx->u32PageCount = 32768UL; /* W25Q64 contains 32768 pages. */
pstcW25qxx->u32SectorCount = 2048U; /* W25Q64 contains 2048 sectors. */
pstcW25qxx->u32BlockCount32k = 0U; /* DO NOT support 32K block. */
pstcW25qxx->u32BlockCount64k = 128U;
pstcW25qxx->u32CapacityInBytes = pstcW25qxx->u32PageCount * W25Q_SIZE_PAGE;
pstcW25qxx->u32CapacityInKB = pstcW25qxx->u32CapacityInBytes * W25Q_SIZE_1K;
break;
default:
break;
}
}
}
/**
* @brief Read manufacturer device ID.
* @param None
* @retval 16 bit manufacturer device ID.
*/
uint16_t W25QXX_ReadManDeviceId(void)
{
uint8_t au8TempId[2U];
uint8_t au8Dummy[3U] = {0U};
uint16_t u16ManID;
W25QXX_ReadCmd(W25Q_MANUFACTURER_DEVICE_ID, au8Dummy, 3U, au8TempId, 2U);
u16ManID = (uint16_t)au8TempId[0U] << 8U;
u16ManID |= au8TempId[1U];
return u16ManID;
}
/**
* @brief Read unique ID.
* @param [out] pu8UniqueId Pointer to a buffer the 64 bit unique ID to be stored.
* @retval None
*/
void W25QXX_ReadUniqueId(uint8_t *pu8UniqueId)
{
uint8_t au8Dummy[4U] = {0U};
W25QXX_ReadCmd(W25Q_READ_UNIQUE_ID, au8Dummy, 4U, pu8UniqueId, 8U);
}
/**
* @brief W25QXX read status register.
* @param None
* @retval 16 bit W25QXX status.
*/
uint16_t W25QXX_ReadStatus(void)
{
uint8_t u8TempStatus;
uint16_t u16RetStatus;
W25QXX_ReadCmd(W25Q_READ_STATUS_REG_2, NULL, 0U, &u8TempStatus, 1U);
u16RetStatus = u8TempStatus;
W25QXX_ReadCmd(W25Q_READ_STATUS_REG_1, NULL, 0U, &u8TempStatus, 1U);
u16RetStatus <<= 8U;
u16RetStatus |= u8TempStatus;
return u16RetStatus;
}
/**
* @brief W25QXX write status register
* @param [in] u16Status Specified status.
* @retval None
*/
void W25QXX_WriteStatus(uint16_t u16Status)
{
uint8_t au8Data[2U];
au8Data[0U] = (uint8_t)u16Status;
au8Data[1U] = (uint8_t)(u16Status >> 8U);
W25QXX_WriteCmd(W25Q_WRITE_STATUS_REG, au8Data, 2U);
}
/**
* @brief W25QXX power down.
* @param None
* @retval None
*/
void W25QXX_PowerDown(void)
{
W25QXX_WriteCmd(W25Q_POWER_DOWN, NULL, 0U);
W25QXX_DELAY_MS(1U);
}
/**
* @brief W25QXX release power down.
* @param None
* @retval None
*/
void W25QXX_ReleasePowerDown(void)
{
W25QXX_WriteCmd(W25Q_RELEASE_POWER_DOWN, NULL, 0U);
W25QXX_DELAY_MS(1U);
}
/**
* @brief W25QXX chip ease.
* @param None
* @retval None
*/
void W25QXX_EraseChip(void)
{
W25QXX_WriteEnable();
W25QXX_WaitBusy();
W25QXX_WriteCmd(W25Q_CHIP_ERASE, NULL, 0U);
W25QXX_WaitBusy();
}
/**
* @brief W25QXX sector ease.
* @param [in] u32SectorAddress The address of the specified sector.
* @retval None
*/
void W25QXX_EraseSector(uint32_t u32SectorAddress)
{
u32SectorAddress *= W25Q_SIZE_SECTOR;
W25QXX_WriteEnable();
W25QXX_WaitBusy();
W25QXX_Wt(W25Q_SECTOR_ERASE, u32SectorAddress, NULL, 0U);
W25QXX_WaitBusy();
W25QXX_WriteDisable();
}
/**
* @brief W25QXX block ease.
* @param [in] u32BlockAddress The address of the specified block.
* @retval None
*/
void W25QXX_EraseBlock(uint32_t u32BlockAddress)
{
W25QXX_Wt(W25Q_BLOCK_ERASE_64K, u32BlockAddress, NULL, 0U);
}
/**
* @brief W25QXX flash write
* @param [in] pBuffer Data buffer to be written
* @param [in] WriteAddr Address to be written
* @param [in] NumByteToWrite Number to be written, (MAX. 65535)
* @retval None
*/
static void W25QXX_Write_NoCheck(const uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint32_t pageremain;
uint32_t u32BufAdrTmp = (uint32_t)pBuffer;
pageremain = 256U - WriteAddr % 256U;
if (NumByteToWrite <= pageremain)
{
pageremain = NumByteToWrite;
}
for(;;)
{
W25QXX_WritePage(WriteAddr, (uint8_t *)u32BufAdrTmp, pageremain);
if (NumByteToWrite == (uint16_t)pageremain)
{
break;
}
else //NumByteToWrite>pageremain
{
u32BufAdrTmp += pageremain;
WriteAddr += pageremain;
NumByteToWrite -= (uint16_t)pageremain;
if (NumByteToWrite > 256U)
{
pageremain = 256U;
}
else
{
pageremain = (uint32_t)NumByteToWrite;
}
}
}
}
/**
* @brief W25QXX write data.
* @param [in] u32Address The start address of the data to be written.
* @param [in] pu8WriteBuf The pointer to the buffer contains the data to be written.
* @param [in] u32NumByteToWrite Buffer size in bytes.
* @retval None
*/
void W25QXX_WriteData(uint32_t u32Address, const uint8_t *pu8WriteBuf, uint32_t u32NumByteToWrite)
{
uint32_t secpos;
uint16_t secoff;
uint16_t secremain;
uint16_t i;
uint8_t *pW25QXX_BUF;
pW25QXX_BUF = W25QXX_BUFFER;
uint32_t u32WriteBufAddr = (uint32_t)&pu8WriteBuf;
secpos = u32Address / 4096U;
secoff = (uint16_t)(u32Address % 4096U);
secremain = 4096U - secoff;
if (u32NumByteToWrite <= secremain)
{
secremain = (uint16_t)u32NumByteToWrite;
}
for(;;)
{
W25QXX_ReadData(secpos * 4096U, pW25QXX_BUF, 4096U); // read one sector content
for (i = 0U; i < secremain; i++) // check if blank sector
{
if (pW25QXX_BUF[secoff + i] != (uint8_t)0xFFU)
{
break;
}
}
if (i < secremain)
{
W25QXX_EraseSector(secpos); // not blank, need erase
for (i = 0U; i < secremain; i++) // backup first
{
pW25QXX_BUF[i + secoff] = pu8WriteBuf[i];
}
W25QXX_Write_NoCheck(pW25QXX_BUF, secpos * 4096U, 4096U); // write back after erase
}
else
{
W25QXX_Write_NoCheck((const uint8_t *)u32WriteBufAddr, u32Address, secremain);
}
if (u32NumByteToWrite == secremain)
{
break;
}
else
{
secpos++; // next sector
secoff = 0U;
u32WriteBufAddr += secremain;
u32Address += secremain;
u32NumByteToWrite -= secremain;
if (u32NumByteToWrite > 4096U)
{
secremain = 4096U;
}
else
{
secremain = (uint16_t)u32NumByteToWrite;
}
}
}
}
/**
* @brief W25QXX read data.
* @param [in] u32Address The start address of the data to be read.
* @param [in] pu8ReadBuf The pointer to the buffer contains the data to be stored.
* @param [in] u32NumByteToRead Buffer size in bytes.
* @retval None
*/
void W25QXX_ReadData(uint32_t u32Address, uint8_t *pu8ReadBuf, uint32_t u32NumByteToRead)
{
W25QXX_Rd(W25Q_READ_DATA, u32Address, pu8ReadBuf, u32NumByteToRead);
}
/**
* @}
*/
/**
* @addtogroup W25QXX_Local_Functions W25QXX Local Functions
* @{
*/
/**
* @brief W25QXX write command.
* @param [in] u8Cmd Command of W25QXX.
* @param [in] pu8CmdData Pointer to a buffer that contains the data following the command.
* @param [in] u32CmdDataLength The length of the command data in bytes.
* @retval None
*/
static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength)
{
W25Q_CS_ACTIVE();
(void)BSP_W25Q_SPI_Transmit(&u8Cmd, 1U);
(void)BSP_W25Q_SPI_Transmit(pu8CmdData, u32CmdDataLength);
W25Q_CS_INACTIVE();
}
/**
* @brief W25QXX read command.
* @param [in] u8Cmd Command of W25QXX.
* @param [in] pu8CmdData Pointer to a buffer that contains the data following the command.
* @param [in] u32CmdDataLength The length of the command data in bytes.
* @param [in] pu8Info The information of the command.
* @param [in] u8InfoLength The length of the information.
* @retval None
*/
static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength,
uint8_t *pu8Info, uint8_t u8InfoLength)
{
W25Q_CS_ACTIVE();
(void)BSP_W25Q_SPI_Transmit(&u8Cmd, 1U);
(void)BSP_W25Q_SPI_Transmit(pu8CmdData, u32CmdDataLength);
(void)BSP_W25Q_SPI_Receive(pu8Info, (uint32_t)u8InfoLength);
W25Q_CS_INACTIVE();
}
/**
* @brief W25QXX write data.
* @param [in] u8Cmd Command of W25QXX.
* @param [in] u32Address The start address of the data to be written.
* @param [in] pu8Data The data to be written.
* @param [in] u32DataLength The length of the data in bytes.
* @retval None
*/
static void W25QXX_Wt(uint8_t u8Cmd, uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength)
{
uint8_t au8Cmd[4U];
LOAD_CMD(au8Cmd, u8Cmd, u32Address);
W25Q_CS_ACTIVE();
(void)BSP_W25Q_SPI_Transmit(au8Cmd, 4U);
(void)BSP_W25Q_SPI_Transmit(pu8Data, u32DataLength);
W25Q_CS_INACTIVE();
}
/**
* @brief W25QXX read data.
* @param [in] u8Cmd Command of W25QXX.
* @param [in] u32Address The start address of the data to be written.
* @param [in] pu8Data The data to be stored.
* @param [in] u32DataLength The length of the data in bytes.
* @retval None
*/
static void W25QXX_Rd(uint8_t u8Cmd, uint32_t u32Address, uint8_t *pu8Data, uint32_t u32DataLength)
{
uint8_t au8Cmd[4U];
LOAD_CMD(au8Cmd, u8Cmd, u32Address);
W25Q_CS_ACTIVE();
(void)BSP_W25Q_SPI_Transmit(au8Cmd, 4U);
(void)BSP_W25Q_SPI_Receive(pu8Data, u32DataLength);
W25Q_CS_INACTIVE();
}
/**
* @brief W25QXX Write enable.
* @param None
* @retval None
*/
static void W25QXX_WriteEnable(void)
{
W25QXX_WriteCmd(W25Q_WRITE_ENABLE, NULL, 0U);
}
/**
* @brief W25QXX Write disable.
* @param None
* @retval None
*/
static void W25QXX_WriteDisable(void)
{
W25QXX_WriteCmd(W25Q_WRITE_DISABLE, NULL, 0U);
}
/**
* @brief Wait while W25QXX is busy.
* @param None
* @retval None
*/
static void W25QXX_WaitBusy(void)
{
while ((W25QXX_ReadStatus() & W25Q_ST_BUSY) == W25Q_ST_BUSY)
{
;
}
}
/**
* @brief W25QXX page program.
* @param [in] u32Address Start address of the page.
* @param [in] pu8Data Pointer to a buffer that contains the data to be written.
* @param [in] u32DataLength Size of the buffer in bytes.
* @retval None
*/
static void W25QXX_WritePage(uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength)
{
W25QXX_WriteEnable();
W25QXX_Wt(W25Q_PAGE_PROGRAM, u32Address, pu8Data, u32DataLength);
W25QXX_WaitBusy();
}
/**
* @}
*/
#endif /* BSP_W25QXX_ENABLE */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

View File

@ -1,197 +0,0 @@
/**
*******************************************************************************
* @file w25qxx.h
* @brief This file provides firmware functions to W25QXX group spi flash.
@verbatim
Change Logs:
Date Author Notes
2020-06-12 Wangmin First version
@endverbatim
*******************************************************************************
* Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
*
* This software component is licensed by HDSC under BSD 3-Clause license
* (the "License"); You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
*******************************************************************************
*/
#ifndef __W25QXX_H__
#define __W25QXX_H__
/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif
/*******************************************************************************
* Include files
******************************************************************************/
#include "hc32_common.h"
/**
* @addtogroup BSP
* @{
*/
/**
* @addtogroup Components
* @{
*/
/** @addtogroup W25QXX
* @{
*/
#if (BSP_W25QXX_ENABLE == BSP_ON)
/*******************************************************************************
* Global type definitions ('typedef')
******************************************************************************/
/**
* @defgroup W25QXX_Global_Types W25QXX Global Types
* @{
*/
/**
* @brief Structure definition of W25QXX information.
*/
typedef struct
{
uint16_t u16ManId; /*!< Manufacturer device ID. */
uint8_t au8UniqueId[8U]; /*!< 64 bit unique ID number. */
uint32_t u32PageCount;
uint32_t u32SectorCount;
uint32_t u32BlockCount32k;
uint32_t u32BlockCount64k;
uint32_t u32CapacityInBytes;
uint32_t u32CapacityInKB;
} stc_w25qxx_t;
/**
* @}
*/
/*******************************************************************************
* Global pre-processor symbols/macros ('#define')
******************************************************************************/
/**
* @defgroup W25QXX_Global_Macros W25QXX Global Macros
* @{
*/
/**
* @defgroup W25QXX_ID W25QXX ID
* @{
*/
#define W25Q80 (0xEF13U)
#define W25Q16 (0xEF14U)
#define W25Q32 (0xEF15U)
#define W25Q64 (0xEF16U)
#define W25Q128 (0xEF17U)
/**
* @}
*/
/**
* @defgroup W25QXX_Command W25QXX Command
* @{
*/
#define W25Q_WRITE_ENABLE ((uint8_t)0x06U)
#define W25Q_VOLATILE_SR_WRITE_ENABLE ((uint8_t)0x50U)
#define W25Q_WRITE_DISABLE ((uint8_t)0x04U)
#define W25Q_READ_STATUS_REG_1 ((uint8_t)0x05U)
#define W25Q_READ_STATUS_REG_2 ((uint8_t)0x35U)
#define W25Q_WRITE_STATUS_REG ((uint8_t)0x01U)
#define W25Q_PAGE_PROGRAM ((uint8_t)0x02U)
#define W25Q_SECTOR_ERASE ((uint8_t)0x20U)
#define W25Q_BLOCK_ERASE_32K ((uint8_t)0x52U)
#define W25Q_BLOCK_ERASE_64K ((uint8_t)0xD8U)
#define W25Q_CHIP_ERASE ((uint8_t)0xC7U)
#define W25Q_ERASE_PROGRAM_SUSPEND ((uint8_t)0x75U)
#define W25Q_ERASE_PROGRAM_RESUME ((uint8_t)0x7AU)
#define W25Q_POWER_DOWN ((uint8_t)0xB9U)
#define W25Q_READ_DATA ((uint8_t)0x03U)
#define W25Q_FAST_READ ((uint8_t)0x0BU)
#define W25Q_DEVICE_ID ((uint8_t)0xABU)
#define W25Q_RELEASE_POWER_DOWN (W25Q_DEVICE_ID)
#define W25Q_MANUFACTURER_DEVICE_ID ((uint8_t)0x90U)
#define W25Q_JEDEC_ID ((uint8_t)0x9FU)
#define W25Q_READ_UNIQUE_ID ((uint8_t)0x4BU)
#define W25Q_READ_SFDP_REG ((uint8_t)0x5AU)
#define W25Q_REASE_SECURITY_REG ((uint8_t)0x44U)
#define W25Q_PROGRAM_SECURITY_REG ((uint8_t)0x42U)
#define W25Q_READ_SECURITY_REG ((uint8_t)0x48U)
#define W25Q_ENABLE_QPI ((uint8_t)0x38U)
#define W25Q_ENABLE_RESET ((uint8_t)0x66U)
#define W25Q_RESET ((uint8_t)0x99U)
/**
* @}
*/
#define W25Q_SIZE_1K (1024U) /*!< 1KB */
#define W25Q_SIZE_PAGE (256U) /*!< 256B/page */
#define W25Q_SIZE_SECTOR (W25Q_SIZE_1K * 4U) /*!< 4KB/sector */
#define W25Q_SIZE_BLOCK (W25Q_SIZE_1K * 64U) /*!< 64KB/block */
/**
* @}
*/
/*******************************************************************************
* Global variable definitions ('extern')
******************************************************************************/
/*******************************************************************************
Global function prototypes (definition in C source)
******************************************************************************/
/**
* @addtogroup W25QXX_Global_Functions W25QXX Global Functions
* @{
*/
void W25QXX_Init(stc_w25qxx_t *pstcW25qxx);
uint16_t W25QXX_ReadManDeviceId(void);
void W25QXX_ReadUniqueId(uint8_t *pu8UniqueId);
uint16_t W25QXX_ReadStatus(void);
void W25QXX_WriteStatus(uint16_t u16Status);
void W25QXX_PowerDown(void);
void W25QXX_ReleasePowerDown(void);
void W25QXX_EraseChip(void);
void W25QXX_EraseSector(uint32_t u32SectorAddress);
void W25QXX_EraseBlock(uint32_t u32BlockAddress);
void W25QXX_WriteData(uint32_t u32Address, const uint8_t *pu8WriteBuf, uint32_t u32NumByteToWrite);
void W25QXX_ReadData(uint32_t u32Address, uint8_t *pu8ReadBuf, uint32_t u32NumByteToRead);
/**
* @}
*/
#endif /* BSP_W25QXX_ENABLE */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* __W25QXX_H__ */
/*******************************************************************************
* EOF (not truncated)
******************************************************************************/

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

View File

@ -0,0 +1,36 @@
menu "TableStorage"
config TABLE_STORAGE
bool "Using Table storage system"
default n
if TABLE_STORAGE
config TABLE_STORAGE_BASIC
bool "Enable TableStorage Basic"
default y
config TABLE_STORAGE_QUERY
bool "[System-level] Enable TableStorage Buffer"
default n
config TABLE_STORAGE_CACHE
bool "[System-level] Enable TableStorage Prefetcher"
default n
config TABLE_STORAGE_PREFETCH
bool "[Table-level] Enable TableStorage Query Cache"
default n
config TABLE_STORAGE_SECOND_INDEX
bool "[Table-level] Enable TableStorage Second Index"
default n
config TABLE_STORAGE_TRANSACTION
bool "(Other) Enable TableStorage Transaction"
default n
endif
endmenu

View File

@ -0,0 +1,153 @@
## README
TableStorage是一款面向泛在操作系统的轻量级表存储原型系统。TableStorage专注于泛在操作系统场景下结构化数据的存储与传统的多层堆叠式软件栈数据库 + 文件系统不同TableStorage避免过度分层从存储全栈角度进行跨层数据库的存储引擎 + 文件系统)的设计,主要包含以下三个属性
- 低冗余:去除文件抽象并直接将“表”存储到设备中, 避免功能冗余和不必要的软件开销
- 兼容性提供一组通用的API 以支持表级的存取操作,与传统数据库中的读写操作兼容
- 可集成:支持组件的深度集成,具体来说, 可以集成事务和执行引擎以满足复杂的事务和查询处理需求
### 开发板
- K210最小系统板Max bit
- SD卡配置
| 引脚 | 作用 | RW007板子 |
| :----------------: | :-------: | :-------: |
| io 27(印丝标注SCK) | SPI1_SCK | SCK |
| io 26(印丝标注SO) | SPI1_MISO | MISO |
| io 28(印丝标注SI) | SPI1_MOSI | MOSI |
| io 29 | CS/BOOT1 | CS |
### 编译说明
- 环境搭建
- 参考https://gitlink.org.cn/xuos/xiuos/tree/prepare_for_master/Ubiquitous%2FXiZi_IIoT%2Fboard%2Fkd233下的**开发环境搭建**小节搭建好XiUOS的开发环境
- 参考https://gitlink.org.cn/xuos/xiuos/tree/prepare_for_master/Ubiquitous%2FRT-Thread_Fusion_XiUOS%2Faiit_board%2Fk210搭建好XiUOS-RTThread的开发环境
- 配置XiUOS-RTThread基本环境
- SD卡的配置按照上表SD卡引脚说明配置
<img src="pic/image-20221123215723700.png" alt="image-20221123215723700" style="zoom: 33%;" />
- 其他推荐配置
<img src="pic/image-20221123215509060.png" alt="image-20221123215509060" style="zoom: 50%;" />
- (可选)如果编译时,出现定时器错误,则可以选择使用软件定时器
<img src="pic/image-20221123215939427.png" alt="image-20221123215939427" style="zoom: 33%;" />
- 配置TableStorage
```shell
scons --menuconfig
```
- 若不开启TableStorage组件则自动在SD卡上使用FATFS
- 若开启TableStorage组件则在SD卡上使用TableStorage默认打开了Enable TableStorage Basic模块当前版本仅支持Basic模块
<img src="pic/image-20221123213344406.png" alt="image-20221123213344406" style="zoom: 33%;" />
- 执行 scons 编译若编译正确无误在当前文件夹下生成rtthread.elf、rtthread.bin。其中rtthread.bin需要烧写到设备中进行运行
- 烧录及运行结果图
```shell
sudo kflash -t rtthread.bin -p /dev/ttyUSB0
```
- 烧录并运行无误,则
<img src="pic/image-20221123215143184.png" alt="image-20221123215143184" style="zoom: 33%;" />
### 调试
- 修改k210/rtconfig.py中的BUILD选项来配置debug模式并重新编译
- 安装openocd下载ubuntu版本64位
- 下载地址:[Releases · kendryte/openocd-kendryte (github.com)](https://github.com/kendryte/openocd-kendryte/releases),推荐下载地址为http://101.36.126.201:8011/kendryte-openocd-0.2.3-ubuntu64.tar.gz
- 安装
```shell
sudo apt install libusb-dev libftdi-dev libhidapi-dev
sudo mv kendryte-openocd-0.2.3-ubuntu64.tar.gz /opt
cd /opt
sudo tar -zxvf kendryte-openocd-0.2.3-ubuntu64.tar.gz
```
- 修改配置文件
sudo vim /opt/kendryte-openocd/tcl/k210.cfg并复制以下内容
```shell
# SiPEED USB-JTAG/TTL
interface ftdi
ftdi_device_desc "Dual RS232"
ftdi_vid_pid 0x0403 0x6010
ftdi_layout_init 0x0508 0x0f1b
ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100
ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400
jtag_rclk 3000
# server port
gdb_port 9999
telnet_port 4444
# add cpu target
set _CHIPNAME riscv
jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x04e4796b
set _TARGETNAME $_CHIPNAME.cpu
target create $_TARGETNAME riscv -chain-position $_TARGETNAME
# command
init
if {[ info exists pulse_srst]} {
ftdi_set_signal nSRST 0
ftdi_set_signal nSRST 1
ftdi_set_signal nSRST z
}
halt
```
- 调试器和Max bit开发板的硬件连线
<img src="pic/image-20221123220234259.png" alt="image-20221123220234259" style="zoom: 33%;" />
- 启动调试器
```shell
sudo /opt/kendryte-openocd/bin/openocd -f /opt/kendryte-openocd/tcl/k210.cfg
```
<img src="pic/image-20221123221828637.png" alt="image-20221123221828637" style="zoom: 33%;" />
- 在Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210目录下连接调试器
```shell
/opt/xpack-riscv-none-embed-gcc-10.2.0-1.2/bin/riscv-none-embed-gdb rtthread.elf --eval-command="target remote 127.0.0.1:9999"
```
- gdb终端调试
<img src="pic/image-20221123222125802.png" alt="image-20221123222125802" style="zoom: 33%;" />
<img src="pic/image-20221123223127817.png" alt="image-20221123223127817" style="zoom:33%;" />
- vscode调试
<img src="pic/image-20221123225705614.png" alt="image-20221123225705614" style="zoom:33%;" />

View File

@ -0,0 +1,26 @@
from building import *
# get current directory
cwd = GetCurrentDir()
# the set of source files associated with this SConscript file.
src = Glob('src/common/*.cc')
src += Glob('src/execution/*.cc')
src += Glob('src/storage/*.cc')
# compile optional modules
if GetDepend(['TABLE_STORAGE_CACHE']):
src += ['src/modules/prefetcher.cc']
if GetDepend(['TABLE_STORAGE_CACHE']):
src += ['src/modules/queryCache.cc']
if GetDepend(['TABLE_STORAGE_CACHE']):
src += ['src/modules/buffer.cc']
if GetDepend(['TABLE_STORAGE_CACHE']):
src += ['src/modules/secondIndex.cc']
# include path
path = [cwd + '/include']
group = DefineGroup('TableStorage', src, depend = ['TABLE_STORAGE'], CPPPATH = path)
Return('group')

View File

@ -0,0 +1,35 @@
/**
* @file BufferItem.h
* @brief BufferItem
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef BUFFERITEM_H
#define BUFFERITEM_H
#include <stdint.h>
#include "Common.h"
namespace LightTable {
class BufferItem {
public:
BufferItem(uint64_t tableID);
virtual ~BufferItem();
// virtual void flush() const = 0;
uint64_t getTableID() { return tableID; }
protected:
uint64_t tableID;
DISALLOW_COPY_AND_ASSIGN(BufferItem);
};
} // namespace LightTable
#endif // BUFFERITEM_H

View File

@ -0,0 +1,144 @@
/**
* @file Common.h
* @brief parameter configuration
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef COMMON_H
#define COMMON_H
#include <rtconfig.h>
#include <time.h>
#include <chrono>
#include <queue>
namespace LightTable {
#define YCSB_TEST
extern int cacheReadNum;
extern int cacheWriteNum;
extern std::chrono::steady_clock::time_point start_time;
extern std::chrono::steady_clock::time_point end_time;
extern double diff_sdcard_read;
extern double diff_sdcard_write;
#define SYSTEM_MAX_CORES 0
#define SYSTEM_MAX_IO_QUEUES 8
#ifndef YCSB_TEST
#define NETWORK_MESSAGE_DATA_MAX_SIZE 4088
#define NETWORK_TRANSMIT_MAX_SIZE 4096
#else
#define NETWORK_MESSAGE_DATA_MAX_SIZE 51192
#define NETWORK_TRANSMIT_MAX_SIZE 51200
#endif
#define SDCARD_TEST_WRITE_BLOCKID 200
#define SDCARD_TEST_READ_BLOCKID 1000
#define SDCARD_TEST_NUM 10000
#define HASH_BUCKET_SIZE 50
#define CACHE_SIZE 500
#define SEGMENT_TYPE_SMALL_BITMAP_SIZE 32768
#define SEGMENT_TYPE_MEDIUM_BITMAP_SIZE 4096
#ifndef YCSB_TEST
#define SEGMENT_TYPE_BIG_BITMAP_SIZE 512
#else
#define SEGMENT_TYPE_BIG_BITMAP_SIZE 512
#endif
#define SEGMENT_TYPE_SMALL_START 64
#define SEGMENT_TYPE_MEDIUM_START 2097216
#define SEGMENT_TYPE_BIG_START 6291528
#define SEGMENT_TYPE_SMALL_CELL_SIZE 4096
#define SEGMENT_TYPE_MEDIUM_CELL_SIZE 65536
#ifndef YCSB_TEST
#define SEGMENT_TYPE_BIG_CELL_SIZE 2097152
#else
#define SEGMENT_TYPE_BIG_CELL_SIZE 65536000
#endif
#define PREFETCH_BLOCK_SERIALIZED_LENGTH 33
#define MAX_BRANCH_COUNT 4
#define PRELOAD_BLOCK_COUNT 10
#define PRELOAD_CHECK_INTERVAL_US 50
#define BLOCK_SIZE 512
#ifndef YCSB_TEST
#define BUFFER_SIZE 200
#else
#define BUFFER_SIZE 300000
#endif
#define CACHED_PAGE_COUNT 100
#define ROOTTABLE_TUPLE_SIZE sizeof(RootTable::TableTuple)
#define TABLE_ID_SIZE sizeof(uint64_t)
#define SYSTEM_TABLE_COUNT 1
#define ROOTTABLE_TABLE_ID 1
#define ROOTTABLE_SEGMENT_ID 1
#define ROOTTABLE_FIRST_BLOCK_ID 14680164
#define TABLE1_META_BLOCKID 1000
#define TABLE1_META_LOG_BLOCKID 10000
#define TABLE1_INDEX_BLOCKID 2000
#define TABLE1_INDEX_LOG_BLOCKID 20000
#define TABLE1_DATA_LOG_BLOCKID 30000
#define META_ENTRY_NUM 8
#define META_ENTRY_SIZE 64
#define BUFFER_MAX 4096
#define COMMON_TABLE_START_ID 101
#define YCSB_TABLE_ID 100
#define TABLE_NAME_LENGTH 32
#define PRIMARY_KEY_LENGTH 128
#define FILE_PATH_LENGTH 1024
#define FILE_NAME_LENGTH 128
#define USER_NAME_LENGTH 32
#define COLUMN_NAME_LENGTH 128
#define COLUMN_TYPE_NAME_LENGTH 32
#define PREFETCH_BLOCK_SERIALIZED_LENGTH 33
#define ROWMAP_SERIALIZED_LENGTH 42
#define SCHEMA_ENTRY_SERIALIZED_LENGTH 181
#define MAX_META_LENGTH 2048
#define MAX_PATH_LENGTH 128
const char METAPATH[MAX_PATH_LENGTH] = "../../data";
struct timespec diff(struct timespec start, struct timespec end);
class Queue {
public:
#ifdef IO_PROFILING
static struct timespec accumulate_io_times();
static struct timespec accumulate_io_submit_times();
#endif
#ifdef IO_PROFILING
static std::queue<struct timespec> io_times;
static std::queue<struct timespec> io_submit_times;
#endif
};
// A macro to disallow the copy constructor and operator= functions
#ifndef DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName &) = delete; \
TypeName &operator=(const TypeName &) = delete;
#endif
} // namespace LightTable
#endif // COMMON_H

View File

@ -0,0 +1,35 @@
/**
* @file CommonTable.h
* @brief CommonTable
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef COMMONTABLE_H
#define COMMONTABLE_H
#include "Table.h"
namespace LightTable {
class CommonTable : public Table {
public:
CommonTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
uint64_t segmentID, SegmentType segmentType,
std::vector<Schema::SchemaEntry> schemaEntrys,
bool usePrimaryKeyIndex = false);
CommonTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID,
uint64_t segmentID, SegmentType segmentType,
bool usePrimaryKeyIndex = false);
friend class MetaHandle;
protected:
DISALLOW_COPY_AND_ASSIGN(CommonTable);
};
} // namespace LightTable
#endif // COMMONTABLE_H

View File

@ -0,0 +1,61 @@
/**
* @file Driver.h
* @brief driver
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef DRIVER_H
#define DRIVER_H
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <atomic>
#include <iostream>
#include <thread>
#include "Common.h"
#include "Error.h"
// #include <mutex>
// #include <pthread.h>
// #include <condition_variable>
#ifdef __cplusplus
extern "C" {
#endif
uint32_t MakeTableStorage(const char *device_name);
#ifdef __cplusplus
}
#endif
namespace LightTable {
class Driver {
public:
static uint32_t driver_init(const char *device_name);
static void driver_cleanup(const char *device_name);
static uint32_t driver_read(uint8_t *buf, uint64_t blockID);
static uint32_t driver_write(uint8_t *buf, uint64_t blockID);
static uint32_t read(uint8_t *buf, uint64_t blockID);
static uint32_t write(uint8_t *buf, uint64_t blockID);
Driver(){};
#ifdef TABLE_STORAGE_CACHE
static BlockCache *blkCache;
#endif
};
} // namespace LightTable
#endif // DRIVER_H

View File

@ -0,0 +1,62 @@
/**
* @file Error.h
* @brief error number
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef ERROR_H
#define ERROR_H
namespace LightTable {
enum ErrorCode {
SUCCESS = 0,
ERROR_TABLE = 1,
SEGMENT_TYPE_ERROR = 2,
SEGMENT_STATUS_ERROR = 3,
SEGMENT_IS_EXHAUSTED = 4,
BUCKET_ITEM_NOT_FOUND = 5,
ADD_BUCKET_ITEM_ERROR = 6,
PREFETCH_BLOCK_NOT_FOUND = 7,
GET_AVAILABLE_BLOCK_ERROR = 8,
BLOCK_OCCUPIED = 9,
ADD_ROW_MAP_ENTRY_ERROR = 10,
ROW_MAP_ENTRY_NOT_FOUND = 11,
ADD_SCHEMA_ENTRY_ERROR = 12,
SCHEMA_ENTRY_NOT_FOUND = 13,
COLUMN_ITEM_NOT_FOUND = 14,
COLUMN_ID_NOT_CONTINUOUS = 15,
DELETE_PARIMARY_KEY_COLUMN = 16,
TABLE_NOT_FOUND = 17,
TABLE_TUPLE_NOT_FOUND = 18,
ADD_TABLE_TUPLE_ERROR = 19,
BUFFER_EMPTY = 20,
TYPE_INVALID = 21,
ROWLOCATION_INVALID = 22,
CREATE_SOCKET_ERROR = 23,
INET_PTON_ERROR = 24,
BIND_SOCKET_ERROR = 25,
LISTEN_SOCKET_ERROR = 26,
ACCEPT_SOCKET_ERROR = 27,
CONNECT_SOCKET_ERROR = 28,
SEND_MESSAGE_ERROR = 29,
EVENT_TYPE_NOT_DEFINED = 30,
SCHEMA_NOT_EXIST = 31,
OPEN_META_FILE_ERROR = 32,
INVALID_META_FILE = 33,
INVALID_MEMORY_BLOCK_ID = 34,
UPDATE_TUPLE_ERROR = 35,
INVALID_PAGE_ID = 36,
ADD_QUERY_CACHE_ERROR = 37,
TRIE_LEAF_EXIST = 38,
TRIE_LEAF_NOT_EXIST = 39,
TRIE_LEAF_NOT_FOUND = 40,
INVALID_SCAN_RANGE = 41,
INVALID_PRELOAD_TASK = 42,
};
} // namespace LightTable
#endif // ERROR_H

View File

@ -0,0 +1,59 @@
/**
* @file HashBucket.h
* @brief HashBucket
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef HASHBUCKET_H
#define HASHBUCKET_H
#include <stdint.h>
// #include <pthread.h>
#include <algorithm>
#include <map>
#include <iostream>
#include <utility>
// #include <mutex>
#include "Common.h"
#include "Error.h"
namespace LightTable {
typedef struct rowLocation {
uint64_t blockID;
uint64_t rowOffset;
} RowLocation;
class HashBucket {
public:
HashBucket();
uint32_t addBucketItem(uint64_t key, RowLocation rowLocation);
uint32_t deleteBucketItem(uint64_t key);
uint32_t updateRowLocation(uint64_t key, RowLocation rowLocation);
uint32_t getRowLocation(uint64_t key, RowLocation &rowLocation);
uint64_t getBucketSize();
uint32_t setBucketSize(uint64_t bucketSize);
uint32_t getAllBucketItems(std::map<uint64_t, RowLocation> &bucketItems);
private:
std::map<uint64_t, RowLocation> bucketItems;
uint64_t bucketSize;
// pthread_mutex_t mtx;
DISALLOW_COPY_AND_ASSIGN(HashBucket);
};
} // namespace LightTable
#endif // HASHBUCKET_H

View File

@ -0,0 +1,63 @@
/**
* @file HashTable.h
* @brief HashTable
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include <stdint.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
#include "Common.h"
#include "HashBucket.h"
namespace LightTable {
class HashTable {
public:
HashTable();
~HashTable();
uint64_t getMapKey(const char *primaryKey);
uint32_t hashToBucket(uint64_t key);
uint32_t getRowLocation(uint32_t bucketID, uint64_t key,
RowLocation &rowLocation);
uint32_t addItem(uint32_t bucketID, uint64_t key, RowLocation rowLocation);
uint32_t deleteItem(uint32_t bucketID, uint64_t key);
uint32_t updateItem(uint32_t bucketID, uint64_t key, RowLocation rowLocation);
uint64_t getItemCount();
uint32_t getAllBuckets(std::vector<HashBucket *> &buckets);
uint32_t refreshRowLocations(uint64_t blockID, uint64_t deleteOffset,
uint64_t rowSize,
std::map<uint64_t, RowLocation> &locationItems);
uint32_t clear();
private:
std::vector<HashBucket *> buckets;
DISALLOW_COPY_AND_ASSIGN(HashTable);
public:
friend class MetaHandle;
};
} // namespace LightTable
#endif // HASHTABLE_H

View File

@ -0,0 +1,101 @@
/**
* @file PrefetchBlockManager.h
* @brief PrefetchBlockManager
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef PREFETCHBLOCKMANAGER_H
#define PREFETCHBLOCKMANAGER_H
#include <stdint.h>
#include <time.h>
#include <stdlib.h>
// #include <pthread.h>
#include <map>
#include <iostream>
#include <algorithm>
#include <chrono>
#include <utility>
// #include <mutex>
#include "Error.h"
#include "Common.h"
#include "SegmentManager.h"
namespace LightTable
{
enum PrefetchBlockStatus
{
PREFETCH_BLOCK_STATUS_IDLE = 0,
PREFETCH_BLOCK_STATUS_BUSY,
};
class PrefetchBlockManager
{
public:
typedef struct prefetchBlockManagerEntry
{
uint64_t blockID;
uint64_t currentOffset;
bool isOccupied;
bool isCached;
uint64_t pageID;
}PrefetchBlockManagerEntry;
PrefetchBlockManager(uint64_t firstBlockID, uint64_t segmentID,
SegmentType segmentType);
~PrefetchBlockManager();
uint64_t blockAllocate(uint64_t rowSize);
uint64_t getNextBlock();
uint32_t setBlockState(uint64_t blockID, bool isOccupied);
uint32_t setOffset(uint64_t blockID, uint64_t currentOffset);
uint32_t getOffset(uint64_t blockID, uint64_t &currentOffset);
uint32_t advanceOffset(uint64_t blockID, uint64_t rowSize);
uint32_t isOccupied(uint64_t blockID, bool &status);
uint32_t getPrefetchBlockEntry(uint64_t blockID,
PrefetchBlockManagerEntry &entry);
uint32_t getAllPrefetchBlockEntrys(std::map<uint64_t,
PrefetchBlockManagerEntry> &entrys);
uint32_t lockBlock(uint64_t blockID);
uint32_t unlockBlock(uint64_t blockID);
uint32_t setIsCached(uint64_t blockID, bool isCached, uint64_t pageID);
bool isCached(uint64_t blockID, uint64_t &pageID);
private:
std::map<uint64_t, PrefetchBlockManagerEntry> prefetchBlocks;
const uint64_t segmentID;
const SegmentType segmentType;
const uint64_t firstBlockID;
uint64_t blockCount;
uint64_t currentID;
DISALLOW_COPY_AND_ASSIGN(PrefetchBlockManager);
public:
friend class QueryCache;
friend class MetaHandle;
};
} // namespace LightTable
#endif // PREFETCHBLOCKMANAGER_H

View File

@ -0,0 +1,57 @@
/**
* @file RWLock.h
* @brief RWLock
* @version 0.1
* @author SYS Lab
* @date 2022.11.01
*/
#ifndef RWLOCK_H
#define RWLOCK_H
#include <stdint.h>
#include <stdio.h>
#include <atomic>
namespace LightTable {
using version_lock_t = uint8_t;
#define LOAD_ORDER std::memory_order_acquire
#define STORE_ORDER std::memory_order_release
static_assert(sizeof(version_lock_t) == 1, "Lock must be 1 byte.");
static constexpr version_lock_t CLIENT_BIT = 0b10000000;
static constexpr version_lock_t NO_CLIENT_BIT = 0b01111111;
static constexpr version_lock_t USED_BIT = 0b01000000;
static constexpr version_lock_t UNLOCKED_BIT = 0b11111110;
#define IS_LOCKED(lock) ((lock)&1)
class RWLock {
std::atomic<version_lock_t> version_lock;
public:
bool lock(const bool blocking = true) {
version_lock_t lock_value = version_lock.load(LOAD_ORDER);
// Compare and swap until we are the thread to set the lock bit
lock_value &= UNLOCKED_BIT;
while (!version_lock.compare_exchange_weak(lock_value, lock_value + 1)) {
lock_value &= UNLOCKED_BIT;
if (!blocking) {
return false;
}
}
return true;
}
void unlock() {
const version_lock_t current_version = version_lock.load(LOAD_ORDER);
version_lock_t new_version = (current_version + 1) % USED_BIT;
new_version |= USED_BIT;
new_version |= (current_version & CLIENT_BIT);
version_lock.store(new_version, STORE_ORDER);
}
};
} // namespace LightTable
#endif // HASHTABLE_H

Some files were not shown because too many files have changed in this diff Show More