From 281389af1cb1de2c83adeb0483ef79a69b47f990 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 27 Sep 2022 20:54:22 +0800 Subject: [PATCH 01/18] support uart1-uart3 for k210 on Nuttx --- .../xidatong-riscv64/include/board.h | 20 + .../xidatong-riscv64/src/k210_bringup.c | 28 + .../nuttx/arch/risc-v/include/k210/irq.h | 49 + .../nuttx/arch/risc-v/src/k210/Kconfig | 267 + .../nuttx/arch/risc-v/src/k210/Make.defs | 4 +- .../nuttx/arch/risc-v/src/k210/fpioa.c | 4932 +++++++++++++++++ .../nuttx/arch/risc-v/src/k210/fpioa.h | 1035 ++++ .../arch/risc-v/src/k210/k210_clockconfig.c | 20 +- .../nuttx/arch/risc-v/src/k210/k210_fpioa.c | 42 +- .../nuttx/arch/risc-v/src/k210/k210_fpioa.h | 330 +- .../nuttx/arch/risc-v/src/k210/k210_serial.c | 733 +++ .../arch/risc-v/src/k210/k210_uart_16550.c | 1002 ++++ .../arch/risc-v/src/k210/k210_uart_16550.h | 340 ++ 13 files changed, 8683 insertions(+), 119 deletions(-) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/include/k210/irq.h create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index 9435e91c8..03564ace5 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -79,6 +79,26 @@ extern "C" #define EXTERN extern #endif + +#define GPIO_CAN_RXD 18 +#define GPIO_CAN_TXD 19 + +#define GPIO_EC200T_RXD 21 +#define GPIO_EC200T_TXD 20 + +#define GPIO_CH376T_RXD 22 +#define GPIO_CH376T_TXD 23 + + +#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 + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c index bc90e372b..227696b1e 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c @@ -36,6 +36,8 @@ #include "k210.h" #include "k210_clockconfig.h" #include "xidatong-riscv64.h" +#include +#include "k210_sysctl.h" #ifdef CONFIG_BSP_USING_CH438 # include "k210_ch438.h" @@ -85,5 +87,31 @@ int k210_bringup(void) } #endif +#ifdef CONFIG_K210_16550_UART1 + sysctl_clock_enable(SYSCTL_CLOCK_UART1); + sysctl_reset(SYSCTL_RESET_UART1); + fpioa_set_function(GPIO_CAN_RXD, FPOA_USART1_RX); + fpioa_set_function(GPIO_CAN_TXD, FPOA_USART1_TX); +#endif + +#ifdef CONFIG_K210_16550_UART2 + sysctl_clock_enable(SYSCTL_CLOCK_UART2); + sysctl_reset(SYSCTL_RESET_UART2); + fpioa_set_function(GPIO_EC200T_RXD, FPOA_USART2_RX); + fpioa_set_function(GPIO_EC200T_TXD, FPOA_USART2_TX); +#endif + +#ifdef CONFIG_K210_16550_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 + +#ifdef CONFIG_BSP_USING_ENET + k210_sysctl_init(); + board_enet_initialize(); +#endif + return ret; } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/include/k210/irq.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/include/k210/irq.h new file mode 100644 index 000000000..a800588bb --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/include/k210/irq.h @@ -0,0 +1,49 @@ +/**************************************************************************** + * arch/risc-v/include/k210/irq.h + * + * 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. + * + ****************************************************************************/ + +#ifndef __ARCH_RISCV_INCLUDE_K210_IRQ_H +#define __ARCH_RISCV_INCLUDE_K210_IRQ_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Map RISC-V exception code to NuttX IRQ */ + +#ifdef CONFIG_K210_WITH_QEMU +#define K210_IRQ_UART0 (RISCV_IRQ_MEXT + 4) +#else +#define K210_IRQ_UART0 (RISCV_IRQ_MEXT + 33) +#define K210_IRQ_UART1 (RISCV_IRQ_MEXT + 11) +#define K210_IRQ_UART2 (RISCV_IRQ_MEXT + 12) +#define K210_IRQ_UART3 (RISCV_IRQ_MEXT + 13) +#endif + +/* Total number of IRQs */ + +#define NR_IRQS (64 + 16 +16) + +#endif /* __ARCH_RISCV_INCLUDE_K210_IRQ_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig index 0502d2b18..bc34095b5 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Kconfig @@ -40,6 +40,273 @@ config K210_LCD_BACKLIGHT endmenu +menuconfig K210_16550_UART + bool "K210 16550 UART Chip support" + select ARCH_HAVE_SERIAL_TERMIOS + default n + +if K210_16550_UART + config K210_16550_SERIAL_DISABLE_REORDERING + bool "Disable reordering of ttySx devices." + default n + ---help--- + NuttX per default reorders the serial ports (/dev/ttySx) so that the + 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. + + config K210_16550_UART1 + bool "K210 16550 UART1" + default n + + if K210_16550_UART1 + + config K210_16550_UART1_BASE + hex "K210 16550 UART1 base address" + default 0x50210000 + + config K210_16550_UART1_CLOCK + int "K210 16550 UART1 clock" + default 195000000 + + + config K210_16550_UART1_IRQ + int "K210 16550 UART1 IRQ number" + default 38 + + config K210_16550_UART1_BAUD + int "K210 16550 UART1 BAUD" + default 115200 + + config K210_16550_UART1_PARITY + int "K210 16550 UART1 parity" + default 0 + range 0 2 + ---help--- + K210 16550 UART1 parity. 0=None, 1=Odd, 2=Even. Default: None + + config K210_16550_UART1_BITS + int "K210 16550 UART1 number of bits" + default 8 + ---help--- + K210 16550 UART1 number of bits. Default: 8 + + config K210_16550_UART1_2STOP + int "K210 16550 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" + default 256 + ---help--- + K210 16550 UART1 Rx buffer size. Default: 128 + + config K210_16550_UART1_TXBUFSIZE + int "K210 16550 UART1 Tx buffer size" + default 256 + ---help--- + K210 16550 UART1 Tx buffer size. Default: 128 + + config K210_16550_UART1_IFLOWCONTROL + bool "K210 16550 UART1 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable K210 16550 UART1 RTS flow control + + config K210_16550_UART1_OFLOWCONTROL + bool "K210 16550 UART1 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable K210 16550 UART1 CTS flow control + + endif # K210_16550_UART1 + + config K210_16550_UART2 + bool "K210 16550 UART2" + default n + + if K210_16550_UART2 + + config K210_16550_UART2_BASE + hex "K210 16550 UART2 base address" + default 0x50220000 + + config K210_16550_UART2_CLOCK + int "K210 16550 UART2 clock" + default 195000000 + + config K210_16550_UART2_IRQ + int "K210 16550 UART2 IRQ number" + default 39 + + config K210_16550_UART2_BAUD + int "K210 16550 UART2 BAUD" + default 115200 + + config K210_16550_UART2_PARITY + int "K210 16550 UART2 parity" + default 0 + range 0 2 + ---help--- + K210 16550 UART2 parity. 0=None, 1=Odd, 2=Even. Default: None + + config K210_16550_UART2_BITS + int "K210 16550 UART2 number of bits" + default 8 + ---help--- + K210 16550 UART2 number of bits. Default: 8 + + config K210_16550_UART2_2STOP + int "K210 16550 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" + default 256 + ---help--- + K210 16550 UART2 Rx buffer size. Default: 128 + + config K210_16550_UART2_TXBUFSIZE + int "K210 16550 UART2 Tx buffer size" + default 256 + ---help--- + K210 16550 UART2 Tx buffer size. Default: 128 + + config K210_16550_UART2_IFLOWCONTROL + bool "K210 16550 UART2 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable K210 16550 UART2 RTS flow control + + config K210_16550_UART2_OFLOWCONTROL + bool "K210 16550 UART2 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable K210 16550 UART2 CTS flow control + + endif # K210_16550_UART2 + + config K210_16550_UART3 + bool "K210 16550 UART3" + default n + + if K210_16550_UART3 + + config K210_16550_UART3_BASE + hex "K210 16550 UART3 base address" + default 0x50230000 + + config K210_16550_UART3_CLOCK + int "K210 16550 UART3 clock" + default 195000000 + + config K210_16550_UART3_IRQ + int "K210 16550 UART3 IRQ number" + default 40 + + config K210_16550_UART3_BAUD + int "K210 16550 UART3 BAUD" + default 115200 + + config K210_16550_UART3_PARITY + int "K210 16550 UART3 parity" + default 0 + range 0 2 + ---help--- + K210 16550 UART3 parity. 0=None, 1=Odd, 2=Even. Default: None + + config K210_16550_UART3_BITS + int "K210 16550 UART3 number of bits" + default 8 + ---help--- + K210 16550 UART3 number of bits. Default: 8 + + config K210_16550_UART3_2STOP + int "K210 16550 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" + default 256 + ---help--- + K210 16550 UART3 Rx buffer size. Default: 128 + + config K210_16550_UART3_TXBUFSIZE + int "K210 16550 UART3 Tx buffer size" + default 256 + ---help--- + K210 16550 UART3 Tx buffer size. Default: 128 + + config K210_16550_UART3_IFLOWCONTROL + bool "K210 16550 UART3 RTS flow control" + default n + select SERIAL_IFLOWCONTROL + ---help--- + Enable K210 16550 UART3 RTS flow control + + config K210_16550_UART3_OFLOWCONTROL + bool "K210 16550 UART3 CTS flow control" + default n + select SERIAL_OFLOWCONTROL + ---help--- + Enable K210 16550 UART3 CTS flow control + + endif # K210_16550_UART3 + + config K210_16550_SUPRESS_CONFIG + bool "Suppress K210 16550 configuration" + default n + + config K210_16550_SUPRESS_INITIAL_CONFIG + bool "Suppress initial K210 16550 configuration" + depends on !K210_16550_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 + just leave the existing console configuration in place. Default: n + + config SERIAL_UART_ARCH_MMIO + bool "Platform access register through the memory mapping" + default y + + config SERIAL_UART_ARCH_IOCTL + bool "Platform has own custom IOCTL" + default n + + config K210_16550_REGINCR + int "Address increment between K210 16550 registers" + default 4 + ---help--- + The address increment between K210 16550 registers. Options are 1, 2, or 4. + Default: 1 + + config K210_16550_REGWIDTH + int "Bit width of K210 16550 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" + default 32 + ---help--- + The bit width of registers. Options are 0, 8, 16, or 32. + Default: 32 + Note: 0 means auto detect address size (uintptr_t) +endif + menu "K210 Others" config K210_WITH_QEMU diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs index 63dbba19a..4089b0be4 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/Make.defs @@ -55,9 +55,9 @@ endif # Specify our C code within this directory to be included 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 +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 +CHIP_CSRCS += k210_sysctl.c k210_uart_16550.c ifeq ($(CONFIG_BUILD_PROTECTED),y) CMN_CSRCS += riscv_task_start.c riscv_pthread_start.c diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c new file mode 100644 index 000000000..093ae74ec --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c @@ -0,0 +1,4932 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include "fpioa.h" +#include "k210_fpioa.h" +#include "k210_sysctl.h" +#include "k210_memorymap.h" + +volatile fpioa_t *const fpioa = (volatile fpioa_t *)K210_FPIOA_BASE; + +/** + * @brief Internal used FPIOA function initialize cell + * + * This is NOT fpioa_io_config_t, can't assign directly + * + */ +typedef struct _fpioa_assign_t +{ + uint32_t ch_sel : 8; + /* Channel select from 256 input. */ + uint32_t ds : 4; + /* Driving selector. */ + uint32_t oe_en : 1; + /* Static output enable, will AND with OE_INV. */ + uint32_t oe_inv : 1; + /* Invert output enable. */ + uint32_t do_sel : 1; + /* Data output select: 0 for DO, 1 for OE. */ + uint32_t do_inv : 1; + /* Invert the result of data output select (DO_SEL). */ + uint32_t pu : 1; + /* Pull up enable. 0 for nothing, 1 for pull up. */ + uint32_t pd : 1; + /* Pull down enable. 0 for nothing, 1 for pull down. */ + uint32_t resv0 : 1; + /* Reserved bits. */ + uint32_t sl : 1; + /* Slew rate control enable. */ + uint32_t ie_en : 1; + /* Static input enable, will AND with IE_INV. */ + uint32_t ie_inv : 1; + /* Invert input enable. */ + uint32_t di_inv : 1; + /* Invert Data input. */ + uint32_t st : 1; + /* Schmitt trigger. */ + uint32_t tie_en : 1; + /* Input tie enable, 1 for enable, 0 for disable. */ + uint32_t tie_val : 1; + /* Input tie value, 1 for high, 0 for low. */ + uint32_t resv1 : 5; + /* Reserved bits. */ + uint32_t pad_di : 1; + /* Read current PAD's data input. */ +} __attribute__((packed, aligned(4))) fpioa_assign_t; + +/* Function list */ +static const fpioa_assign_t function_config[FUNC_MAX] = + { + {.ch_sel = FUNC_JTAG_TCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_JTAG_TDI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_JTAG_TMS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_JTAG_TDO, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_D7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_ARB, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 1, + .tie_val = 1, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI0_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UARTHS_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UARTHS_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV6, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV7, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_SPI1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_I2C1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS9, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS10, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS11, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS12, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS13, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS15, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS16, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS17, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS18, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS19, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS20, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS21, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS22, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS23, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS24, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS25, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS26, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS27, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS28, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS29, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS30, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIOHS31, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_GPIO7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RX, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_TX, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_D7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SS3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_ARB, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 1, + .tie_val = 1, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI1_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI_SLAVE_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 1, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI_SLAVE_SS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SPI_SLAVE_SCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S0_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S1_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_MCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_SCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_WS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_IN_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2S2_OUT_D3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV4, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_RESV5, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C0_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C0_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C1_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C1_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C2_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_I2C2_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_XCLK, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_RST, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_PWDN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_VSYNC, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_HREF, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_PCLK, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D0, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D1, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D2, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D3, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D4, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D5, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D6, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CMOS_D7, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SCCB_SCLK, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_SCCB_SDA, + .ds = 0x0, + .oe_en = 1, + .oe_inv = 1, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART1_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART2_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_CTS, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DSR, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DCD, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RI, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_SIR_IN, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DTR, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RTS, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_OUT2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_OUT1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_SIR_OUT, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_BAUD, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_DE, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_UART3_RS485_EN, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER0_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER1_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_TIMER2_TOGGLE4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_SPI2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CLK_I2C2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL9, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL10, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL11, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL12, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL13, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 1, + .pd = 0, + .resv1 = 0, + .sl = 1, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL15, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL16, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL17, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_CONSTANT, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_INTERNAL18, + .ds = 0x0, + .oe_en = 0, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 1, + .ie_inv = 0, + .di_inv = 0, + .st = 1, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG0, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG1, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG2, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG3, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG4, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG5, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG6, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG7, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG8, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG9, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG10, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG11, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG12, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG13, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG14, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG15, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG16, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG17, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG18, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG19, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG20, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG21, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG22, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG23, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG24, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG25, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG26, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG27, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG28, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG29, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG30, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, + {.ch_sel = FUNC_DEBUG31, + .ds = 0xf, + .oe_en = 1, + .oe_inv = 0, + .do_sel = 0, + .do_inv = 0, + .pu = 0, + .pd = 0, + .resv1 = 0, + .sl = 0, + .ie_en = 0, + .ie_inv = 0, + .di_inv = 0, + .st = 0, + .tie_en = 0, + .tie_val = 0, + .resv0 = 0, + .pad_di = 0}, +}; + +int fpioa_init(void) +{ + int i = 0; + + /* Enable fpioa clock in system controller */ + sysctl_clock_enable(SYSCTL_CLOCK_FPIOA); + + /* Initialize tie */ + fpioa_tie_t tie = {0}; + + /* Set tie enable and tie value */ + for(i = 0; i < FUNC_MAX; i++) + { + tie.en[i / 32] |= (function_config[i].tie_en << (i % 32)); + tie.val[i / 32] |= (function_config[i].tie_val << (i % 32)); + } + + /* Atomic write every 32bit register to fpioa function */ + for(i = 0; i < FUNC_MAX / 32; i++) + { + /* Set value before enable */ + fpioa->tie.val[i] = tie.val[i]; + fpioa->tie.en[i] = tie.en[i]; + } + + return 0; +} + +int fpioa_get_io(int number, fpioa_io_config_t *cfg) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || cfg == NULL) + return -1; + /* Atomic read register */ + *cfg = fpioa->io[number]; + return 0; +} + +int fpioa_set_io(int number, fpioa_io_config_t *cfg) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || cfg == NULL) + return -1; + /* Atomic write register */ + fpioa->io[number] = *cfg; + return 0; +} + +int fpioa_set_io_pull(int number, fpioa_pull_t pull) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || pull >= FPIOA_PULL_MAX) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + + switch(pull) + { + case FPIOA_PULL_NONE: + cfg.pu = 0; + cfg.pd = 0; + break; + case FPIOA_PULL_DOWN: + cfg.pu = 0; + cfg.pd = 1; + break; + case FPIOA_PULL_UP: + cfg.pu = 1; + cfg.pd = 0; + break; + default: + break; + } + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_get_io_pull(int number) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + fpioa_pull_t pull; + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + + if(cfg.pu == 0 && cfg.pd == 1) + pull = FPIOA_PULL_DOWN; + else if(cfg.pu == 1 && cfg.pd == 0) + pull = FPIOA_PULL_UP; + else + pull = FPIOA_PULL_NONE; + return pull; +} + +int fpioa_set_io_driving(int number, fpioa_driving_t driving) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || driving >= FPIOA_DRIVING_MAX) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO driving */ + cfg.ds = driving; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_sl(int number, uint8_t sl_enable) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO slew rate */ + cfg.sl = sl_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_st(int number, uint8_t st_enable) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO schmitt trigger */ + cfg.st = st_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_set_oe_inv(int number, uint8_t inv_enable) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + /* Atomic read register */ + fpioa_io_config_t cfg = fpioa->io[number]; + /* Set IO schmitt trigger */ + cfg.oe_inv = inv_enable; + /* Atomic write register */ + fpioa->io[number] = cfg; + return 0; +} + +int fpioa_get_io_driving(int number) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO) + return -1; + + return fpioa->io[number].ds; +} + +int fpioa_set_function_raw(int number, fpioa_function_t function) +{ + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || function < 0 || function >= FUNC_MAX) + return -1; + /* Atomic write register */ + fpioa->io[number] = (const fpioa_io_config_t){ + .ch_sel = function_config[function].ch_sel, + .ds = function_config[function].ds, + .oe_en = function_config[function].oe_en, + .oe_inv = function_config[function].oe_inv, + .do_sel = function_config[function].do_sel, + .do_inv = function_config[function].do_inv, + .pu = function_config[function].pu, + .pd = function_config[function].pd, + .sl = function_config[function].sl, + .ie_en = function_config[function].ie_en, + .ie_inv = function_config[function].ie_inv, + .di_inv = function_config[function].di_inv, + .st = function_config[function].st, + /* resv and pad_di do not need initialization */ + }; + return 0; +} + +int fpioa_set_function(int number, fpioa_function_t function) +{ + uint8_t index = 0; + /* Check parameters */ + if(number < 0 || number >= FPIOA_NUM_IO || function < 0 || function >= FUNC_MAX) + return -1; + if(function == FUNC_RESV0) + { + fpioa_set_function_raw(number, FUNC_RESV0); + return 0; + } + /* Compare all IO */ + for(index = 0; index < FPIOA_NUM_IO; index++) + { + if((fpioa->io[index].ch_sel == function) && (index != number)) + fpioa_set_function_raw(index, FUNC_RESV0); + } + fpioa_set_function_raw(number, function); + return 0; +} + +int fpioa_set_tie_enable(fpioa_function_t function, int enable) +{ + /* Check parameters */ + if(function < 0 || function >= FUNC_MAX) + return -1; + /* Set tie enable */ + if(enable) + fpioa->tie.en[function / 32] |= (1UL << (function % 32)); + else + fpioa->tie.en[function / 32] &= (~(1UL << (function % 32))); + return 0; +} + +int fpioa_set_tie_value(fpioa_function_t function, int value) +{ + /* Check parameters */ + if(function < 0 || function >= FUNC_MAX) + return -1; + /* Set tie value */ + if(value) + fpioa->tie.val[function / 32] |= (1UL << (function % 32)); + else + fpioa->tie.val[function / 32] &= (~(1UL << (function % 32))); + return 0; +} + +int fpioa_get_io_by_function(fpioa_function_t function) +{ + int index = 0; + for(index = 0; index < FPIOA_NUM_IO; index++) + { + if(fpioa->io[index].ch_sel == function) + return index; + } + + return -1; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h new file mode 100644 index 000000000..15e86eaea --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h @@ -0,0 +1,1035 @@ +/* Copyright 2018 Canaan Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @file + * @brief Field Programmable GPIO Array (FPIOA) + * + * The FPIOA peripheral supports the following features: + * + * - 48 IO with 256 functions + * + * - Schmitt trigger + * + * - Invert input and output + * + * - Pull up and pull down + * + * - Driving selector + * + * - Static input and output + * + */ + +#ifndef _DRIVER_FPIOA_H +#define _DRIVER_FPIOA_H + +#include +//#include "platform.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* clang-format off */ +/* Pad number settings */ +#define FPIOA_NUM_IO (48) +/* clang-format on */ + +/** + * @brief FPIOA IO functions + * + * @note FPIOA pin function table + * + * | Function | Name | Description | + * |-----------|------------------|-----------------------------------| + * | 0 | JTAG_TCLK | JTAG Test Clock | + * | 1 | JTAG_TDI | JTAG Test Data In | + * | 2 | JTAG_TMS | JTAG Test Mode Select | + * | 3 | JTAG_TDO | JTAG Test Data Out | + * | 4 | SPI0_D0 | SPI0 Data 0 | + * | 5 | SPI0_D1 | SPI0 Data 1 | + * | 6 | SPI0_D2 | SPI0 Data 2 | + * | 7 | SPI0_D3 | SPI0 Data 3 | + * | 8 | SPI0_D4 | SPI0 Data 4 | + * | 9 | SPI0_D5 | SPI0 Data 5 | + * | 10 | SPI0_D6 | SPI0 Data 6 | + * | 11 | SPI0_D7 | SPI0 Data 7 | + * | 12 | SPI0_SS0 | SPI0 Chip Select 0 | + * | 13 | SPI0_SS1 | SPI0 Chip Select 1 | + * | 14 | SPI0_SS2 | SPI0 Chip Select 2 | + * | 15 | SPI0_SS3 | SPI0 Chip Select 3 | + * | 16 | SPI0_ARB | SPI0 Arbitration | + * | 17 | SPI0_SCLK | SPI0 Serial Clock | + * | 18 | UARTHS_RX | UART High speed Receiver | + * | 19 | UARTHS_TX | UART High speed Transmitter | + * | 20 | RESV6 | Reserved function | + * | 21 | RESV7 | Reserved function | + * | 22 | CLK_SPI1 | Clock SPI1 | + * | 23 | CLK_I2C1 | Clock I2C1 | + * | 24 | GPIOHS0 | GPIO High speed 0 | + * | 25 | GPIOHS1 | GPIO High speed 1 | + * | 26 | GPIOHS2 | GPIO High speed 2 | + * | 27 | GPIOHS3 | GPIO High speed 3 | + * | 28 | GPIOHS4 | GPIO High speed 4 | + * | 29 | GPIOHS5 | GPIO High speed 5 | + * | 30 | GPIOHS6 | GPIO High speed 6 | + * | 31 | GPIOHS7 | GPIO High speed 7 | + * | 32 | GPIOHS8 | GPIO High speed 8 | + * | 33 | GPIOHS9 | GPIO High speed 9 | + * | 34 | GPIOHS10 | GPIO High speed 10 | + * | 35 | GPIOHS11 | GPIO High speed 11 | + * | 36 | GPIOHS12 | GPIO High speed 12 | + * | 37 | GPIOHS13 | GPIO High speed 13 | + * | 38 | GPIOHS14 | GPIO High speed 14 | + * | 39 | GPIOHS15 | GPIO High speed 15 | + * | 40 | GPIOHS16 | GPIO High speed 16 | + * | 41 | GPIOHS17 | GPIO High speed 17 | + * | 42 | GPIOHS18 | GPIO High speed 18 | + * | 43 | GPIOHS19 | GPIO High speed 19 | + * | 44 | GPIOHS20 | GPIO High speed 20 | + * | 45 | GPIOHS21 | GPIO High speed 21 | + * | 46 | GPIOHS22 | GPIO High speed 22 | + * | 47 | GPIOHS23 | GPIO High speed 23 | + * | 48 | GPIOHS24 | GPIO High speed 24 | + * | 49 | GPIOHS25 | GPIO High speed 25 | + * | 50 | GPIOHS26 | GPIO High speed 26 | + * | 51 | GPIOHS27 | GPIO High speed 27 | + * | 52 | GPIOHS28 | GPIO High speed 28 | + * | 53 | GPIOHS29 | GPIO High speed 29 | + * | 54 | GPIOHS30 | GPIO High speed 30 | + * | 55 | GPIOHS31 | GPIO High speed 31 | + * | 56 | GPIO0 | GPIO pin 0 | + * | 57 | GPIO1 | GPIO pin 1 | + * | 58 | GPIO2 | GPIO pin 2 | + * | 59 | GPIO3 | GPIO pin 3 | + * | 60 | GPIO4 | GPIO pin 4 | + * | 61 | GPIO5 | GPIO pin 5 | + * | 62 | GPIO6 | GPIO pin 6 | + * | 63 | GPIO7 | GPIO pin 7 | + * | 64 | UART1_RX | UART1 Receiver | + * | 65 | UART1_TX | UART1 Transmitter | + * | 66 | UART2_RX | UART2 Receiver | + * | 67 | UART2_TX | UART2 Transmitter | + * | 68 | UART3_RX | UART3 Receiver | + * | 69 | UART3_TX | UART3 Transmitter | + * | 70 | SPI1_D0 | SPI1 Data 0 | + * | 71 | SPI1_D1 | SPI1 Data 1 | + * | 72 | SPI1_D2 | SPI1 Data 2 | + * | 73 | SPI1_D3 | SPI1 Data 3 | + * | 74 | SPI1_D4 | SPI1 Data 4 | + * | 75 | SPI1_D5 | SPI1 Data 5 | + * | 76 | SPI1_D6 | SPI1 Data 6 | + * | 77 | SPI1_D7 | SPI1 Data 7 | + * | 78 | SPI1_SS0 | SPI1 Chip Select 0 | + * | 79 | SPI1_SS1 | SPI1 Chip Select 1 | + * | 80 | SPI1_SS2 | SPI1 Chip Select 2 | + * | 81 | SPI1_SS3 | SPI1 Chip Select 3 | + * | 82 | SPI1_ARB | SPI1 Arbitration | + * | 83 | SPI1_SCLK | SPI1 Serial Clock | + * | 84 | SPI_SLAVE_D0 | SPI Slave Data 0 | + * | 85 | SPI_SLAVE_SS | SPI Slave Select | + * | 86 | SPI_SLAVE_SCLK | SPI Slave Serial Clock | + * | 87 | I2S0_MCLK | I2S0 Master Clock | + * | 88 | I2S0_SCLK | I2S0 Serial Clock(BCLK) | + * | 89 | I2S0_WS | I2S0 Word Select(LRCLK) | + * | 90 | I2S0_IN_D0 | I2S0 Serial Data Input 0 | + * | 91 | I2S0_IN_D1 | I2S0 Serial Data Input 1 | + * | 92 | I2S0_IN_D2 | I2S0 Serial Data Input 2 | + * | 93 | I2S0_IN_D3 | I2S0 Serial Data Input 3 | + * | 94 | I2S0_OUT_D0 | I2S0 Serial Data Output 0 | + * | 95 | I2S0_OUT_D1 | I2S0 Serial Data Output 1 | + * | 96 | I2S0_OUT_D2 | I2S0 Serial Data Output 2 | + * | 97 | I2S0_OUT_D3 | I2S0 Serial Data Output 3 | + * | 98 | I2S1_MCLK | I2S1 Master Clock | + * | 99 | I2S1_SCLK | I2S1 Serial Clock(BCLK) | + * | 100 | I2S1_WS | I2S1 Word Select(LRCLK) | + * | 101 | I2S1_IN_D0 | I2S1 Serial Data Input 0 | + * | 102 | I2S1_IN_D1 | I2S1 Serial Data Input 1 | + * | 103 | I2S1_IN_D2 | I2S1 Serial Data Input 2 | + * | 104 | I2S1_IN_D3 | I2S1 Serial Data Input 3 | + * | 105 | I2S1_OUT_D0 | I2S1 Serial Data Output 0 | + * | 106 | I2S1_OUT_D1 | I2S1 Serial Data Output 1 | + * | 107 | I2S1_OUT_D2 | I2S1 Serial Data Output 2 | + * | 108 | I2S1_OUT_D3 | I2S1 Serial Data Output 3 | + * | 109 | I2S2_MCLK | I2S2 Master Clock | + * | 110 | I2S2_SCLK | I2S2 Serial Clock(BCLK) | + * | 111 | I2S2_WS | I2S2 Word Select(LRCLK) | + * | 112 | I2S2_IN_D0 | I2S2 Serial Data Input 0 | + * | 113 | I2S2_IN_D1 | I2S2 Serial Data Input 1 | + * | 114 | I2S2_IN_D2 | I2S2 Serial Data Input 2 | + * | 115 | I2S2_IN_D3 | I2S2 Serial Data Input 3 | + * | 116 | I2S2_OUT_D0 | I2S2 Serial Data Output 0 | + * | 117 | I2S2_OUT_D1 | I2S2 Serial Data Output 1 | + * | 118 | I2S2_OUT_D2 | I2S2 Serial Data Output 2 | + * | 119 | I2S2_OUT_D3 | I2S2 Serial Data Output 3 | + * | 120 | RESV0 | Reserved function | + * | 121 | RESV1 | Reserved function | + * | 122 | RESV2 | Reserved function | + * | 123 | RESV3 | Reserved function | + * | 124 | RESV4 | Reserved function | + * | 125 | RESV5 | Reserved function | + * | 126 | I2C0_SCLK | I2C0 Serial Clock | + * | 127 | I2C0_SDA | I2C0 Serial Data | + * | 128 | I2C1_SCLK | I2C1 Serial Clock | + * | 129 | I2C1_SDA | I2C1 Serial Data | + * | 130 | I2C2_SCLK | I2C2 Serial Clock | + * | 131 | I2C2_SDA | I2C2 Serial Data | + * | 132 | CMOS_XCLK | DVP System Clock | + * | 133 | CMOS_RST | DVP System Reset | + * | 134 | CMOS_PWDN | DVP Power Down Mode | + * | 135 | CMOS_VSYNC | DVP Vertical Sync | + * | 136 | CMOS_HREF | DVP Horizontal Reference output | + * | 137 | CMOS_PCLK | Pixel Clock | + * | 138 | CMOS_D0 | Data Bit 0 | + * | 139 | CMOS_D1 | Data Bit 1 | + * | 140 | CMOS_D2 | Data Bit 2 | + * | 141 | CMOS_D3 | Data Bit 3 | + * | 142 | CMOS_D4 | Data Bit 4 | + * | 143 | CMOS_D5 | Data Bit 5 | + * | 144 | CMOS_D6 | Data Bit 6 | + * | 145 | CMOS_D7 | Data Bit 7 | + * | 146 | SCCB_SCLK | SCCB Serial Clock | + * | 147 | SCCB_SDA | SCCB Serial Data | + * | 148 | UART1_CTS | UART1 Clear To Send | + * | 149 | UART1_DSR | UART1 Data Set Ready | + * | 150 | UART1_DCD | UART1 Data Carrier Detect | + * | 151 | UART1_RI | UART1 Ring Indicator | + * | 152 | UART1_SIR_IN | UART1 Serial Infrared Input | + * | 153 | UART1_DTR | UART1 Data Terminal Ready | + * | 154 | UART1_RTS | UART1 Request To Send | + * | 155 | UART1_OUT2 | UART1 User-designated Output 2 | + * | 156 | UART1_OUT1 | UART1 User-designated Output 1 | + * | 157 | UART1_SIR_OUT | UART1 Serial Infrared Output | + * | 158 | UART1_BAUD | UART1 Transmit Clock Output | + * | 159 | UART1_RE | UART1 Receiver Output Enable | + * | 160 | UART1_DE | UART1 Driver Output Enable | + * | 161 | UART1_RS485_EN | UART1 RS485 Enable | + * | 162 | UART2_CTS | UART2 Clear To Send | + * | 163 | UART2_DSR | UART2 Data Set Ready | + * | 164 | UART2_DCD | UART2 Data Carrier Detect | + * | 165 | UART2_RI | UART2 Ring Indicator | + * | 166 | UART2_SIR_IN | UART2 Serial Infrared Input | + * | 167 | UART2_DTR | UART2 Data Terminal Ready | + * | 168 | UART2_RTS | UART2 Request To Send | + * | 169 | UART2_OUT2 | UART2 User-designated Output 2 | + * | 170 | UART2_OUT1 | UART2 User-designated Output 1 | + * | 171 | UART2_SIR_OUT | UART2 Serial Infrared Output | + * | 172 | UART2_BAUD | UART2 Transmit Clock Output | + * | 173 | UART2_RE | UART2 Receiver Output Enable | + * | 174 | UART2_DE | UART2 Driver Output Enable | + * | 175 | UART2_RS485_EN | UART2 RS485 Enable | + * | 176 | UART3_CTS | UART3 Clear To Send | + * | 177 | UART3_DSR | UART3 Data Set Ready | + * | 178 | UART3_DCD | UART3 Data Carrier Detect | + * | 179 | UART3_RI | UART3 Ring Indicator | + * | 180 | UART3_SIR_IN | UART3 Serial Infrared Input | + * | 181 | UART3_DTR | UART3 Data Terminal Ready | + * | 182 | UART3_RTS | UART3 Request To Send | + * | 183 | UART3_OUT2 | UART3 User-designated Output 2 | + * | 184 | UART3_OUT1 | UART3 User-designated Output 1 | + * | 185 | UART3_SIR_OUT | UART3 Serial Infrared Output | + * | 186 | UART3_BAUD | UART3 Transmit Clock Output | + * | 187 | UART3_RE | UART3 Receiver Output Enable | + * | 188 | UART3_DE | UART3 Driver Output Enable | + * | 189 | UART3_RS485_EN | UART3 RS485 Enable | + * | 190 | TIMER0_TOGGLE1 | TIMER0 Toggle Output 1 | + * | 191 | TIMER0_TOGGLE2 | TIMER0 Toggle Output 2 | + * | 192 | TIMER0_TOGGLE3 | TIMER0 Toggle Output 3 | + * | 193 | TIMER0_TOGGLE4 | TIMER0 Toggle Output 4 | + * | 194 | TIMER1_TOGGLE1 | TIMER1 Toggle Output 1 | + * | 195 | TIMER1_TOGGLE2 | TIMER1 Toggle Output 2 | + * | 196 | TIMER1_TOGGLE3 | TIMER1 Toggle Output 3 | + * | 197 | TIMER1_TOGGLE4 | TIMER1 Toggle Output 4 | + * | 198 | TIMER2_TOGGLE1 | TIMER2 Toggle Output 1 | + * | 199 | TIMER2_TOGGLE2 | TIMER2 Toggle Output 2 | + * | 200 | TIMER2_TOGGLE3 | TIMER2 Toggle Output 3 | + * | 201 | TIMER2_TOGGLE4 | TIMER2 Toggle Output 4 | + * | 202 | CLK_SPI2 | Clock SPI2 | + * | 203 | CLK_I2C2 | Clock I2C2 | + * | 204 | INTERNAL0 | Internal function signal 0 | + * | 205 | INTERNAL1 | Internal function signal 1 | + * | 206 | INTERNAL2 | Internal function signal 2 | + * | 207 | INTERNAL3 | Internal function signal 3 | + * | 208 | INTERNAL4 | Internal function signal 4 | + * | 209 | INTERNAL5 | Internal function signal 5 | + * | 210 | INTERNAL6 | Internal function signal 6 | + * | 211 | INTERNAL7 | Internal function signal 7 | + * | 212 | INTERNAL8 | Internal function signal 8 | + * | 213 | INTERNAL9 | Internal function signal 9 | + * | 214 | INTERNAL10 | Internal function signal 10 | + * | 215 | INTERNAL11 | Internal function signal 11 | + * | 216 | INTERNAL12 | Internal function signal 12 | + * | 217 | INTERNAL13 | Internal function signal 13 | + * | 218 | INTERNAL14 | Internal function signal 14 | + * | 219 | INTERNAL15 | Internal function signal 15 | + * | 220 | INTERNAL16 | Internal function signal 16 | + * | 221 | INTERNAL17 | Internal function signal 17 | + * | 222 | CONSTANT | Constant function | + * | 223 | INTERNAL18 | Internal function signal 18 | + * | 224 | DEBUG0 | Debug function 0 | + * | 225 | DEBUG1 | Debug function 1 | + * | 226 | DEBUG2 | Debug function 2 | + * | 227 | DEBUG3 | Debug function 3 | + * | 228 | DEBUG4 | Debug function 4 | + * | 229 | DEBUG5 | Debug function 5 | + * | 230 | DEBUG6 | Debug function 6 | + * | 231 | DEBUG7 | Debug function 7 | + * | 232 | DEBUG8 | Debug function 8 | + * | 233 | DEBUG9 | Debug function 9 | + * | 234 | DEBUG10 | Debug function 10 | + * | 235 | DEBUG11 | Debug function 11 | + * | 236 | DEBUG12 | Debug function 12 | + * | 237 | DEBUG13 | Debug function 13 | + * | 238 | DEBUG14 | Debug function 14 | + * | 239 | DEBUG15 | Debug function 15 | + * | 240 | DEBUG16 | Debug function 16 | + * | 241 | DEBUG17 | Debug function 17 | + * | 242 | DEBUG18 | Debug function 18 | + * | 243 | DEBUG19 | Debug function 19 | + * | 244 | DEBUG20 | Debug function 20 | + * | 245 | DEBUG21 | Debug function 21 | + * | 246 | DEBUG22 | Debug function 22 | + * | 247 | DEBUG23 | Debug function 23 | + * | 248 | DEBUG24 | Debug function 24 | + * | 249 | DEBUG25 | Debug function 25 | + * | 250 | DEBUG26 | Debug function 26 | + * | 251 | DEBUG27 | Debug function 27 | + * | 252 | DEBUG28 | Debug function 28 | + * | 253 | DEBUG29 | Debug function 29 | + * | 254 | DEBUG30 | Debug function 30 | + * | 255 | DEBUG31 | Debug function 31 | + * + * Any IO of FPIOA have 256 functions, it is a IO-function matrix. + * All IO have default reset function, after reset, re-configure + * IO function is required. + */ + +/* clang-format off */ +typedef enum _fpioa_function +{ + FUNC_JTAG_TCLK = 0, /*!< JTAG Test Clock */ + FUNC_JTAG_TDI = 1, /*!< JTAG Test Data In */ + FUNC_JTAG_TMS = 2, /*!< JTAG Test Mode Select */ + FUNC_JTAG_TDO = 3, /*!< JTAG Test Data Out */ + FUNC_SPI0_D0 = 4, /*!< SPI0 Data 0 */ + FUNC_SPI0_D1 = 5, /*!< SPI0 Data 1 */ + FUNC_SPI0_D2 = 6, /*!< SPI0 Data 2 */ + FUNC_SPI0_D3 = 7, /*!< SPI0 Data 3 */ + FUNC_SPI0_D4 = 8, /*!< SPI0 Data 4 */ + FUNC_SPI0_D5 = 9, /*!< SPI0 Data 5 */ + FUNC_SPI0_D6 = 10, /*!< SPI0 Data 6 */ + FUNC_SPI0_D7 = 11, /*!< SPI0 Data 7 */ + FUNC_SPI0_SS0 = 12, /*!< SPI0 Chip Select 0 */ + FUNC_SPI0_SS1 = 13, /*!< SPI0 Chip Select 1 */ + FUNC_SPI0_SS2 = 14, /*!< SPI0 Chip Select 2 */ + FUNC_SPI0_SS3 = 15, /*!< SPI0 Chip Select 3 */ + FUNC_SPI0_ARB = 16, /*!< SPI0 Arbitration */ + FUNC_SPI0_SCLK = 17, /*!< SPI0 Serial Clock */ + FUNC_UARTHS_RX = 18, /*!< UART High speed Receiver */ + FUNC_UARTHS_TX = 19, /*!< UART High speed Transmitter */ + FUNC_RESV6 = 20, /*!< Reserved function */ + FUNC_RESV7 = 21, /*!< Reserved function */ + FUNC_CLK_SPI1 = 22, /*!< Clock SPI1 */ + FUNC_CLK_I2C1 = 23, /*!< Clock I2C1 */ + FUNC_GPIOHS0 = 24, /*!< GPIO High speed 0 */ + FUNC_GPIOHS1 = 25, /*!< GPIO High speed 1 */ + FUNC_GPIOHS2 = 26, /*!< GPIO High speed 2 */ + FUNC_GPIOHS3 = 27, /*!< GPIO High speed 3 */ + FUNC_GPIOHS4 = 28, /*!< GPIO High speed 4 */ + FUNC_GPIOHS5 = 29, /*!< GPIO High speed 5 */ + FUNC_GPIOHS6 = 30, /*!< GPIO High speed 6 */ + FUNC_GPIOHS7 = 31, /*!< GPIO High speed 7 */ + FUNC_GPIOHS8 = 32, /*!< GPIO High speed 8 */ + FUNC_GPIOHS9 = 33, /*!< GPIO High speed 9 */ + FUNC_GPIOHS10 = 34, /*!< GPIO High speed 10 */ + FUNC_GPIOHS11 = 35, /*!< GPIO High speed 11 */ + FUNC_GPIOHS12 = 36, /*!< GPIO High speed 12 */ + FUNC_GPIOHS13 = 37, /*!< GPIO High speed 13 */ + FUNC_GPIOHS14 = 38, /*!< GPIO High speed 14 */ + FUNC_GPIOHS15 = 39, /*!< GPIO High speed 15 */ + FUNC_GPIOHS16 = 40, /*!< GPIO High speed 16 */ + FUNC_GPIOHS17 = 41, /*!< GPIO High speed 17 */ + FUNC_GPIOHS18 = 42, /*!< GPIO High speed 18 */ + FUNC_GPIOHS19 = 43, /*!< GPIO High speed 19 */ + FUNC_GPIOHS20 = 44, /*!< GPIO High speed 20 */ + FUNC_GPIOHS21 = 45, /*!< GPIO High speed 21 */ + FUNC_GPIOHS22 = 46, /*!< GPIO High speed 22 */ + FUNC_GPIOHS23 = 47, /*!< GPIO High speed 23 */ + FUNC_GPIOHS24 = 48, /*!< GPIO High speed 24 */ + FUNC_GPIOHS25 = 49, /*!< GPIO High speed 25 */ + FUNC_GPIOHS26 = 50, /*!< GPIO High speed 26 */ + FUNC_GPIOHS27 = 51, /*!< GPIO High speed 27 */ + FUNC_GPIOHS28 = 52, /*!< GPIO High speed 28 */ + FUNC_GPIOHS29 = 53, /*!< GPIO High speed 29 */ + FUNC_GPIOHS30 = 54, /*!< GPIO High speed 30 */ + FUNC_GPIOHS31 = 55, /*!< GPIO High speed 31 */ + FUNC_GPIO0 = 56, /*!< GPIO pin 0 */ + FUNC_GPIO1 = 57, /*!< GPIO pin 1 */ + FUNC_GPIO2 = 58, /*!< GPIO pin 2 */ + FUNC_GPIO3 = 59, /*!< GPIO pin 3 */ + FUNC_GPIO4 = 60, /*!< GPIO pin 4 */ + FUNC_GPIO5 = 61, /*!< GPIO pin 5 */ + FUNC_GPIO6 = 62, /*!< GPIO pin 6 */ + FUNC_GPIO7 = 63, /*!< GPIO pin 7 */ + FUNC_UART1_RX = 64, /*!< UART1 Receiver */ + FUNC_UART1_TX = 65, /*!< UART1 Transmitter */ + FUNC_UART2_RX = 66, /*!< UART2 Receiver */ + FUNC_UART2_TX = 67, /*!< UART2 Transmitter */ + FUNC_UART3_RX = 68, /*!< UART3 Receiver */ + FUNC_UART3_TX = 69, /*!< UART3 Transmitter */ + FUNC_SPI1_D0 = 70, /*!< SPI1 Data 0 */ + FUNC_SPI1_D1 = 71, /*!< SPI1 Data 1 */ + FUNC_SPI1_D2 = 72, /*!< SPI1 Data 2 */ + FUNC_SPI1_D3 = 73, /*!< SPI1 Data 3 */ + FUNC_SPI1_D4 = 74, /*!< SPI1 Data 4 */ + FUNC_SPI1_D5 = 75, /*!< SPI1 Data 5 */ + FUNC_SPI1_D6 = 76, /*!< SPI1 Data 6 */ + FUNC_SPI1_D7 = 77, /*!< SPI1 Data 7 */ + FUNC_SPI1_SS0 = 78, /*!< SPI1 Chip Select 0 */ + FUNC_SPI1_SS1 = 79, /*!< SPI1 Chip Select 1 */ + FUNC_SPI1_SS2 = 80, /*!< SPI1 Chip Select 2 */ + FUNC_SPI1_SS3 = 81, /*!< SPI1 Chip Select 3 */ + FUNC_SPI1_ARB = 82, /*!< SPI1 Arbitration */ + FUNC_SPI1_SCLK = 83, /*!< SPI1 Serial Clock */ + FUNC_SPI_SLAVE_D0 = 84, /*!< SPI Slave Data 0 */ + FUNC_SPI_SLAVE_SS = 85, /*!< SPI Slave Select */ + FUNC_SPI_SLAVE_SCLK = 86, /*!< SPI Slave Serial Clock */ + FUNC_I2S0_MCLK = 87, /*!< I2S0 Master Clock */ + FUNC_I2S0_SCLK = 88, /*!< I2S0 Serial Clock(BCLK) */ + FUNC_I2S0_WS = 89, /*!< I2S0 Word Select(LRCLK) */ + FUNC_I2S0_IN_D0 = 90, /*!< I2S0 Serial Data Input 0 */ + FUNC_I2S0_IN_D1 = 91, /*!< I2S0 Serial Data Input 1 */ + FUNC_I2S0_IN_D2 = 92, /*!< I2S0 Serial Data Input 2 */ + FUNC_I2S0_IN_D3 = 93, /*!< I2S0 Serial Data Input 3 */ + FUNC_I2S0_OUT_D0 = 94, /*!< I2S0 Serial Data Output 0 */ + FUNC_I2S0_OUT_D1 = 95, /*!< I2S0 Serial Data Output 1 */ + FUNC_I2S0_OUT_D2 = 96, /*!< I2S0 Serial Data Output 2 */ + FUNC_I2S0_OUT_D3 = 97, /*!< I2S0 Serial Data Output 3 */ + FUNC_I2S1_MCLK = 98, /*!< I2S1 Master Clock */ + FUNC_I2S1_SCLK = 99, /*!< I2S1 Serial Clock(BCLK) */ + FUNC_I2S1_WS = 100, /*!< I2S1 Word Select(LRCLK) */ + FUNC_I2S1_IN_D0 = 101, /*!< I2S1 Serial Data Input 0 */ + FUNC_I2S1_IN_D1 = 102, /*!< I2S1 Serial Data Input 1 */ + FUNC_I2S1_IN_D2 = 103, /*!< I2S1 Serial Data Input 2 */ + FUNC_I2S1_IN_D3 = 104, /*!< I2S1 Serial Data Input 3 */ + FUNC_I2S1_OUT_D0 = 105, /*!< I2S1 Serial Data Output 0 */ + FUNC_I2S1_OUT_D1 = 106, /*!< I2S1 Serial Data Output 1 */ + FUNC_I2S1_OUT_D2 = 107, /*!< I2S1 Serial Data Output 2 */ + FUNC_I2S1_OUT_D3 = 108, /*!< I2S1 Serial Data Output 3 */ + FUNC_I2S2_MCLK = 109, /*!< I2S2 Master Clock */ + FUNC_I2S2_SCLK = 110, /*!< I2S2 Serial Clock(BCLK) */ + FUNC_I2S2_WS = 111, /*!< I2S2 Word Select(LRCLK) */ + FUNC_I2S2_IN_D0 = 112, /*!< I2S2 Serial Data Input 0 */ + FUNC_I2S2_IN_D1 = 113, /*!< I2S2 Serial Data Input 1 */ + FUNC_I2S2_IN_D2 = 114, /*!< I2S2 Serial Data Input 2 */ + FUNC_I2S2_IN_D3 = 115, /*!< I2S2 Serial Data Input 3 */ + FUNC_I2S2_OUT_D0 = 116, /*!< I2S2 Serial Data Output 0 */ + FUNC_I2S2_OUT_D1 = 117, /*!< I2S2 Serial Data Output 1 */ + FUNC_I2S2_OUT_D2 = 118, /*!< I2S2 Serial Data Output 2 */ + FUNC_I2S2_OUT_D3 = 119, /*!< I2S2 Serial Data Output 3 */ + FUNC_RESV0 = 120, /*!< Reserved function */ + FUNC_RESV1 = 121, /*!< Reserved function */ + FUNC_RESV2 = 122, /*!< Reserved function */ + FUNC_RESV3 = 123, /*!< Reserved function */ + FUNC_RESV4 = 124, /*!< Reserved function */ + FUNC_RESV5 = 125, /*!< Reserved function */ + FUNC_I2C0_SCLK = 126, /*!< I2C0 Serial Clock */ + FUNC_I2C0_SDA = 127, /*!< I2C0 Serial Data */ + FUNC_I2C1_SCLK = 128, /*!< I2C1 Serial Clock */ + FUNC_I2C1_SDA = 129, /*!< I2C1 Serial Data */ + FUNC_I2C2_SCLK = 130, /*!< I2C2 Serial Clock */ + FUNC_I2C2_SDA = 131, /*!< I2C2 Serial Data */ + FUNC_CMOS_XCLK = 132, /*!< DVP System Clock */ + FUNC_CMOS_RST = 133, /*!< DVP System Reset */ + FUNC_CMOS_PWDN = 134, /*!< DVP Power Down Mode */ + FUNC_CMOS_VSYNC = 135, /*!< DVP Vertical Sync */ + FUNC_CMOS_HREF = 136, /*!< DVP Horizontal Reference output */ + FUNC_CMOS_PCLK = 137, /*!< Pixel Clock */ + FUNC_CMOS_D0 = 138, /*!< Data Bit 0 */ + FUNC_CMOS_D1 = 139, /*!< Data Bit 1 */ + FUNC_CMOS_D2 = 140, /*!< Data Bit 2 */ + FUNC_CMOS_D3 = 141, /*!< Data Bit 3 */ + FUNC_CMOS_D4 = 142, /*!< Data Bit 4 */ + FUNC_CMOS_D5 = 143, /*!< Data Bit 5 */ + FUNC_CMOS_D6 = 144, /*!< Data Bit 6 */ + FUNC_CMOS_D7 = 145, /*!< Data Bit 7 */ + FUNC_SCCB_SCLK = 146, /*!< SCCB Serial Clock */ + FUNC_SCCB_SDA = 147, /*!< SCCB Serial Data */ + FUNC_UART1_CTS = 148, /*!< UART1 Clear To Send */ + FUNC_UART1_DSR = 149, /*!< UART1 Data Set Ready */ + FUNC_UART1_DCD = 150, /*!< UART1 Data Carrier Detect */ + FUNC_UART1_RI = 151, /*!< UART1 Ring Indicator */ + FUNC_UART1_SIR_IN = 152, /*!< UART1 Serial Infrared Input */ + FUNC_UART1_DTR = 153, /*!< UART1 Data Terminal Ready */ + FUNC_UART1_RTS = 154, /*!< UART1 Request To Send */ + FUNC_UART1_OUT2 = 155, /*!< UART1 User-designated Output 2 */ + FUNC_UART1_OUT1 = 156, /*!< UART1 User-designated Output 1 */ + FUNC_UART1_SIR_OUT = 157, /*!< UART1 Serial Infrared Output */ + FUNC_UART1_BAUD = 158, /*!< UART1 Transmit Clock Output */ + FUNC_UART1_RE = 159, /*!< UART1 Receiver Output Enable */ + FUNC_UART1_DE = 160, /*!< UART1 Driver Output Enable */ + FUNC_UART1_RS485_EN = 161, /*!< UART1 RS485 Enable */ + FUNC_UART2_CTS = 162, /*!< UART2 Clear To Send */ + FUNC_UART2_DSR = 163, /*!< UART2 Data Set Ready */ + FUNC_UART2_DCD = 164, /*!< UART2 Data Carrier Detect */ + FUNC_UART2_RI = 165, /*!< UART2 Ring Indicator */ + FUNC_UART2_SIR_IN = 166, /*!< UART2 Serial Infrared Input */ + FUNC_UART2_DTR = 167, /*!< UART2 Data Terminal Ready */ + FUNC_UART2_RTS = 168, /*!< UART2 Request To Send */ + FUNC_UART2_OUT2 = 169, /*!< UART2 User-designated Output 2 */ + FUNC_UART2_OUT1 = 170, /*!< UART2 User-designated Output 1 */ + FUNC_UART2_SIR_OUT = 171, /*!< UART2 Serial Infrared Output */ + FUNC_UART2_BAUD = 172, /*!< UART2 Transmit Clock Output */ + FUNC_UART2_RE = 173, /*!< UART2 Receiver Output Enable */ + FUNC_UART2_DE = 174, /*!< UART2 Driver Output Enable */ + FUNC_UART2_RS485_EN = 175, /*!< UART2 RS485 Enable */ + FUNC_UART3_CTS = 176, /*!< UART3 Clear To Send */ + FUNC_UART3_DSR = 177, /*!< UART3 Data Set Ready */ + FUNC_UART3_DCD = 178, /*!< UART3 Data Carrier Detect */ + FUNC_UART3_RI = 179, /*!< UART3 Ring Indicator */ + FUNC_UART3_SIR_IN = 180, /*!< UART3 Serial Infrared Input */ + FUNC_UART3_DTR = 181, /*!< UART3 Data Terminal Ready */ + FUNC_UART3_RTS = 182, /*!< UART3 Request To Send */ + FUNC_UART3_OUT2 = 183, /*!< UART3 User-designated Output 2 */ + FUNC_UART3_OUT1 = 184, /*!< UART3 User-designated Output 1 */ + FUNC_UART3_SIR_OUT = 185, /*!< UART3 Serial Infrared Output */ + FUNC_UART3_BAUD = 186, /*!< UART3 Transmit Clock Output */ + FUNC_UART3_RE = 187, /*!< UART3 Receiver Output Enable */ + FUNC_UART3_DE = 188, /*!< UART3 Driver Output Enable */ + FUNC_UART3_RS485_EN = 189, /*!< UART3 RS485 Enable */ + FUNC_TIMER0_TOGGLE1 = 190, /*!< TIMER0 Toggle Output 1 */ + FUNC_TIMER0_TOGGLE2 = 191, /*!< TIMER0 Toggle Output 2 */ + FUNC_TIMER0_TOGGLE3 = 192, /*!< TIMER0 Toggle Output 3 */ + FUNC_TIMER0_TOGGLE4 = 193, /*!< TIMER0 Toggle Output 4 */ + FUNC_TIMER1_TOGGLE1 = 194, /*!< TIMER1 Toggle Output 1 */ + FUNC_TIMER1_TOGGLE2 = 195, /*!< TIMER1 Toggle Output 2 */ + FUNC_TIMER1_TOGGLE3 = 196, /*!< TIMER1 Toggle Output 3 */ + FUNC_TIMER1_TOGGLE4 = 197, /*!< TIMER1 Toggle Output 4 */ + FUNC_TIMER2_TOGGLE1 = 198, /*!< TIMER2 Toggle Output 1 */ + FUNC_TIMER2_TOGGLE2 = 199, /*!< TIMER2 Toggle Output 2 */ + FUNC_TIMER2_TOGGLE3 = 200, /*!< TIMER2 Toggle Output 3 */ + FUNC_TIMER2_TOGGLE4 = 201, /*!< TIMER2 Toggle Output 4 */ + FUNC_CLK_SPI2 = 202, /*!< Clock SPI2 */ + FUNC_CLK_I2C2 = 203, /*!< Clock I2C2 */ + FUNC_INTERNAL0 = 204, /*!< Internal function signal 0 */ + FUNC_INTERNAL1 = 205, /*!< Internal function signal 1 */ + FUNC_INTERNAL2 = 206, /*!< Internal function signal 2 */ + FUNC_INTERNAL3 = 207, /*!< Internal function signal 3 */ + FUNC_INTERNAL4 = 208, /*!< Internal function signal 4 */ + FUNC_INTERNAL5 = 209, /*!< Internal function signal 5 */ + FUNC_INTERNAL6 = 210, /*!< Internal function signal 6 */ + FUNC_INTERNAL7 = 211, /*!< Internal function signal 7 */ + FUNC_INTERNAL8 = 212, /*!< Internal function signal 8 */ + FUNC_INTERNAL9 = 213, /*!< Internal function signal 9 */ + FUNC_INTERNAL10 = 214, /*!< Internal function signal 10 */ + FUNC_INTERNAL11 = 215, /*!< Internal function signal 11 */ + FUNC_INTERNAL12 = 216, /*!< Internal function signal 12 */ + FUNC_INTERNAL13 = 217, /*!< Internal function signal 13 */ + FUNC_INTERNAL14 = 218, /*!< Internal function signal 14 */ + FUNC_INTERNAL15 = 219, /*!< Internal function signal 15 */ + FUNC_INTERNAL16 = 220, /*!< Internal function signal 16 */ + FUNC_INTERNAL17 = 221, /*!< Internal function signal 17 */ + FUNC_CONSTANT = 222, /*!< Constant function */ + FUNC_INTERNAL18 = 223, /*!< Internal function signal 18 */ + FUNC_DEBUG0 = 224, /*!< Debug function 0 */ + FUNC_DEBUG1 = 225, /*!< Debug function 1 */ + FUNC_DEBUG2 = 226, /*!< Debug function 2 */ + FUNC_DEBUG3 = 227, /*!< Debug function 3 */ + FUNC_DEBUG4 = 228, /*!< Debug function 4 */ + FUNC_DEBUG5 = 229, /*!< Debug function 5 */ + FUNC_DEBUG6 = 230, /*!< Debug function 6 */ + FUNC_DEBUG7 = 231, /*!< Debug function 7 */ + FUNC_DEBUG8 = 232, /*!< Debug function 8 */ + FUNC_DEBUG9 = 233, /*!< Debug function 9 */ + FUNC_DEBUG10 = 234, /*!< Debug function 10 */ + FUNC_DEBUG11 = 235, /*!< Debug function 11 */ + FUNC_DEBUG12 = 236, /*!< Debug function 12 */ + FUNC_DEBUG13 = 237, /*!< Debug function 13 */ + FUNC_DEBUG14 = 238, /*!< Debug function 14 */ + FUNC_DEBUG15 = 239, /*!< Debug function 15 */ + FUNC_DEBUG16 = 240, /*!< Debug function 16 */ + FUNC_DEBUG17 = 241, /*!< Debug function 17 */ + FUNC_DEBUG18 = 242, /*!< Debug function 18 */ + FUNC_DEBUG19 = 243, /*!< Debug function 19 */ + FUNC_DEBUG20 = 244, /*!< Debug function 20 */ + FUNC_DEBUG21 = 245, /*!< Debug function 21 */ + FUNC_DEBUG22 = 246, /*!< Debug function 22 */ + FUNC_DEBUG23 = 247, /*!< Debug function 23 */ + FUNC_DEBUG24 = 248, /*!< Debug function 24 */ + FUNC_DEBUG25 = 249, /*!< Debug function 25 */ + FUNC_DEBUG26 = 250, /*!< Debug function 26 */ + FUNC_DEBUG27 = 251, /*!< Debug function 27 */ + FUNC_DEBUG28 = 252, /*!< Debug function 28 */ + FUNC_DEBUG29 = 253, /*!< Debug function 29 */ + FUNC_DEBUG30 = 254, /*!< Debug function 30 */ + FUNC_DEBUG31 = 255, /*!< Debug function 31 */ + FUNC_MAX = 256, /*!< Function numbers */ +} fpioa_function_t; +/* clang-format on */ + +/** + * @brief FPIOA pull settings + * + * @note FPIOA pull settings description + * + * | PU | PD | Description | + * |-----|-----|-----------------------------------| + * | 0 | 0 | No Pull | + * | 0 | 1 | Pull Down | + * | 1 | 0 | Pull Up | + * | 1 | 1 | Undefined | + * + */ + +/* clang-format off */ +typedef enum _fpioa_pull +{ + FPIOA_PULL_NONE, /*!< No Pull */ + FPIOA_PULL_DOWN, /*!< Pull Down */ + FPIOA_PULL_UP, /*!< Pull Up */ + FPIOA_PULL_MAX /*!< Count of pull settings */ +} fpioa_pull_t; +/* clang-format on */ + +/** + * @brief FPIOA driving settings + * + * @note FPIOA driving settings description + * There are 16 kinds of driving settings + * + * @note Low Level Output Current + * + * |DS[3:0] |Min(mA)|Typ(mA)|Max(mA)| + * |--------|-------|-------|-------| + * |0000 |3.2 |5.4 |8.3 | + * |0001 |4.7 |8.0 |12.3 | + * |0010 |6.3 |10.7 |16.4 | + * |0011 |7.8 |13.2 |20.2 | + * |0100 |9.4 |15.9 |24.2 | + * |0101 |10.9 |18.4 |28.1 | + * |0110 |12.4 |20.9 |31.8 | + * |0111 |13.9 |23.4 |35.5 | + * + * @note High Level Output Current + * + * |DS[3:0] |Min(mA)|Typ(mA)|Max(mA)| + * |--------|-------|-------|-------| + * |0000 |5.0 |7.6 |11.2 | + * |0001 |7.5 |11.4 |16.8 | + * |0010 |10.0 |15.2 |22.3 | + * |0011 |12.4 |18.9 |27.8 | + * |0100 |14.9 |22.6 |33.3 | + * |0101 |17.4 |26.3 |38.7 | + * |0110 |19.8 |30.0 |44.1 | + * |0111 |22.3 |33.7 |49.5 | + * + */ + +/* clang-format off */ +typedef enum _fpioa_driving +{ + FPIOA_DRIVING_0, /*!< 0000 */ + FPIOA_DRIVING_1, /*!< 0001 */ + FPIOA_DRIVING_2, /*!< 0010 */ + FPIOA_DRIVING_3, /*!< 0011 */ + FPIOA_DRIVING_4, /*!< 0100 */ + FPIOA_DRIVING_5, /*!< 0101 */ + FPIOA_DRIVING_6, /*!< 0110 */ + FPIOA_DRIVING_7, /*!< 0111 */ + FPIOA_DRIVING_8, /*!< 1000 */ + FPIOA_DRIVING_9, /*!< 1001 */ + FPIOA_DRIVING_10, /*!< 1010 */ + FPIOA_DRIVING_11, /*!< 1011 */ + FPIOA_DRIVING_12, /*!< 1100 */ + FPIOA_DRIVING_13, /*!< 1101 */ + FPIOA_DRIVING_14, /*!< 1110 */ + FPIOA_DRIVING_15, /*!< 1111 */ + FPIOA_DRIVING_MAX /*!< Count of driving settings */ +} fpioa_driving_t; +/* clang-format on */ + +/** + * @brief FPIOA IO + * + * FPIOA IO is the specific pin of the chip package. Every IO + * has a 32bit width register that can independently implement + * schmitt trigger, invert input, invert output, strong pull + * up, driving selector, static input and static output. And more, + * it can implement any pin of any peripheral devices. + * + * @note FPIOA IO's register bits Layout + * + * | Bits | Name |Description | + * |-----------|----------|---------------------------------------------------| + * | 31 | PAD_DI | Read current IO's data input. | + * | 30:24 | NA | Reserved bits. | + * | 23 | ST | Schmitt trigger. | + * | 22 | DI_INV | Invert Data input. | + * | 21 | IE_INV | Invert the input enable signal. | + * | 20 | IE_EN | Input enable. It can disable or enable IO input. | + * | 19 | SL | Slew rate control enable. | + * | 18 | SPU | Strong pull up. | + * | 17 | PD | Pull select: 0 for pull down, 1 for pull up. | + * | 16 | PU | Pull enable. | + * | 15 | DO_INV | Invert the result of data output select (DO_SEL). | + * | 14 | DO_SEL | Data output select: 0 for DO, 1 for OE. | + * | 13 | OE_INV | Invert the output enable signal. | + * | 12 | OE_EN | Output enable.It can disable or enable IO output. | + * | 11:8 | DS | Driving selector. | + * | 7:0 | CH_SEL | Channel select from 256 input. | + * + */ +typedef struct _fpioa_io_config +{ + uint32_t ch_sel : 8; + /*!< Channel select from 256 input. */ + uint32_t ds : 4; + /*!< Driving selector. */ + uint32_t oe_en : 1; + /*!< Static output enable, will AND with OE_INV. */ + uint32_t oe_inv : 1; + /*!< Invert output enable. */ + uint32_t do_sel : 1; + /*!< Data output select: 0 for DO, 1 for OE. */ + uint32_t do_inv : 1; + /*!< Invert the result of data output select (DO_SEL). */ + uint32_t pu : 1; + /*!< Pull up enable. 0 for nothing, 1 for pull up. */ + uint32_t pd : 1; + /*!< Pull down enable. 0 for nothing, 1 for pull down. */ + uint32_t resv0 : 1; + /*!< Reserved bits. */ + uint32_t sl : 1; + /*!< Slew rate control enable. */ + uint32_t ie_en : 1; + /*!< Static input enable, will AND with IE_INV. */ + uint32_t ie_inv : 1; + /*!< Invert input enable. */ + uint32_t di_inv : 1; + /*!< Invert Data input. */ + uint32_t st : 1; + /*!< Schmitt trigger. */ + uint32_t resv1 : 7; + /*!< Reserved bits. */ + uint32_t pad_di : 1; + /*!< Read current IO's data input. */ +} __attribute__((packed, aligned(4))) fpioa_io_config_t; + +/** + * @brief FPIOA tie setting + * + * FPIOA Object have 48 IO pin object and 256 bit input tie bits. + * All SPI arbitration signal will tie high by default. + * + * @note FPIOA function tie bits RAM Layout + * + * | Address | Name |Description | + * |-----------|------------------|----------------------------------| + * | 0x000 | TIE_EN[31:0] | Input tie enable bits [31:0] | + * | 0x004 | TIE_EN[63:32] | Input tie enable bits [63:32] | + * | 0x008 | TIE_EN[95:64] | Input tie enable bits [95:64] | + * | 0x00C | TIE_EN[127:96] | Input tie enable bits [127:96] | + * | 0x010 | TIE_EN[159:128] | Input tie enable bits [159:128] | + * | 0x014 | TIE_EN[191:160] | Input tie enable bits [191:160] | + * | 0x018 | TIE_EN[223:192] | Input tie enable bits [223:192] | + * | 0x01C | TIE_EN[255:224] | Input tie enable bits [255:224] | + * | 0x020 | TIE_VAL[31:0] | Input tie value bits [31:0] | + * | 0x024 | TIE_VAL[63:32] | Input tie value bits [63:32] | + * | 0x028 | TIE_VAL[95:64] | Input tie value bits [95:64] | + * | 0x02C | TIE_VAL[127:96] | Input tie value bits [127:96] | + * | 0x030 | TIE_VAL[159:128] | Input tie value bits [159:128] | + * | 0x034 | TIE_VAL[191:160] | Input tie value bits [191:160] | + * | 0x038 | TIE_VAL[223:192] | Input tie value bits [223:192] | + * | 0x03C | TIE_VAL[255:224] | Input tie value bits [255:224] | + * + * @note Function which input tie high by default + * + * | Name |Description | + * |---------------|---------------------------------------| + * | SPI0_ARB | Arbitration function of SPI master 0 | + * | SPI1_ARB | Arbitration function of SPI master 1 | + * + * Tie high means the SPI Arbitration input is 1 + * + */ +typedef struct _fpioa_tie +{ + uint32_t en[FUNC_MAX / 32]; + /*!< FPIOA GPIO multiplexer tie enable array */ + uint32_t val[FUNC_MAX / 32]; + /*!< FPIOA GPIO multiplexer tie value array */ +} __attribute__((packed, aligned(4))) fpioa_tie_t; + +/** + * @brief FPIOA Object + * + * FPIOA Object have 48 IO pin object and 256 bit input tie bits. + * All SPI arbitration signal will tie high by default. + * + * @note FPIOA IO Pin RAM Layout + * + * | Address | Name |Description | + * |-----------|----------|--------------------------------| + * | 0x000 | PAD0 | FPIOA GPIO multiplexer io 0 | + * | 0x004 | PAD1 | FPIOA GPIO multiplexer io 1 | + * | 0x008 | PAD2 | FPIOA GPIO multiplexer io 2 | + * | 0x00C | PAD3 | FPIOA GPIO multiplexer io 3 | + * | 0x010 | PAD4 | FPIOA GPIO multiplexer io 4 | + * | 0x014 | PAD5 | FPIOA GPIO multiplexer io 5 | + * | 0x018 | PAD6 | FPIOA GPIO multiplexer io 6 | + * | 0x01C | PAD7 | FPIOA GPIO multiplexer io 7 | + * | 0x020 | PAD8 | FPIOA GPIO multiplexer io 8 | + * | 0x024 | PAD9 | FPIOA GPIO multiplexer io 9 | + * | 0x028 | PAD10 | FPIOA GPIO multiplexer io 10 | + * | 0x02C | PAD11 | FPIOA GPIO multiplexer io 11 | + * | 0x030 | PAD12 | FPIOA GPIO multiplexer io 12 | + * | 0x034 | PAD13 | FPIOA GPIO multiplexer io 13 | + * | 0x038 | PAD14 | FPIOA GPIO multiplexer io 14 | + * | 0x03C | PAD15 | FPIOA GPIO multiplexer io 15 | + * | 0x040 | PAD16 | FPIOA GPIO multiplexer io 16 | + * | 0x044 | PAD17 | FPIOA GPIO multiplexer io 17 | + * | 0x048 | PAD18 | FPIOA GPIO multiplexer io 18 | + * | 0x04C | PAD19 | FPIOA GPIO multiplexer io 19 | + * | 0x050 | PAD20 | FPIOA GPIO multiplexer io 20 | + * | 0x054 | PAD21 | FPIOA GPIO multiplexer io 21 | + * | 0x058 | PAD22 | FPIOA GPIO multiplexer io 22 | + * | 0x05C | PAD23 | FPIOA GPIO multiplexer io 23 | + * | 0x060 | PAD24 | FPIOA GPIO multiplexer io 24 | + * | 0x064 | PAD25 | FPIOA GPIO multiplexer io 25 | + * | 0x068 | PAD26 | FPIOA GPIO multiplexer io 26 | + * | 0x06C | PAD27 | FPIOA GPIO multiplexer io 27 | + * | 0x070 | PAD28 | FPIOA GPIO multiplexer io 28 | + * | 0x074 | PAD29 | FPIOA GPIO multiplexer io 29 | + * | 0x078 | PAD30 | FPIOA GPIO multiplexer io 30 | + * | 0x07C | PAD31 | FPIOA GPIO multiplexer io 31 | + * | 0x080 | PAD32 | FPIOA GPIO multiplexer io 32 | + * | 0x084 | PAD33 | FPIOA GPIO multiplexer io 33 | + * | 0x088 | PAD34 | FPIOA GPIO multiplexer io 34 | + * | 0x08C | PAD35 | FPIOA GPIO multiplexer io 35 | + * | 0x090 | PAD36 | FPIOA GPIO multiplexer io 36 | + * | 0x094 | PAD37 | FPIOA GPIO multiplexer io 37 | + * | 0x098 | PAD38 | FPIOA GPIO multiplexer io 38 | + * | 0x09C | PAD39 | FPIOA GPIO multiplexer io 39 | + * | 0x0A0 | PAD40 | FPIOA GPIO multiplexer io 40 | + * | 0x0A4 | PAD41 | FPIOA GPIO multiplexer io 41 | + * | 0x0A8 | PAD42 | FPIOA GPIO multiplexer io 42 | + * | 0x0AC | PAD43 | FPIOA GPIO multiplexer io 43 | + * | 0x0B0 | PAD44 | FPIOA GPIO multiplexer io 44 | + * | 0x0B4 | PAD45 | FPIOA GPIO multiplexer io 45 | + * | 0x0B8 | PAD46 | FPIOA GPIO multiplexer io 46 | + * | 0x0BC | PAD47 | FPIOA GPIO multiplexer io 47 | + * + */ +typedef struct _fpioa +{ + fpioa_io_config_t io[FPIOA_NUM_IO]; + /*!< FPIOA GPIO multiplexer io array */ + fpioa_tie_t tie; + /*!< FPIOA GPIO multiplexer tie */ +} __attribute__((packed, aligned(4))) fpioa_t; + +/** + * @brief FPIOA object instanse + */ +extern volatile fpioa_t *const fpioa; + +/** + * @brief Initialize FPIOA user custom default settings + * + * @note This function will set all FPIOA pad registers to user-defined + * values from kconfig + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_init(void); + +/** + * @brief Get IO configuration + * + * @param[in] number The IO number + * @param cfg Pointer to struct of IO configuration for specified IO + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_get_io(int number, fpioa_io_config_t *cfg); + +/** + * @brief Set IO configuration + * + * @param[in] number The IO number + * @param[in] cfg Pointer to struct of IO configuration for specified IO + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io(int number, fpioa_io_config_t *cfg); + +/** + * @brief Set IO configuration with function number + * + * @note The default IO configuration which bind to function number will + * set automatically + * + * @param[in] number The IO number + * @param[in] function The function enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_function_raw(int number, fpioa_function_t function); + +/** + * @brief Set only IO configuration with function number + * + * @note The default IO configuration which bind to function number will + * set automatically + * + * @param[in] number The IO number + * @param[in] function The function enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_function(int number, fpioa_function_t function); + +/** + * @brief Set tie enable to function + * + * @param[in] function The function enum number + * @param[in] enable Tie enable to set, 1 is enable, 0 is disable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_tie_enable(fpioa_function_t function, int enable); + +/** + * @brief Set tie value to function + * + * @param[in] function The function enum number + * @param[in] value Tie value to set, 1 is HIGH, 0 is LOW + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_tie_value(fpioa_function_t function, int value); + +/** + * @brief Set IO pull function + * + * @param[in] number The IO number + * @param[in] pull The pull enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io_pull(int number, fpioa_pull_t pull); + +/** + * @brief Get IO pull function + * + * @param[in] number The IO number + * + * @return result + * - -1 Fail + * - Other The pull enum number + */ +int fpioa_get_io_pull(int number); + +/** + * @brief Set IO driving + * + * @param[in] number The IO number + * @param[in] driving The driving enum number + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_io_driving(int number, fpioa_driving_t driving); + +/** + * @brief Get IO driving + * + * @param[in] number The IO number + * + * @return result + * - -1 Fail + * - Other The driving enum number + */ +int fpioa_get_io_driving(int number); + +/** + * @brief Get IO by function + * + * @param[in] function The function enum number + * + * @return result + * - -1 Fail + * - Other The IO number + */ +int fpioa_get_io_by_function(fpioa_function_t function); + +/** + * @brief Set IO slew rate control + * + * @param[in] number The IO number + * @param[in] sl_value Enable slew rate. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_sl(int number, uint8_t sl_enable); + +/** + * @brief Set IO schmitt trigger + * + * @param[in] number The IO number + * @param[in] st_enable Enable schmitt trigger. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_st(int number, uint8_t st_enable); + +/** + * @brief Set IO output invert enable + * + * @param[in] number The IO number + * @param[in] inv_enable Enable output invert. 0: disable 1:enable + * + * @return result + * - 0 Success + * - Other Fail + */ +int fpioa_set_oe_inv(int number, uint8_t inv_enable); + +#ifdef __cplusplus +} +#endif + +#endif /* _DRIVER_FPIOA_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c index 616348bf6..4e1836180 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c @@ -128,8 +128,6 @@ void k210_clockconfig(void) { /* PLL0 selected */ g_cpu_clock = k210_get_pll0clk() / 2; - - syslog(LOG_NOTICE, "g_cpu clock = %d sel %#x\r\n", g_cpu_clock, clksel0); } else { @@ -142,12 +140,18 @@ void k210_clockconfig(void) void k210_sysctl_init(void) { -// sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); -// sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL); -// sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL); + sysctl_pll_set_freq(SYSCTL_PLL0, 800000000UL); + sysctl_pll_set_freq(SYSCTL_PLL1, 400000000UL); + sysctl_pll_set_freq(SYSCTL_PLL2, 45158400UL); + sysctl_clock_set_threshold(SYSCTL_THRESHOLD_APB1, 2); -// sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); -// sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); -// sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK0, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK1, SYSCTL_POWER_V18); + sysctl_set_power_mode(SYSCTL_POWER_BANK2, SYSCTL_POWER_V18); + + // for IO-27/28 + sysctl_set_power_mode(SYSCTL_POWER_BANK4, SYSCTL_POWER_V33); + // for IO-20~23 + sysctl_set_power_mode(SYSCTL_POWER_BANK3, SYSCTL_POWER_V33); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c index 267011ec3..0adcee8db 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.c @@ -47,55 +47,21 @@ int k210_fpioa_get_io_by_function(uint8_t function) { int index = 0; uint32_t RegValue = 0x0000; - uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; + uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE; for (index = 0; index < K210_IO_NUMBER; index++) { - RegValue = getreg32(&fpioa[index]); + RegValue = getreg32(&fpioa_base[index]); if ((RegValue & 0xFF) == function) return index; } return -1; } -int fpioa_set_io_pull(int number, fpioa_pull_t pull) -{ - /* Check parameters */ - if (number < 0 || number >= K210_IO_NUMBER || pull >= FPIOA_PULL_MAX) - return -1; - - /* read register */ - uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; - fpioa_io_config_t cfg = *(fpioa_io_config_t *)(&fpioa[number]); - uint32_t ioflags = 0x0000; - - switch (pull) - { - case FPIOA_PULL_NONE: - cfg.pu = 0; - cfg.pd = 0; - break; - case FPIOA_PULL_DOWN: - cfg.pu = 0; - cfg.pd = 1; - break; - case FPIOA_PULL_UP: - cfg.pu = 1; - cfg.pd = 0; - break; - default: - break; - } - - /* write register */ - ioflags = *(uint32_t*)(&cfg); - putreg32(ioflags, &fpioa[number]); - return 0; -} void k210_fpioa_config(uint32_t io, uint32_t ioflags) { - uint32_t *fpioa = (uint32_t *)K210_FPIOA_BASE; + uint32_t *fpioa_base = (uint32_t *)K210_FPIOA_BASE; DEBUGASSERT(io < K210_IO_NUMBER); - putreg32(ioflags, &fpioa[io]); + putreg32(ioflags, &fpioa_base[io]); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h index cc122c3b8..6c4a472ea 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_fpioa.h @@ -22,7 +22,7 @@ * @file k210_fpioa.h * @brief nuttx source code * https://github.com/apache/incubator-nuttx.git -* @version 10.3.0 +* @version 10.3.0 * @author AIIT XUOS Lab * @date 2022-03-23 */ @@ -35,6 +35,7 @@ ****************************************************************************/ #include +#include "fpioa.h" /**************************************************************************** * Pre-processor Definitions @@ -44,48 +45,263 @@ #define K210_GPIOHS_MAX_PINNO 32 #define K210_GPIO_MAX_PINNO 8 -#define K210_IO_FUNC_UARTHS_RX 18 /* UART High speed Receiver */ -#define K210_IO_FUNC_UARTHS_TX 19 /* UART High speed Transmitter */ -#define K210_IO_FUNC_GPIOHS0 24 /* GPIO High speed 0 */ -#define K210_IO_FUNC_GPIOHS1 25 /* GPIO High speed 1 */ -#define K210_IO_FUNC_GPIOHS2 26 /* GPIO High speed 2 */ -#define K210_IO_FUNC_GPIOHS3 27 /* GPIO High speed 3 */ -#define K210_IO_FUNC_GPIOHS4 28 /* GPIO High speed 4 */ -#define K210_IO_FUNC_GPIOHS5 29 /* GPIO High speed 5 */ -#define K210_IO_FUNC_GPIOHS6 30 /* GPIO High speed 6 */ -#define K210_IO_FUNC_GPIOHS7 31 /* GPIO High speed 7 */ -#define K210_IO_FUNC_GPIOHS8 32 /* GPIO High speed 8 */ -#define K210_IO_FUNC_GPIOHS9 33 /* GPIO High speed 9 */ -#define K210_IO_FUNC_GPIOHS10 34 /* GPIO High speed 10 */ -#define K210_IO_FUNC_GPIOHS11 35 /* GPIO High speed 11 */ -#define K210_IO_FUNC_GPIOHS12 36 /* GPIO High speed 12 */ -#define K210_IO_FUNC_GPIOHS13 37 /* GPIO High speed 13 */ -#define K210_IO_FUNC_GPIOHS14 38 /* GPIO High speed 14 */ -#define K210_IO_FUNC_GPIOHS15 39 /* GPIO High speed 15 */ -#define K210_IO_FUNC_GPIOHS16 40 /* GPIO High speed 16 */ -#define K210_IO_FUNC_GPIOHS17 41 /* GPIO High speed 17 */ -#define K210_IO_FUNC_GPIOHS18 42 /* GPIO High speed 18 */ -#define K210_IO_FUNC_GPIOHS19 43 /* GPIO High speed 19 */ -#define K210_IO_FUNC_GPIOHS20 44 /* GPIO High speed 20 */ -#define K210_IO_FUNC_GPIOHS21 45 /* GPIO High speed 21 */ -#define K210_IO_FUNC_GPIOHS22 46 /* GPIO High speed 22 */ -#define K210_IO_FUNC_GPIOHS23 47 /* GPIO High speed 23 */ -#define K210_IO_FUNC_GPIOHS24 48 /* GPIO High speed 24 */ -#define K210_IO_FUNC_GPIOHS25 49 /* GPIO High speed 25 */ -#define K210_IO_FUNC_GPIOHS26 50 /* GPIO High speed 26 */ -#define K210_IO_FUNC_GPIOHS27 51 /* GPIO High speed 27 */ -#define K210_IO_FUNC_GPIOHS28 52 /* GPIO High speed 28 */ -#define K210_IO_FUNC_GPIOHS29 53 /* GPIO High speed 29 */ -#define K210_IO_FUNC_GPIOHS30 54 /* GPIO High speed 30 */ -#define K210_IO_FUNC_GPIOHS31 55 /* GPIO High speed 31 */ -#define K210_IO_FUNC_GPIO0 56 /* GPIO pin 0 */ -#define K210_IO_FUNC_GPIO1 57 /* GPIO pin 1 */ -#define K210_IO_FUNC_GPIO2 58 /* GPIO pin 2 */ -#define K210_IO_FUNC_GPIO3 59 /* GPIO pin 3 */ -#define K210_IO_FUNC_GPIO4 60 /* GPIO pin 4 */ -#define K210_IO_FUNC_GPIO5 61 /* GPIO pin 5 */ -#define K210_IO_FUNC_GPIO6 62 /* GPIO pin 6 */ -#define K210_IO_FUNC_GPIO7 63 /* GPIO pin 7 */ +#define K210_IO_FUNC_JTAG_TCLK 0 /* JTAG Test Clock */ +#define K210_IO_FUNC_JTAG_TDI 1 /* JTAG Test Data In */ +#define K210_IO_FUNC_JTAG_TMS 2 /* JTAG Test Mode Select */ +#define K210_IO_FUNC_JTAG_TDO 3 /* JTAG Test Data Out */ +#define K210_IO_FUNC_SPI0_D0 4 /* SPI0 Data 0 */ +#define K210_IO_FUNC_SPI0_D1 5 /* SPI0 Data 1 */ +#define K210_IO_FUNC_SPI0_D2 6 /* SPI0 Data 2 */ +#define K210_IO_FUNC_SPI0_D3 7 /* SPI0 Data 3 */ +#define K210_IO_FUNC_SPI0_D4 8 /* SPI0 Data 4 */ +#define K210_IO_FUNC_SPI0_D5 9 /* SPI0 Data 5 */ +#define K210_IO_FUNC_SPI0_D6 10 /* SPI0 Data 6 */ +#define K210_IO_FUNC_SPI0_D7 11 /* SPI0 Data 7 */ +#define K210_IO_FUNC_SPI0_SS0 12 /* SPI0 Chip Select 0 */ +#define K210_IO_FUNC_SPI0_SS1 13 /* SPI0 Chip Select 1 */ +#define K210_IO_FUNC_SPI0_SS2 14 /* SPI0 Chip Select 2 */ +#define K210_IO_FUNC_SPI0_SS3 15 /* SPI0 Chip Select 3 */ +#define K210_IO_FUNC_SPI0_ARB 16 /* SPI0 Arbitration */ +#define K210_IO_FUNC_SPI0_SCLK 17 /* SPI0 Serial Clock */ +#define K210_IO_FUNC_UARTHS_RX 18 /* UART High speed Receiver */ +#define K210_IO_FUNC_UARTHS_TX 19 /* UART High speed Transmitter */ +#define K210_IO_FUNC_RESV6 20 /* Reserved function */ +#define K210_IO_FUNC_RESV7 21 /* Reserved function */ +#define K210_IO_FUNC_CLK_SPI1 22 /* Clock SPI1 */ +#define K210_IO_FUNC_CLK_I2C1 23 /* Clock I2C1 */ +#define K210_IO_FUNC_GPIOHS0 24 /* GPIO High speed 0 */ +#define K210_IO_FUNC_GPIOHS1 25 /* GPIO High speed 1 */ +#define K210_IO_FUNC_GPIOHS2 26 /* GPIO High speed 2 */ +#define K210_IO_FUNC_GPIOHS3 27 /* GPIO High speed 3 */ +#define K210_IO_FUNC_GPIOHS4 28 /* GPIO High speed 4 */ +#define K210_IO_FUNC_GPIOHS5 29 /* GPIO High speed 5 */ +#define K210_IO_FUNC_GPIOHS6 30 /* GPIO High speed 6 */ +#define K210_IO_FUNC_GPIOHS7 31 /* GPIO High speed 7 */ +#define K210_IO_FUNC_GPIOHS8 32 /* GPIO High speed 8 */ +#define K210_IO_FUNC_GPIOHS9 33 /* GPIO High speed 9 */ +#define K210_IO_FUNC_GPIOHS10 34 /* GPIO High speed 10 */ +#define K210_IO_FUNC_GPIOHS11 35 /* GPIO High speed 11 */ +#define K210_IO_FUNC_GPIOHS12 36 /* GPIO High speed 12 */ +#define K210_IO_FUNC_GPIOHS13 37 /* GPIO High speed 13 */ +#define K210_IO_FUNC_GPIOHS14 38 /* GPIO High speed 14 */ +#define K210_IO_FUNC_GPIOHS15 39 /* GPIO High speed 15 */ +#define K210_IO_FUNC_GPIOHS16 40 /* GPIO High speed 16 */ +#define K210_IO_FUNC_GPIOHS17 41 /* GPIO High speed 17 */ +#define K210_IO_FUNC_GPIOHS18 42 /* GPIO High speed 18 */ +#define K210_IO_FUNC_GPIOHS19 43 /* GPIO High speed 19 */ +#define K210_IO_FUNC_GPIOHS20 44 /* GPIO High speed 20 */ +#define K210_IO_FUNC_GPIOHS21 45 /* GPIO High speed 21 */ +#define K210_IO_FUNC_GPIOHS22 46 /* GPIO High speed 22 */ +#define K210_IO_FUNC_GPIOHS23 47 /* GPIO High speed 23 */ +#define K210_IO_FUNC_GPIOHS24 48 /* GPIO High speed 24 */ +#define K210_IO_FUNC_GPIOHS25 49 /* GPIO High speed 25 */ +#define K210_IO_FUNC_GPIOHS26 50 /* GPIO High speed 26 */ +#define K210_IO_FUNC_GPIOHS27 51 /* GPIO High speed 27 */ +#define K210_IO_FUNC_GPIOHS28 52 /* GPIO High speed 28 */ +#define K210_IO_FUNC_GPIOHS29 53 /* GPIO High speed 29 */ +#define K210_IO_FUNC_GPIOHS30 54 /* GPIO High speed 30 */ +#define K210_IO_FUNC_GPIOHS31 55 /* GPIO High speed 31 */ +#define K210_IO_FUNC_GPIO0 56 /* GPIO pin 0 */ +#define K210_IO_FUNC_GPIO1 57 /* GPIO pin 1 */ +#define K210_IO_FUNC_GPIO2 58 /* GPIO pin 2 */ +#define K210_IO_FUNC_GPIO3 59 /* GPIO pin 3 */ +#define K210_IO_FUNC_GPIO4 60 /* GPIO pin 4 */ +#define K210_IO_FUNC_GPIO5 61 /* GPIO pin 5 */ +#define K210_IO_FUNC_GPIO6 62 /* GPIO pin 6 */ +#define K210_IO_FUNC_GPIO7 63 /* GPIO pin 7 */ +#define K210_IO_FUNC_UART1_RX 64 /* UART1 Receiver */ +#define K210_IO_FUNC_UART1_TX 65 /* UART1 Transmitter */ +#define K210_IO_FUNC_UART2_RX 66 /* UART2 Receiver */ +#define K210_IO_FUNC_UART2_TX 67 /* UART2 Transmitter */ +#define K210_IO_FUNC_UART3_RX 68 /* UART3 Receiver */ +#define K210_IO_FUNC_UART3_TX 69 /* UART3 Transmitter */ +#define K210_IO_FUNC_SPI1_D0 70 /* SPI1 Data 0 */ +#define K210_IO_FUNC_SPI1_D1 71 /* SPI1 Data 1 */ +#define K210_IO_FUNC_SPI1_D2 72 /* SPI1 Data 2 */ +#define K210_IO_FUNC_SPI1_D3 73 /* SPI1 Data 3 */ +#define K210_IO_FUNC_SPI1_D4 74 /* SPI1 Data 4 */ +#define K210_IO_FUNC_SPI1_D5 75 /* SPI1 Data 5 */ +#define K210_IO_FUNC_SPI1_D6 76 /* SPI1 Data 6 */ +#define K210_IO_FUNC_SPI1_D7 77 /* SPI1 Data 7 */ +#define K210_IO_FUNC_SPI1_SS0 78 /* SPI1 Chip Select 0 */ +#define K210_IO_FUNC_SPI1_SS1 79 /* SPI1 Chip Select 1 */ +#define K210_IO_FUNC_SPI1_SS2 80 /* SPI1 Chip Select 2 */ +#define K210_IO_FUNC_SPI1_SS3 81 /* SPI1 Chip Select 3 */ +#define K210_IO_FUNC_SPI1_ARB 82 /* SPI1 Arbitration */ +#define K210_IO_FUNC_SPI1_SCLK 83 /* SPI1 Serial Clock */ +#define K210_IO_FUNC_SPI_SLAVE_D0 84 /* SPI Slave Data 0 */ +#define K210_IO_FUNC_SPI_SLAVE_SS 85 /* SPI Slave Select */ +#define K210_IO_FUNC_SPI_SLAVE_SCLK 86 /* SPI Slave Serial Clock */ +#define K210_IO_FUNC_I2S0_MCLK 87 /* I2S0 Master Clock */ +#define K210_IO_FUNC_I2S0_SCLK 88 /* I2S0 Serial Clock(BCLK) */ +#define K210_IO_FUNC_I2S0_WS 89 /* I2S0 Word Select(LRCLK) */ +#define K210_IO_FUNC_I2S0_IN_D0 90 /* I2S0 Serial Data Input 0 */ +#define K210_IO_FUNC_I2S0_IN_D1 91 /* I2S0 Serial Data Input 1 */ +#define K210_IO_FUNC_I2S0_IN_D2 92 /* I2S0 Serial Data Input 2 */ +#define K210_IO_FUNC_I2S0_IN_D3 93 /* I2S0 Serial Data Input 3 */ +#define K210_IO_FUNC_I2S0_OUT_D0 94 /* I2S0 Serial Data Output 0 */ +#define K210_IO_FUNC_I2S0_OUT_D1 95 /* I2S0 Serial Data Output 1 */ +#define K210_IO_FUNC_I2S0_OUT_D2 96 /* I2S0 Serial Data Output 2 */ +#define K210_IO_FUNC_I2S0_OUT_D3 97 /* I2S0 Serial Data Output 3 */ +#define K210_IO_FUNC_I2S1_MCLK 98 /* I2S1 Master Clock */ +#define K210_IO_FUNC_I2S1_SCLK 99 /* I2S1 Serial Clock(BCLK) */ +#define K210_IO_FUNC_I2S1_WS 100 /* I2S1 Word Select(LRCLK) */ +#define K210_IO_FUNC_I2S1_IN_D0 101 /* I2S1 Serial Data Input 0 */ +#define K210_IO_FUNC_I2S1_IN_D1 102 /* I2S1 Serial Data Input 1 */ +#define K210_IO_FUNC_I2S1_IN_D2 103 /* I2S1 Serial Data Input 2 */ +#define K210_IO_FUNC_I2S1_IN_D3 104 /* I2S1 Serial Data Input 3 */ +#define K210_IO_FUNC_I2S1_OUT_D0 105 /* I2S1 Serial Data Output 0 */ +#define K210_IO_FUNC_I2S1_OUT_D1 106 /* I2S1 Serial Data Output 1 */ +#define K210_IO_FUNC_I2S1_OUT_D2 107 /* I2S1 Serial Data Output 2 */ +#define K210_IO_FUNC_I2S1_OUT_D3 108 /* I2S1 Serial Data Output 3 */ +#define K210_IO_FUNC_I2S2_MCLK 109 /* I2S2 Master Clock */ +#define K210_IO_FUNC_I2S2_SCLK 110 /* I2S2 Serial Clock(BCLK) */ +#define K210_IO_FUNC_I2S2_WS 111 /* I2S2 Word Select(LRCLK) */ +#define K210_IO_FUNC_I2S2_IN_D0 112 /* I2S2 Serial Data Input 0 */ +#define K210_IO_FUNC_I2S2_IN_D1 113 /* I2S2 Serial Data Input 1 */ +#define K210_IO_FUNC_I2S2_IN_D2 114 /* I2S2 Serial Data Input 2 */ +#define K210_IO_FUNC_I2S2_IN_D3 115 /* I2S2 Serial Data Input 3 */ +#define K210_IO_FUNC_I2S2_OUT_D0 116 /* I2S2 Serial Data Output 0 */ +#define K210_IO_FUNC_I2S2_OUT_D1 117 /* I2S2 Serial Data Output 1 */ +#define K210_IO_FUNC_I2S2_OUT_D2 118 /* I2S2 Serial Data Output 2 */ +#define K210_IO_FUNC_I2S2_OUT_D3 119 /* I2S2 Serial Data Output 3 */ +#define K210_IO_FUNC_RESV0 120 /* Reserved function */ +#define K210_IO_FUNC_RESV1 121 /* Reserved function */ +#define K210_IO_FUNC_RESV2 122 /* Reserved function */ +#define K210_IO_FUNC_RESV3 123 /* Reserved function */ +#define K210_IO_FUNC_RESV4 124 /* Reserved function */ +#define K210_IO_FUNC_RESV5 125 /* Reserved function */ +#define K210_IO_FUNC_I2C0_SCLK 126 /* I2C0 Serial Clock */ +#define K210_IO_FUNC_I2C0_SDA 127 /* I2C0 Serial Data */ +#define K210_IO_FUNC_I2C1_SCLK 128 /* I2C1 Serial Clock */ +#define K210_IO_FUNC_I2C1_SDA 129 /* I2C1 Serial Data */ +#define K210_IO_FUNC_I2C2_SCLK 130 /* I2C2 Serial Clock */ +#define K210_IO_FUNC_I2C2_SDA 131 /* I2C2 Serial Data */ +#define K210_IO_FUNC_CMOS_XCLK 132 /* DVP System Clock */ +#define K210_IO_FUNC_CMOS_RST 133 /* DVP System Reset */ +#define K210_IO_FUNC_CMOS_PWDN 134 /* DVP Power Down Mode */ +#define K210_IO_FUNC_CMOS_VSYNC 135 /* DVP Vertical Sync */ +#define K210_IO_FUNC_CMOS_HREF 136 /* DVP Horizontal Reference output */ +#define K210_IO_FUNC_CMOS_PCLK 137 /* Pixel Clock */ +#define K210_IO_FUNC_CMOS_D0 138 /* Data Bit 0 */ +#define K210_IO_FUNC_CMOS_D1 139 /* Data Bit 1 */ +#define K210_IO_FUNC_CMOS_D2 140 /* Data Bit 2 */ +#define K210_IO_FUNC_CMOS_D3 141 /* Data Bit 3 */ +#define K210_IO_FUNC_CMOS_D4 142 /* Data Bit 4 */ +#define K210_IO_FUNC_CMOS_D5 143 /* Data Bit 5 */ +#define K210_IO_FUNC_CMOS_D6 144 /* Data Bit 6 */ +#define K210_IO_FUNC_CMOS_D7 145 /* Data Bit 7 */ +#define K210_IO_FUNC_SCCB_SCLK 146 /* SCCB Serial Clock */ +#define K210_IO_FUNC_SCCB_SDA 147 /* SCCB Serial Data */ +#define K210_IO_FUNC_UART1_CTS 148 /* UART1 Clear To Send */ +#define K210_IO_FUNC_UART1_DSR 149 /* UART1 Data Set Ready */ +#define K210_IO_FUNC_UART1_DCD 150 /* UART1 Data Carrier Detect */ +#define K210_IO_FUNC_UART1_RI 151 /* UART1 Ring Indicator */ +#define K210_IO_FUNC_UART1_SIR_IN 152 /* UART1 Serial Infrared Input */ +#define K210_IO_FUNC_UART1_DTR 153 /* UART1 Data Terminal Ready */ +#define K210_IO_FUNC_UART1_RTS 154 /* UART1 Request To Send */ +#define K210_IO_FUNC_UART1_OUT2 155 /* UART1 User-designated Output 2 */ +#define K210_IO_FUNC_UART1_OUT1 156 /* UART1 User-designated Output 1 */ +#define K210_IO_FUNC_UART1_SIR_OUT 157 /* UART1 Serial Infrared Output */ +#define K210_IO_FUNC_UART1_BAUD 158 /* UART1 Transmit Clock Output */ +#define K210_IO_FUNC_UART1_RE 159 /* UART1 Receiver Output Enable */ +#define K210_IO_FUNC_UART1_DE 160 /* UART1 Driver Output Enable */ +#define K210_IO_FUNC_UART1_RS485_EN 161 /* UART1 RS485 Enable */ +#define K210_IO_FUNC_UART2_CTS 162 /* UART2 Clear To Send */ +#define K210_IO_FUNC_UART2_DSR 163 /* UART2 Data Set Ready */ +#define K210_IO_FUNC_UART2_DCD 164 /* UART2 Data Carrier Detect */ +#define K210_IO_FUNC_UART2_RI 165 /* UART2 Ring Indicator */ +#define K210_IO_FUNC_UART2_SIR_IN 166 /* UART2 Serial Infrared Input */ +#define K210_IO_FUNC_UART2_DTR 167 /* UART2 Data Terminal Ready */ +#define K210_IO_FUNC_UART2_RTS 168 /* UART2 Request To Send */ +#define K210_IO_FUNC_UART2_OUT2 169 /* UART2 User-designated Output 2 */ +#define K210_IO_FUNC_UART2_OUT1 170 /* UART2 User-designated Output 1 */ +#define K210_IO_FUNC_UART2_SIR_OUT 171 /* UART2 Serial Infrared Output */ +#define K210_IO_FUNC_UART2_BAUD 172 /* UART2 Transmit Clock Output */ +#define K210_IO_FUNC_UART2_RE 173 /* UART2 Receiver Output Enable */ +#define K210_IO_FUNC_UART2_DE 174 /* UART2 Driver Output Enable */ +#define K210_IO_FUNC_UART2_RS485_EN 175 /* UART2 RS485 Enable */ +#define K210_IO_FUNC_UART3_CTS 176 /* UART3 Clear To Send */ +#define K210_IO_FUNC_UART3_DSR 177 /* UART3 Data Set Ready */ +#define K210_IO_FUNC_UART3_DCD 178 /* UART3 Data Carrier Detect */ +#define K210_IO_FUNC_UART3_RI 179 /* UART3 Ring Indicator */ +#define K210_IO_FUNC_UART3_SIR_IN 180 /* UART3 Serial Infrared Input */ +#define K210_IO_FUNC_UART3_DTR 181 /* UART3 Data Terminal Ready */ +#define K210_IO_FUNC_UART3_RTS 182 /* UART3 Request To Send */ +#define K210_IO_FUNC_UART3_OUT2 183 /* UART3 User-designated Output 2 */ +#define K210_IO_FUNC_UART3_OUT1 184 /* UART3 User-designated Output 1 */ +#define K210_IO_FUNC_UART3_SIR_OUT 185 /* UART3 Serial Infrared Output */ +#define K210_IO_FUNC_UART3_BAUD 186 /* UART3 Transmit Clock Output */ +#define K210_IO_FUNC_UART3_RE 187 /* UART3 Receiver Output Enable */ +#define K210_IO_FUNC_UART3_DE 188 /* UART3 Driver Output Enable */ +#define K210_IO_FUNC_UART3_RS485_EN 189 /* UART3 RS485 Enable */ +#define K210_IO_FUNC_TIMER0_TOGGLE1 190 /* TIMER0 Toggle Output 1 */ +#define K210_IO_FUNC_TIMER0_TOGGLE2 191 /* TIMER0 Toggle Output 2 */ +#define K210_IO_FUNC_TIMER0_TOGGLE3 192 /* TIMER0 Toggle Output 3 */ +#define K210_IO_FUNC_TIMER0_TOGGLE4 193 /* TIMER0 Toggle Output 4 */ +#define K210_IO_FUNC_TIMER1_TOGGLE1 194 /* TIMER1 Toggle Output 1 */ +#define K210_IO_FUNC_TIMER1_TOGGLE2 195 /* TIMER1 Toggle Output 2 */ +#define K210_IO_FUNC_TIMER1_TOGGLE3 196 /* TIMER1 Toggle Output 3 */ +#define K210_IO_FUNC_TIMER1_TOGGLE4 197 /* TIMER1 Toggle Output 4 */ +#define K210_IO_FUNC_TIMER2_TOGGLE1 198 /* TIMER2 Toggle Output 1 */ +#define K210_IO_FUNC_TIMER2_TOGGLE2 199 /* TIMER2 Toggle Output 2 */ +#define K210_IO_FUNC_TIMER2_TOGGLE3 200 /* TIMER2 Toggle Output 3 */ +#define K210_IO_FUNC_TIMER2_TOGGLE4 201 /* TIMER2 Toggle Output 4 */ +#define K210_IO_FUNC_CLK_SPI2 202 /* Clock SPI2 */ +#define K210_IO_FUNC_CLK_I2C2 203 /* Clock I2C2 */ +#define K210_IO_FUNC_INTERNAL0 204 /* Internal function signal 0 */ +#define K210_IO_FUNC_INTERNAL1 205 /* Internal function signal 1 */ +#define K210_IO_FUNC_INTERNAL2 206 /* Internal function signal 2 */ +#define K210_IO_FUNC_INTERNAL3 207 /* Internal function signal 3 */ +#define K210_IO_FUNC_INTERNAL4 208 /* Internal function signal 4 */ +#define K210_IO_FUNC_INTERNAL5 209 /* Internal function signal 5 */ +#define K210_IO_FUNC_INTERNAL6 210 /* Internal function signal 6 */ +#define K210_IO_FUNC_INTERNAL7 211 /* Internal function signal 7 */ +#define K210_IO_FUNC_INTERNAL8 212 /* Internal function signal 8 */ +#define K210_IO_FUNC_INTERNAL9 213 /* Internal function signal 9 */ +#define K210_IO_FUNC_INTERNAL10 214 /* Internal function signal 10 */ +#define K210_IO_FUNC_INTERNAL11 215 /* Internal function signal 11 */ +#define K210_IO_FUNC_INTERNAL12 216 /* Internal function signal 12 */ +#define K210_IO_FUNC_INTERNAL13 217 /* Internal function signal 13 */ +#define K210_IO_FUNC_INTERNAL14 218 /* Internal function signal 14 */ +#define K210_IO_FUNC_INTERNAL15 219 /* Internal function signal 15 */ +#define K210_IO_FUNC_INTERNAL16 220 /* Internal function signal 16 */ +#define K210_IO_FUNC_INTERNAL17 221 /* Internal function signal 17 */ +#define K210_IO_FUNC_CONSTANT 222 /* Constant function */ +#define K210_IO_FUNC_INTERNAL18 223 /* Internal function signal 18 */ +#define K210_IO_FUNC_DEBUG0 224 /* Debug function 0 */ +#define K210_IO_FUNC_DEBUG1 225 /* Debug function 1 */ +#define K210_IO_FUNC_DEBUG2 226 /* Debug function 2 */ +#define K210_IO_FUNC_DEBUG3 227 /* Debug function 3 */ +#define K210_IO_FUNC_DEBUG4 228 /* Debug function 4 */ +#define K210_IO_FUNC_DEBUG5 229 /* Debug function 5 */ +#define K210_IO_FUNC_DEBUG6 230 /* Debug function 6 */ +#define K210_IO_FUNC_DEBUG7 231 /* Debug function 7 */ +#define K210_IO_FUNC_DEBUG8 232 /* Debug function 8 */ +#define K210_IO_FUNC_DEBUG9 233 /* Debug function 9 */ +#define K210_IO_FUNC_DEBUG10 234 /* Debug function 10 */ +#define K210_IO_FUNC_DEBUG11 235 /* Debug function 11 */ +#define K210_IO_FUNC_DEBUG12 236 /* Debug function 12 */ +#define K210_IO_FUNC_DEBUG13 237 /* Debug function 13 */ +#define K210_IO_FUNC_DEBUG14 238 /* Debug function 14 */ +#define K210_IO_FUNC_DEBUG15 239 /* Debug function 15 */ +#define K210_IO_FUNC_DEBUG16 240 /* Debug function 16 */ +#define K210_IO_FUNC_DEBUG17 241 /* Debug function 17 */ +#define K210_IO_FUNC_DEBUG18 242 /* Debug function 18 */ +#define K210_IO_FUNC_DEBUG19 243 /* Debug function 19 */ +#define K210_IO_FUNC_DEBUG20 244 /* Debug function 20 */ +#define K210_IO_FUNC_DEBUG21 245 /* Debug function 21 */ +#define K210_IO_FUNC_DEBUG22 246 /* Debug function 22 */ +#define K210_IO_FUNC_DEBUG23 247 /* Debug function 23 */ +#define K210_IO_FUNC_DEBUG24 248 /* Debug function 24 */ +#define K210_IO_FUNC_DEBUG25 249 /* Debug function 25 */ +#define K210_IO_FUNC_DEBUG26 250 /* Debug function 26 */ +#define K210_IO_FUNC_DEBUG27 251 /* Debug function 27 */ +#define K210_IO_FUNC_DEBUG28 252 /* Debug function 28 */ +#define K210_IO_FUNC_DEBUG29 253 /* Debug function 29 */ +#define K210_IO_FUNC_DEBUG30 254 /* Debug function 30 */ +#define K210_IO_FUNC_DEBUG31 255 /* Debug function 31 */ +#define K210_IO_FUNC_MAX 256 /* Function numbers */ #define K210_IO_DS(x) (x << 8) /* Driving Selector */ @@ -102,34 +318,6 @@ #define K210_IOFLAG_GPIOHS (K210_IO_DS(0xf) | K210_IO_OUTPUT_ENABLE | \ K210_IO_INPUT_ENABLE | K210_IO_ST) -typedef struct _fpioa_io_config -{ - uint32_t ch_sel : 8; /* Channel select from 256 input. */ - uint32_t ds : 4; /* Driving selector. */ - uint32_t oe_en : 1; /* Static output enable, will AND with OE_INV. */ - uint32_t oe_inv : 1; /* Invert output enable. */ - uint32_t do_sel : 1; /* Data output select: 0 for DO, 1 for OE. */ - uint32_t do_inv : 1; /* Invert the result of data output select (DO_SEL). */ - uint32_t pu : 1; /* Pull up enable. 0 for nothing, 1 for pull up. */ - uint32_t pd : 1; /* Pull down enable. 0 for nothing, 1 for pull down. */ - uint32_t resv0 : 1; /* Reserved bits. */ - uint32_t sl : 1; /* Slew rate control enable. */ - uint32_t ie_en : 1; /* Static input enable, will AND with IE_INV. */ - uint32_t ie_inv : 1; /* Invert input enable. */ - uint32_t di_inv : 1; /* Invert Data input. */ - uint32_t st : 1; /* Schmitt trigger. */ - uint32_t resv1 : 7; /* Reserved bits. */ - uint32_t pad_di : 1; /* Read current IO's data input. */ -} __attribute__((packed, aligned(4))) fpioa_io_config_t; - -typedef enum _fpioa_pull -{ - FPIOA_PULL_NONE, /* No Pull */ - FPIOA_PULL_DOWN, /* Pull Down */ - FPIOA_PULL_UP, /* Pull Up */ - FPIOA_PULL_MAX /* Count of pull settings */ -} fpioa_pull_t; - /**************************************************************************** * Public Functions Prototypes diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c new file mode 100644 index 000000000..c5371ebf2 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c @@ -0,0 +1,733 @@ +/**************************************************************************** + * arch/risc-v/src/k210/k210_serial.c + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include "riscv_internal.h" +#include "k210_config.h" +#include "chip.h" +#include "k210.h" +#include "k210_uart_16550.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* If we are not using the serial driver for the console, then we still must + * provide some minimal implementation of up_putc. + */ + +#ifdef USE_SERIALDRIVER + +/* Which UART with be tty0/console and which tty1? The console will always + * be ttyS0. If there is no console then will use the lowest numbered UART. + */ + +#ifdef HAVE_SERIAL_CONSOLE +# if defined(CONFIG_UART0_SERIAL_CONSOLE) +# define CONSOLE_DEV g_uart0port /* UART0 is console */ +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# error "I'm confused... Do we have a serial console or not?" +# endif +#else +# undef CONSOLE_DEV /* No console */ +# undef CONFIG_UART0_SERIAL_CONSOLE +# if defined(CONFIG_K210_UART0) +# define TTYS0_DEV g_uart0port /* UART0 is ttyS0 */ +# undef TTYS1_DEV /* No ttyS1 */ +# define SERIAL_CONSOLE 1 +# else +# undef TTYS0_DEV +# undef TTYS1_DEV +# endif +#endif + +/* Common initialization logic will not not know that the all of the UARTs + * have been disabled. So, as a result, we may still have to provide + * stub implementations of riscv_earlyserialinit(), riscv_serialinit(), and + * up_putc(). + */ + +#ifdef HAVE_UART_DEVICE + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +struct up_dev_s +{ + uintptr_t uartbase; /* Base address of UART registers */ + uint32_t baud; /* Configured baud */ + uint8_t irq; /* IRQ associated with this UART */ + uint8_t im; /* Interrupt mask state */ +}; + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/* Low-level helpers */ + +static uint32_t up_serialin(struct up_dev_s *priv, int offset); +static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value); +static void up_restoreuartint(struct up_dev_s *priv, uint8_t im); +static void up_disableuartint(struct up_dev_s *priv, uint8_t *im); + +/* Serial driver methods */ + +static int up_setup(struct uart_dev_s *dev); +static void up_shutdown(struct uart_dev_s *dev); +static int up_attach(struct uart_dev_s *dev); +static void up_detach(struct uart_dev_s *dev); +static int up_interrupt(int irq, void *context, void *arg); +static int up_ioctl(struct file *filep, int cmd, unsigned long arg); +static int up_receive(struct uart_dev_s *dev, unsigned int *status); +static void up_rxint(struct uart_dev_s *dev, bool enable); +static bool up_rxavailable(struct uart_dev_s *dev); +static void up_send(struct uart_dev_s *dev, int ch); +static void up_txint(struct uart_dev_s *dev, bool enable); +static bool up_txready(struct uart_dev_s *dev); +static bool up_txempty(struct uart_dev_s *dev); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const struct uart_ops_s g_uart_ops = +{ + .setup = up_setup, + .shutdown = up_shutdown, + .attach = up_attach, + .detach = up_detach, + .ioctl = up_ioctl, + .receive = up_receive, + .rxint = up_rxint, + .rxavailable = up_rxavailable, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = NULL, +#endif + .send = up_send, + .txint = up_txint, + .txready = up_txready, + .txempty = up_txempty, +}; + +/* I/O buffers */ + +#ifdef CONFIG_K210_UART0 +static char g_uart0rxbuffer[CONFIG_UART0_RXBUFSIZE]; +static char g_uart0txbuffer[CONFIG_UART0_TXBUFSIZE]; +static uint32_t g_rxdata; +#endif + +#ifdef CONFIG_K210_UART0 +static struct up_dev_s g_uart0priv = +{ + .uartbase = K210_UART0_BASE, + .baud = CONFIG_UART0_BAUD, + .irq = K210_IRQ_UART0, +}; + +static uart_dev_t g_uart0port = +{ +#if SERIAL_CONSOLE == 1 + .isconsole = 1, +#endif + .recv = + { + .size = CONFIG_UART0_RXBUFSIZE, + .buffer = g_uart0rxbuffer, + }, + .xmit = + { + .size = CONFIG_UART0_TXBUFSIZE, + .buffer = g_uart0txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart0priv, +}; +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_serialin + ****************************************************************************/ + +static uint32_t up_serialin(struct up_dev_s *priv, int offset) +{ + return getreg32(priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_serialout + ****************************************************************************/ + +static void up_serialout(struct up_dev_s *priv, int offset, uint32_t value) +{ + putreg32(value, priv->uartbase + offset); +} + +/**************************************************************************** + * Name: up_restoreuartint + ****************************************************************************/ + +static void up_restoreuartint(struct up_dev_s *priv, uint8_t im) +{ + irqstate_t flags = enter_critical_section(); + + priv->im = im; + up_serialout(priv, UART_IE_OFFSET, im); + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_disableuartint + ****************************************************************************/ + +static void up_disableuartint(struct up_dev_s *priv, uint8_t *im) +{ + irqstate_t flags = enter_critical_section(); + + /* Return the current interrupt mask value */ + + if (im) + { + *im = priv->im; + } + + /* Disable all interrupts */ + + priv->im = 0; + up_serialout(priv, UART_IE_OFFSET, 0); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_setup + * + * Description: + * Configure the UART baud, bits, parity, etc. This method is called the + * first time that the serial port is opened. + * + ****************************************************************************/ + +static int up_setup(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + +#if 0 /* TODO: Setup divisor */ +#endif + + /* Enable RX */ + + up_serialout(priv, UART_RXCTL_OFFSET, 1); + + /* Set TX watermark level to 1 and enable TX */ + + up_serialout(priv, UART_TXCTL_OFFSET, 1 << 16 | 1); + + return OK; +} + +/**************************************************************************** + * Name: up_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void up_shutdown(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: up_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method is + * called when the serial port is opened. Normally, this is just after the + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled by the attach method (unless the + * hardware supports multiple levels of interrupt enabling). The RX and TX + * interrupts are not enabled until the txint() and rxint() are called. + * + ****************************************************************************/ + +static int up_attach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + int ret; + + /* Initialize interrupt generation on the peripheral */ + + up_serialout(priv, UART_IE_OFFSET, UART_IE_TXWM | UART_IE_RXWM); + + ret = irq_attach(priv->irq, up_interrupt, dev); + + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } + + return ret; +} + +/**************************************************************************** + * Name: up_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. The exception + * is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void up_detach(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Disable interrupts */ + + up_disable_irq(priv->irq); + + /* Detach from the interrupt */ + + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: up_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 uart_dev_s structure in order to call these functions. + * + ****************************************************************************/ + +static int up_interrupt(int irq, void *context, void *arg) +{ + struct uart_dev_s *dev = (struct uart_dev_s *)arg; + struct up_dev_s *priv; + uint32_t status; + int passes; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (struct up_dev_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Retrieve interrupt pending status */ + + status = up_serialin(priv, UART_IP_OFFSET); + + if (status == 0) + { + break; + } + + if (status & UART_IP_RXWM) + { + /* Process incoming bytes */ + + uart_recvchars(dev); + } + + if (status & UART_IP_TXWM) + { + /* Process outgoing bytes */ + + uart_xmitchars(dev); + } + } + + return OK; +} + +/**************************************************************************** + * Name: up_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int up_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +/**************************************************************************** + * Name: up_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int up_receive(struct uart_dev_s *dev, unsigned int *status) +{ + /* Return status information */ + + if (status) + { + *status = 0; /* We are not yet tracking serial errors */ + } + + /* Return cached data */ + + return g_rxdata; +} + +/**************************************************************************** + * Name: up_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void up_rxint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags = enter_critical_section(); + + if (enable) + { +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= UART_IE_RXWM; +#endif + } + else + { + priv->im &= ~UART_IE_RXWM; + } + + up_serialout(priv, UART_IE_OFFSET, priv->im); + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_rxavailable + * + * Description: + * Return true if the receive register is not empty + * + ****************************************************************************/ + +static bool up_rxavailable(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return true is data is available in the receive data buffer */ + + uint32_t rxdata = up_serialin(priv, UART_RXDATA_OFFSET); + + /* NOTE: In K210, actual data is also retrieved */ + + g_rxdata = rxdata & 0xff; + + return (rxdata & UART_RX_EMPTY) == 0; +} + +/**************************************************************************** + * Name: up_send + * + * Description: + * This method will send one byte on the UART. + * + ****************************************************************************/ + +static void up_send(struct uart_dev_s *dev, int ch) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + up_serialout(priv, UART_TXDATA_OFFSET, (uint32_t)ch); +} + +/**************************************************************************** + * Name: up_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void up_txint(struct uart_dev_s *dev, bool enable) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + irqstate_t flags; + + flags = enter_critical_section(); + if (enable) + { + /* Enable the TX interrupt */ + +#ifndef CONFIG_SUPPRESS_SERIAL_INTS + priv->im |= UART_IE_TXWM; + up_serialout(priv, UART_IE_OFFSET, priv->im); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); +#endif + } + else + { + /* Disable the TX interrupt */ + + priv->im &= ~UART_IE_TXWM; + up_serialout(priv, UART_IE_OFFSET, priv->im); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: up_txready + * + * Description: + * Return true if the tranmsit data register is not full + * + ****************************************************************************/ + +static bool up_txready(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the TX FIFO is not full */ + + return (up_serialin(priv, UART_TXDATA_OFFSET) & UART_TX_FULL) == 0; +} + +/**************************************************************************** + * Name: up_txempty + * + * Description: + * Return true if the tranmsit data register is empty + * + ****************************************************************************/ + +static bool up_txempty(struct uart_dev_s *dev) +{ + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + + /* Return TRUE if the TX wartermak is pending */ + + return (up_serialin(priv, UART_IP_OFFSET) & UART_IP_TXWM) == 1; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +#ifdef USE_EARLYSERIALINIT + +/**************************************************************************** + * Name: riscv_earlyserialinit + * + * Description: + * Performs the low level UART initialization early in debug so that the + * serial console will be available during bootup. This must be called + * before riscv_serialinit. NOTE: This function depends on GPIO pin + * configuration performed in up_consoleinit() and main clock + * initialization performed in up_clkinitialize(). + * + ****************************************************************************/ + +void riscv_earlyserialinit(void) +{ + /* Disable interrupts from all UARTS. The console is enabled in + * k210_consoleinit(). + */ + + up_disableuartint(TTYS0_DEV.priv, NULL); +#ifdef TTYS1_DEV + up_disableuartint(TTYS1_DEV.priv, NULL); +#endif + + /* Configuration whichever one is the console */ + +#ifdef HAVE_SERIAL_CONSOLE + CONSOLE_DEV.isconsole = true; + up_setup(&CONSOLE_DEV); +#endif +} +#endif + +/**************************************************************************** + * Name: riscv_serialinit + * + * Description: + * Register serial console and serial ports. This assumes + * that riscv_earlyserialinit was called previously. + * + ****************************************************************************/ + +void riscv_serialinit(void) +{ + /* Register the console */ + +#ifdef HAVE_SERIAL_CONSOLE + uart_register("/dev/console", &CONSOLE_DEV); +#endif + + /* Register all UARTs */ + uart_register("/dev/ttyS0", &TTYS0_DEV); + +#ifdef CONFIG_K210_16550_UART + /* Register UART1-UART3 */ + k210_uart_16550_register(); +#endif +} + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + struct up_dev_s *priv = (struct up_dev_s *)CONSOLE_DEV.priv; + uint8_t imr; + + up_disableuartint(priv, &imr); + + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); + up_restoreuartint(priv, imr); +#endif + return ch; +} + +/**************************************************************************** + * Name: riscv_earlyserialinit, riscv_serialinit, and up_putc + * + * Description: + * stubs that may be needed. These stubs would be used if all UARTs are + * disabled. In that case, the logic in common/up_initialize() is not + * smart enough to know that there are not UARTs and will still expect + * these interfaces to be provided. + * + ****************************************************************************/ + +#else /* HAVE_UART_DEVICE */ +void riscv_earlyserialinit(void) +{ +} + +void riscv_serialinit(void) +{ +} + +int up_putc(int ch) +{ + return ch; +} + +#endif /* HAVE_UART_DEVICE */ +#else /* USE_SERIALDRIVER */ + +/**************************************************************************** + * Name: up_putc + * + * Description: + * Provide priority, low-level access to support OS debug writes + * + ****************************************************************************/ + +int up_putc(int ch) +{ +#ifdef HAVE_SERIAL_CONSOLE + /* Check for LF */ + + if (ch == '\n') + { + /* Add CR */ + + riscv_lowputc('\r'); + } + + riscv_lowputc(ch); +#endif + return ch; +} + +#endif /* USE_SERIALDRIVER */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c new file mode 100644 index 000000000..0f9267408 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c @@ -0,0 +1,1002 @@ +/**************************************************************************** + * drivers/serial/uart_16550.c + * + * 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. + * + ****************************************************************************/ + +/* Serial driver for 16550 UART */ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include "k210_uart_16550.h" + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#ifdef CONFIG_K210_16550_UART + + +/**************************************************************************** + * Pre-processor definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * 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); +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool k210_16550_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); +#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); +#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); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +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, +#ifdef CONFIG_SERIAL_IFLOWCONTROL + .rxflowcontrol = k210_16550_rxflowcontrol, +#endif +#ifdef CONFIG_SERIAL_TXDMA + .dmasend = k210_16550_dmasend, +#endif +#ifdef CONFIG_SERIAL_RXDMA + .dmareceive = k210_16550_dmareceive, + .dmarxfree = k210_16550_dmarxfree, +#endif +#ifdef CONFIG_SERIAL_TXDMA + .dmatxavail = k210_16550_dmatxavail, +#endif + .send = k210_16550_send, + .txint = k210_16550_txint, + .txready = k210_16550_txready, + .txempty = k210_16550_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]; +#endif +#ifdef CONFIG_K210_16550_UART2 +static char g_uart2rxbuffer[CONFIG_K210_16550_UART2_RXBUFSIZE]; +static char g_uart2txbuffer[CONFIG_K210_16550_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]; +#endif + +/* This describes the state of the 16550 uart1 port. */ + +#ifdef CONFIG_K210_16550_UART1 +static struct k210_16550_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, +#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) + .flow = true, +#endif +#endif +}; + +static uart_dev_t g_uart1port = +{ + .recv = + { + .size = CONFIG_K210_16550_UART1_RXBUFSIZE, + .buffer = g_uart1rxbuffer, + }, + .xmit = + { + .size = CONFIG_K210_16550_UART1_TXBUFSIZE, + .buffer = g_uart1txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart1priv, +}; +#endif + +/* This describes the state of the 16550 uart2 port. */ + +#ifdef CONFIG_K210_16550_UART2 +static struct k210_16550_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, +#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) + .flow = true, +#endif +#endif +}; + +static uart_dev_t g_uart2port = +{ + .recv = + { + .size = CONFIG_K210_16550_UART2_RXBUFSIZE, + .buffer = g_uart2rxbuffer, + }, + .xmit = + { + .size = CONFIG_K210_16550_UART2_TXBUFSIZE, + .buffer = g_uart2txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart2priv, +}; + +#endif + +/* This describes the state of the 16550 uart1 port. */ + +#ifdef CONFIG_K210_16550_UART3 +static struct k210_16550_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, +#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) + .flow = true, +#endif +#endif +}; + +static uart_dev_t g_uart3port = +{ + .recv = + { + .size = CONFIG_K210_16550_UART3_RXBUFSIZE, + .buffer = g_uart3rxbuffer, + }, + .xmit = + { + .size = CONFIG_K210_16550_UART3_TXBUFSIZE, + .buffer = g_uart3txbuffer, + }, + .ops = &g_uart_ops, + .priv = &g_uart3priv, +}; + +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_16550_serialin + ****************************************************************************/ + +static inline uart_datawidth_t k210_16550_serialin(FAR struct k210_16550_s *priv, + int offset) +{ +#ifdef CONFIG_SERIAL_UART_ARCH_MMIO + return *((FAR volatile uart_datawidth_t *)(priv->uartbase + offset)); +#else + return uart_getreg(priv->uartbase, offset); +#endif +} + +/**************************************************************************** + * Name: k210_16550_serialout + ****************************************************************************/ + +static inline void k210_16550_serialout(FAR struct k210_16550_s *priv, int offset, + uart_datawidth_t value) +{ +#ifdef CONFIG_SERIAL_UART_ARCH_MMIO + *((FAR volatile uart_datawidth_t *)(priv->uartbase + offset)) = value; +#else + uart_putreg(priv->uartbase, offset, value); +#endif +} + +/**************************************************************************** + * Name: k210_16550_disableuartint + ****************************************************************************/ + +static inline void k210_16550_disableuartint(FAR struct k210_16550_s *priv, + FAR uart_datawidth_t *ier) +{ + if (ier) + { + *ier = priv->ier & UART_IER_ALLIE; + } + + priv->ier &= ~UART_IER_ALLIE; + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: k210_16550_restoreuartint + ****************************************************************************/ + +static inline void k210_16550_restoreuartint(FAR struct k210_16550_s *priv, + uint32_t ier) +{ + priv->ier |= ier & UART_IER_ALLIE; + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: k210_16550_enablebreaks + ****************************************************************************/ + +static inline void k210_16550_enablebreaks(FAR struct k210_16550_s *priv, + bool enable) +{ + uint32_t lcr = k210_16550_serialin(priv, UART_LCR_OFFSET); + + if (enable) + { + lcr |= UART_LCR_BRK; + } + else + { + lcr &= ~UART_LCR_BRK; + } + + k210_16550_serialout(priv, UART_LCR_OFFSET, lcr); +} + +/**************************************************************************** + * Name: k210_16550_divisor + * + * Description: + * Select a divider to produce the BAUD from the UART_CLK. + * + * BAUD = UART_CLK / (16 * DL), or + * DIV = UART_CLK / BAUD / 16 + * + * Ignoring the fractional divider for now. + * + ****************************************************************************/ + +#ifndef CONFIG_K210_16550_SUPRESS_CONFIG +static inline uint32_t k210_16550_divisor(FAR struct k210_16550_s *priv) +{ + return (priv->uartclk / (uint32_t)priv->baud); +// return (priv->uartclk + (priv->baud << 3)) / (priv->baud << 4); +} +#endif + +/**************************************************************************** + * Name: k210_16550_setup + * + * Description: + * Configure the UART baud, bits, parity, fifos, etc. This + * method is called the first time that the serial port is + * opened. + * + ****************************************************************************/ + +static int k210_16550_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; + uint16_t div; + uint8_t dlh, dll, dlf; + uint32_t lcr; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + uint32_t mcr; +#endif + + /* Clear fifos */ + + k210_16550_serialout(priv, UART_FCR_OFFSET, + (UART_FCR_RXRST | UART_FCR_TXRST)); + + /* Set trigger */ + + k210_16550_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); + + /* Set up the LCR */ + + lcr = 0; + switch (priv->bits) + { + case 5 : + lcr |= UART_LCR_WLS_5BIT; + break; + + case 6 : + lcr |= UART_LCR_WLS_6BIT; + break; + + case 7 : + lcr |= UART_LCR_WLS_7BIT; + break; + + default: + case 8 : + lcr |= UART_LCR_WLS_8BIT; + break; + } + + if (priv->stopbits2) + { + lcr |= UART_LCR_STB; + } + + if (priv->parity == 1) + { + lcr |= UART_LCR_PEN; + } + else if (priv->parity == 2) + { + lcr |= (UART_LCR_PEN | UART_LCR_EPS); + } + + /* Enter DLAB=1 */ + + k210_16550_serialout(priv, UART_LCR_OFFSET, (lcr | UART_LCR_DLAB)); + + /* Set the BAUD divisor */ + + div = k210_16550_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); + + /* Clear DLAB */ + + k210_16550_serialout(priv, UART_LCR_OFFSET, lcr); + + /* Configure the FIFOs */ + + k210_16550_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); + if (priv->flow) + { + mcr |= UART_MCR_AFCE; + } + else + { + mcr &= ~UART_MCR_AFCE; + } + + mcr |= UART_MCR_RTS; + + k210_16550_serialout(priv, UART_MCR_OFFSET, mcr); + + k210_16550_serialout(priv, UART_SRT_OFFSET, 0x0); + +#endif /* defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) */ + +#endif + return OK; +} + +/**************************************************************************** + * Name: k210_16550_shutdown + * + * Description: + * Disable the UART. This method is called when the serial + * port is closed + * + ****************************************************************************/ + +static void k210_16550_shutdown(struct uart_dev_s *dev) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + k210_16550_disableuartint(priv, NULL); +} + +/**************************************************************************** + * Name: k210_16550_attach + * + * Description: + * Configure the UART to operation in interrupt driven mode. This method + * is called when the serial port is opened. Normally, this is just after + * the setup() method is called, however, the serial console may operate in + * a non-interrupt driven mode during the boot phase. + * + * RX and TX interrupts are not enabled when by the attach method (unless + * the hardware supports multiple levels of interrupt enabling). The RX + * and TX interrupts are not enabled until the txint() and rxint() methods + * are called. + * + ****************************************************************************/ + +static int k210_16550_attach(struct uart_dev_s *dev) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + int ret; + + /* Attach and enable the IRQ */ + + ret = irq_attach(priv->irq, k210_16550_interrupt, dev); +#ifndef CONFIG_ARCH_NOINTC + if (ret == OK) + { + /* Enable the interrupt (RX and TX interrupts are still disabled + * in the UART + */ + + up_enable_irq(priv->irq); + } +#endif + + return ret; +} + +/**************************************************************************** + * Name: k210_16550_detach + * + * Description: + * Detach UART interrupts. This method is called when the serial port is + * closed normally just before the shutdown method is called. + * The exception is the serial console which is never shutdown. + * + ****************************************************************************/ + +static void k210_16550_detach(FAR struct uart_dev_s *dev) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + + up_disable_irq(priv->irq); + irq_detach(priv->irq); +} + +/**************************************************************************** + * Name: k210_16550_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. + * + ****************************************************************************/ + +static int k210_16550_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; + uint32_t status; + int passes; + uint8_t v_int_status; + + DEBUGASSERT(dev != NULL && dev->priv != NULL); + priv = (FAR struct k210_16550_s *)dev->priv; + + /* Loop until there are no characters to be transferred or, + * until we have been looping for a long time. + */ + + for (passes = 0; passes < 256; passes++) + { + /* Get the current UART status and check for loop + * termination conditions + */ + + status = k210_16550_serialin(priv, UART_IIR_OFFSET); + + if (status == 0) + { + break; + } + v_int_status = status & 0xF; + + /* The UART_IIR_INTSTATUS bit should be zero if there are pending + * interrupts + */ + if(v_int_status == UART_INTERRUPT_SEND) + { + uart_xmitchars(dev); + break; + } + + else if (v_int_status == UART_INTERRUPT_RECEIVE || v_int_status == UART_INTERRUPT_CHARACTER_TIMEOUT) + { + uart_recvchars(dev); + break; + } + } + + return OK; +} + +/**************************************************************************** + * Name: k210_16550_ioctl + * + * Description: + * All ioctl calls will be routed through this method + * + ****************************************************************************/ + +static int k210_16550_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; + int ret; + +#ifdef CONFIG_SERIAL_UART_ARCH_IOCTL + ret = uart_ioctl(filep, cmd, arg); + + if (ret != -ENOTTY) + { + return ret; + } + +#else + ret = OK; +#endif + + switch (cmd) + { +#ifdef CONFIG_SERIAL_TIOCSERGSTRUCT + case TIOCSERGSTRUCT: + { + FAR struct k210_16550_s *user = (FAR struct k210_16550_s *)arg; + if (!user) + { + ret = -EINVAL; + } + else + { + memcpy(user, dev, sizeof(struct k210_16550_s)); + } + } + break; +#endif + + case TIOCSBRK: /* BSD compatibility: Turn break on, unconditionally */ + { + irqstate_t flags = enter_critical_section(); + k210_16550_enablebreaks(priv, true); + leave_critical_section(flags); + } + break; + + case TIOCCBRK: /* BSD compatibility: Turn break off, unconditionally */ + { + irqstate_t flags; + flags = enter_critical_section(); + k210_16550_enablebreaks(priv, false); + leave_critical_section(flags); + } + break; + +#if defined(CONFIG_SERIAL_TERMIOS) && !defined(CONFIG_K210_16550_SUPRESS_CONFIG) + case TCGETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + irqstate_t flags; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + flags = enter_critical_section(); + + cfsetispeed(termiosp, priv->baud); + termiosp->c_cflag = ((priv->parity != 0) ? PARENB : 0) | + ((priv->parity == 1) ? PARODD : 0); + termiosp->c_cflag |= (priv->stopbits2) ? CSTOPB : 0; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + termiosp->c_cflag |= priv->flow ? CRTSCTS : 0; +#endif + + switch (priv->bits) + { + case 5: + termiosp->c_cflag |= CS5; + break; + + case 6: + termiosp->c_cflag |= CS6; + break; + + case 7: + termiosp->c_cflag |= CS7; + break; + + case 8: + default: + termiosp->c_cflag |= CS8; + break; + } + + leave_critical_section(flags); + } + break; + + case TCSETS: + { + FAR struct termios *termiosp = (FAR struct termios *)arg; + irqstate_t flags; + + if (!termiosp) + { + ret = -EINVAL; + break; + } + + flags = enter_critical_section(); + + switch (termiosp->c_cflag & CSIZE) + { + case CS5: + priv->bits = 5; + break; + + case CS6: + priv->bits = 6; + break; + + case CS7: + priv->bits = 7; + break; + + case CS8: + default: + priv->bits = 8; + break; + } + + if ((termiosp->c_cflag & PARENB) != 0) + { + priv->parity = (termiosp->c_cflag & PARODD) ? 1 : 2; + } + else + { + priv->parity = 0; + } + + priv->baud = cfgetispeed(termiosp); + priv->stopbits2 = (termiosp->c_cflag & CSTOPB) != 0; +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + priv->flow = (termiosp->c_cflag & CRTSCTS) != 0; +#endif + + k210_16550_setup(dev); + leave_critical_section(flags); + } + break; +#endif + + default: + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: k210_16550_receive + * + * Description: + * Called (usually) from the interrupt level to receive one + * character from the UART. Error bits associated with the + * receipt are provided in the return 'status'. + * + ****************************************************************************/ + +static int k210_16550_receive(struct uart_dev_s *dev, unsigned int *status) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + uint32_t rbr = 0; + *status = k210_16550_serialin(priv, UART_LSR_OFFSET); + rbr = k210_16550_serialin(priv, UART_RBR_OFFSET); + return rbr; +} + +/**************************************************************************** + * Name: k210_16550_rxint + * + * Description: + * Call to enable or disable RX interrupts + * + ****************************************************************************/ + +static void k210_16550_rxint(struct uart_dev_s *dev, bool enable) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_s *)dev->priv; + + if (enable) + { + priv->ier |= UART_IER_ERBFI; + } + else + { + priv->ier &= ~UART_IER_ERBFI; + } + + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); +} + +/**************************************************************************** + * Name: k210_16550_rxavailable + * + * Description: + * Return true if the receive fifo is not empty + * + ****************************************************************************/ + +static bool k210_16550_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); +} + +/**************************************************************************** + * Name: k210_16550_dma* + * + * Description: + * Stubbed out DMA-related methods + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_IFLOWCONTROL +static bool k210_16550_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; + + if (priv->flow) + { + /* Disable Rx interrupt to prevent more data being from + * peripheral if the RX buffer is near full. When hardware + * RTS is enabled, this will prevent more data from coming + * in. Otherwise, enable Rx interrupt to make sure that more + * input is received. + */ + + k210_16550_rxint(dev, !upper); + return true; + } +#endif + + return false; +} +#endif + +/**************************************************************************** + * Name: k210_16550_dma* + * + * Description: + * Stub functions used when serial DMA is enabled. + * + ****************************************************************************/ + +#ifdef CONFIG_SERIAL_TXDMA +static void k210_16550_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_16550_dmarxfree(FAR struct uart_dev_s *dev) +{ +} +#endif + +#ifdef CONFIG_SERIAL_TXDMA +static void k210_16550_dmatxavail(FAR struct uart_dev_s *dev) +{ +} +#endif + +/**************************************************************************** + * Name: k210_16550_send + * + * Description: + * This method will send one byte on the UART + * + ****************************************************************************/ + +static void k210_16550_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); +} + +/**************************************************************************** + * Name: k210_16550_txint + * + * Description: + * Call to enable or disable TX interrupts + * + ****************************************************************************/ + +static void k210_16550_txint(struct uart_dev_s *dev, bool enable) +{ + FAR struct k210_16550_s *priv = (FAR struct k210_16550_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); + + /* Fake a TX interrupt here by just calling uart_xmitchars() with + * interrupts disabled (note this may recurse). + */ + + uart_xmitchars(dev); + } + else + { + priv->ier &= ~UART_IER_ETBEI; + k210_16550_serialout(priv, UART_IER_OFFSET, priv->ier); + } + + leave_critical_section(flags); +} + +/**************************************************************************** + * Name: k210_16550_txready + * + * Description: + * Return true if the tranmsit fifo is not full + * + ****************************************************************************/ + +static bool k210_16550_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)); +} + +/**************************************************************************** + * Name: k210_16550_txempty + * + * Description: + * Return true if the transmit fifo is empty + * + ****************************************************************************/ + +static bool k210_16550_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); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: k210_uart_16550_register + * + * Description: + * Register serial console and serial ports. This assumes that + * up_earlyserialinit was called previously. + * + ****************************************************************************/ + +void k210_uart_16550_register(void) +{ +#if defined(CONFIG_K210_16550_UART1) + k210_16550_setup(&g_uart1port); + uart_register("/dev/ttyS1", &g_uart1port); +#endif +#if defined(CONFIG_K210_16550_UART2) + k210_16550_setup(&g_uart2port); + uart_register("/dev/ttyS2", &g_uart2port); +#endif +#if defined(CONFIG_K210_16550_UART3) + k210_16550_setup(&g_uart3port); + uart_register("/dev/ttyS3", &g_uart3port); +#endif +} + +#endif /* CONFIG_K210_16550_UART */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h new file mode 100644 index 000000000..0cc6c2bd2 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h @@ -0,0 +1,340 @@ +/**************************************************************************** + * include/nuttx/serial/uart_16550.h + * Serial driver for 16550 UART + * + * 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. + * + ****************************************************************************/ + +#ifndef __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H +#define __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_K210_16550_UART + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* CONFIGURATION ************************************************************/ + +/* Are any UARTs enabled? */ + +#undef HAVE_UART +#if defined(CONFIG_K210_16550_UART1) || defined(CONFIG_K210_16550_UART2) || defined(CONFIG_K210_16550_UART3) +# define HAVE_UART 1 +#endif + +/* We need to be told the address increment between registers and the + * register bit width. + */ + +#ifndef CONFIG_K210_16550_REGINCR +# error "CONFIG_K210_16550_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" +#endif + +#ifndef CONFIG_K210_16550_REGWIDTH +# error "CONFIG_K210_16550_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" +#endif + +#ifndef CONFIG_K210_16550_ADDRWIDTH +# error "CONFIG_K210_16550_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" +#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 +# endif +# ifndef CONFIG_K210_16550_UART1_CLOCK +# error "CONFIG_K210_16550_UART1_CLOCK not provided" +# undef CONFIG_K210_16550_UART1 +# endif +# ifndef CONFIG_K210_16550_UART1_IRQ +# error "CONFIG_K210_16550_UART1_IRQ not provided" +# undef CONFIG_K210_16550_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 +# endif +# ifndef CONFIG_K210_16550_UART2_CLOCK +# error "CONFIG_K210_16550_UART2_CLOCK not provided" +# undef CONFIG_K210_16550_UART2 +# endif +# ifndef CONFIG_K210_16550_UART2_IRQ +# error "CONFIG_K210_16550_UART2_IRQ not provided" +# undef CONFIG_K210_16550_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 +# endif +# ifndef CONFIG_K210_16550_UART3_CLOCK +# error "CONFIG_K210_16550_UART3_CLOCK not provided" +# undef CONFIG_K210_16550_UART3 +# endif +# ifndef CONFIG_K210_16550_UART3_IRQ +# error "CONFIG_K210_16550_UART3_IRQ not provided" +# undef CONFIG_K210_16550_UART3 +# endif +#endif + +/* Is there a serial console? There should be at most one defined. + * It could be on any UARTn, n=0,1,2,3 + */ + +/* Register offsets *********************************************************/ + +#define UART_RBR_INCR 0 /* (DLAB =0) Receiver Buffer Register */ +#define UART_THR_INCR 0 /* (DLAB =0) Transmit Holding Register */ +#define UART_DLL_INCR 0 /* (DLAB =1) Divisor Latch LSB */ +#define UART_DLM_INCR 1 /* (DLAB =1) Divisor Latch MSB */ +#define UART_IER_INCR 1 /* (DLAB =0) Interrupt Enable Register */ +#define UART_IIR_INCR 2 /* Interrupt ID Register */ +#define UART_FCR_INCR 2 /* FIFO Control Register */ +#define UART_LCR_INCR 3 /* Line Control Register */ +#define UART_MCR_INCR 4 /* Modem Control Register */ +#define UART_LSR_INCR 5 /* Line Status Register */ +#define UART_MSR_INCR 6 /* Modem Status Register */ +#define UART_SCR_INCR 7 /* Scratch Pad Register */ +#define UART_SRT_INCR 39 /* Receive Fifo Trigger Register*/ +#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) + +/* Register bit definitions *************************************************/ + +/* RBR (DLAB =0) Receiver Buffer Register */ + +#define UART_RBR_MASK (0xff) /* Bits 0-7: Oldest received byte in RX FIFO */ + /* Bits 8-31: Reserved */ + +/* THR (DLAB =0) Transmit Holding Register */ + +#define UART_THR_MASK (0xff) /* Bits 0-7: Adds byte to TX FIFO */ + /* Bits 8-31: Reserved */ + +/* DLL (DLAB =1) Divisor Latch LSB */ + +#define UART_DLL_MASK (0xff) /* Bits 0-7: DLL */ + /* Bits 8-31: Reserved */ + +/* DLM (DLAB =1) Divisor Latch MSB */ + +#define UART_DLM_MASK (0xff) /* Bits 0-7: DLM */ + /* Bits 8-31: Reserved */ + +/* IER (DLAB =0) Interrupt Enable Register */ + +#define UART_IER_ERBFI (1 << 0) /* Bit 0: Enable received data available interrupt */ +#define UART_IER_ETBEI (1 << 1) /* Bit 1: Enable THR empty interrupt */ +#define UART_IER_ELSI (1 << 2) /* Bit 2: Enable receiver line status interrupt */ +#define UART_IER_EDSSI (1 << 3) /* Bit 3: Enable MODEM status interrupt */ + /* Bits 4-7: Reserved */ +#define UART_IER_ALLIE (0x0f) + +/* IIR Interrupt ID Register */ + +#define UART_IIR_INTSTATUS (1 << 0) /* Bit 0: Interrupt status (active low) */ +#define UART_IIR_INTID_SHIFT (1) /* Bits 1-3: Interrupt identification */ +#define UART_IIR_INTID_MASK (7 << UART_IIR_INTID_SHIFT) +# define UART_IIR_INTID_MSI (0 << UART_IIR_INTID_SHIFT) /* Modem Status */ +# define UART_IIR_INTID_THRE (1 << UART_IIR_INTID_SHIFT) /* THR Empty Interrupt */ +# define UART_IIR_INTID_RDA (2 << UART_IIR_INTID_SHIFT) /* Receive Data Available (RDA) */ +# define UART_IIR_INTID_RLS (3 << UART_IIR_INTID_SHIFT) /* Receiver Line Status (RLS) */ +# define UART_IIR_INTID_CTI (6 << UART_IIR_INTID_SHIFT) /* Character Time-out Indicator (CTI) */ + + /* Bits 4-5: Reserved */ +#define UART_IIR_FIFOEN_SHIFT (6) /* Bits 6-7: RCVR FIFO interrupt */ +#define UART_IIR_FIFOEN_MASK (3 << UART_IIR_FIFOEN_SHIFT) + +/* FCR FIFO Control Register */ + +#define UART_FCR_FIFOEN (1 << 0) /* Bit 0: Enable FIFOs */ +#define UART_FCR_RXRST (1 << 1) /* Bit 1: RX FIFO Reset */ +#define UART_FCR_TXRST (1 << 2) /* Bit 2: TX FIFO Reset */ +#define UART_FCR_DMAMODE (1 << 3) /* Bit 3: DMA Mode Select */ + /* Bits 4-5: Reserved */ +#define UART_FCR_RXTRIGGER_SHIFT (6) /* Bits 6-7: RX Trigger Level */ +#define UART_FCR_RXTRIGGER_MASK (3 << UART_FCR_RXTRIGGER_SHIFT) +# define UART_FCR_RXTRIGGER_1 (0 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 0 (1 character) */ +# define UART_FCR_RXTRIGGER_4 (1 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 1 (4 characters) */ +# define UART_FCR_RXTRIGGER_8 (2 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 2 (8 characters) */ +# define UART_FCR_RXTRIGGER_14 (3 << UART_FCR_RXTRIGGER_SHIFT) /* Trigger level 3 (14 characters) */ + +/* LCR Line Control Register */ + +#define UART_LCR_WLS_SHIFT (0) /* Bit 0-1: Word Length Select */ +#define UART_LCR_WLS_MASK (3 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_5BIT (0 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_6BIT (1 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_7BIT (2 << UART_LCR_WLS_SHIFT) +# define UART_LCR_WLS_8BIT (3 << UART_LCR_WLS_SHIFT) +#define UART_LCR_STB (1 << 2) /* Bit 2: Number of Stop Bits */ +#define UART_LCR_PEN (1 << 3) /* Bit 3: Parity Enable */ +#define UART_LCR_EPS (1 << 4) /* Bit 4: Even Parity Select */ +#define UART_LCR_STICKY (1 << 5) /* Bit 5: Stick Parity */ +#define UART_LCR_BRK (1 << 6) /* Bit 6: Break Control */ +#define UART_LCR_DLAB (1 << 7) /* Bit 7: Divisor Latch Access Bit (DLAB) */ + +/* MCR Modem Control Register */ + +#define UART_MCR_DTR (1 << 0) /* Bit 0: DTR Control Source for DTR output */ +#define UART_MCR_RTS (1 << 1) /* Bit 1: Control Source for RTS output */ +#define UART_MCR_OUT1 (1 << 2) /* Bit 2: Auxiliary user-defined output 1 */ +#define UART_MCR_OUT2 (1 << 3) /* Bit 3: Auxiliary user-defined output 2 */ +#define UART_MCR_LPBK (1 << 4) /* Bit 4: Loopback Mode Select */ +#define UART_MCR_AFCE (1 << 5) /* Bit 5: Auto Flow Control Enable */ + /* Bit 6-7: Reserved */ + +/* LSR Line Status Register */ + +#define UART_LSR_DR (1 << 0) /* Bit 0: Data Ready */ +#define UART_LSR_OE (1 << 1) /* Bit 1: Overrun Error */ +#define UART_LSR_PE (1 << 2) /* Bit 2: Parity Error */ +#define UART_LSR_FE (1 << 3) /* Bit 3: Framing Error */ +#define UART_LSR_BI (1 << 4) /* Bit 4: Break Interrupt */ +#define UART_LSR_THRE (1 << 5) /* Bit 5: Transmitter Holding Register Empty */ +#define UART_LSR_TEMT (1 << 6) /* Bit 6: Transmitter Empty */ +#define UART_LSR_RXFE (1 << 7) /* Bit 7: Error in RX FIFO (RXFE) */ + +#define UART_INTERRUPT_SEND 0x02U +#define UART_INTERRUPT_RECEIVE 0x04U +#define UART_INTERRUPT_CHARACTER_TIMEOUT 0x0CU + +/* SCR Scratch Pad Register */ + +#define UART_SCR_MASK (0xff) /* Bits 0-7: SCR data */ + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +#if CONFIG_K210_16550_REGWIDTH == 8 +typedef uint8_t uart_datawidth_t; +#elif CONFIG_K210_16550_REGWIDTH == 16 +typedef uint16_t uart_datawidth_t; +#elif CONFIG_K210_16550_REGWIDTH == 32 +typedef uint32_t uart_datawidth_t; +#endif + +#if CONFIG_K210_16550_ADDRWIDTH == 0 +typedef uintptr_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 8 +typedef uint8_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 16 +typedef uint16_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 32 +typedef uint32_t uart_addrwidth_t; +#elif CONFIG_K210_16550_ADDRWIDTH == 64 +typedef uint64_t uart_addrwidth_t; +#endif + +struct k210_16550_s +{ + uart_addrwidth_t uartbase; /* Base address of UART registers */ +#ifndef CONFIG_K210_16550_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 + 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 */ +#if defined(CONFIG_SERIAL_IFLOWCONTROL) || defined(CONFIG_SERIAL_OFLOWCONTROL) + bool flow; /* flow control (RTS/CTS) enabled */ +#endif +#endif +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Public Functions Definitions + ****************************************************************************/ + +/**************************************************************************** + * Name: uart_getreg(), uart_putreg(), uart_ioctl() + * + * Description: + * These functions must be provided by the processor-specific code in order + * to correctly access 16550 registers + * uart_ioctl() is optional to provide custom IOCTLs + * + ****************************************************************************/ + +#ifndef CONFIG_SERIAL_UART_ARCH_MMIO +uart_datawidth_t uart_getreg(uart_addrwidth_t base, unsigned int offset); +void uart_putreg(uart_addrwidth_t base, + unsigned int offset, + uart_datawidth_t value); +#endif + +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 */ +#endif /* __INCLUDE_NUTTX_SERIAL_UART_16550_H */ From 3fa418120c4b3e8cbd8c3448a508712d49538065 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 28 Sep 2022 09:51:01 +0800 Subject: [PATCH 02/18] support Adapter4G for xidatong-riscv64 on nuttx support mulan on nuttx --- .../xidatong-riscv64/configs/4gnsh/defconfig | 77 +++++ .../nuttx/arch/risc-v/src/k210/encoding.h | 35 +- .../nuttx/arch/risc-v/src/k210/fpioa.c | 35 +- .../nuttx/arch/risc-v/src/k210/fpioa.h | 325 ++---------------- .../arch/risc-v/src/k210/k210_clockconfig.c | 9 + .../arch/risc-v/src/k210/k210_memorymap.h | 9 + .../nuttx/arch/risc-v/src/k210/k210_serial.c | 9 + .../nuttx/arch/risc-v/src/k210/k210_sysctl.c | 35 +- .../nuttx/arch/risc-v/src/k210/k210_sysctl.h | 35 +- .../arch/risc-v/src/k210/k210_systemreset.c | 2 +- .../arch/risc-v/src/k210/k210_uart_16550.c | 38 +- .../arch/risc-v/src/k210/k210_uart_16550.h | 39 +-- 12 files changed, 265 insertions(+), 383 deletions(-) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig new file mode 100644 index 000000000..88480a614 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/4gnsh/defconfig @@ -0,0 +1,77 @@ +# +# 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_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_SUPPORT_CONNECTION_FRAMEWORK=y +CONFIG_CONNECTION_FRAMEWORK_DEBUG=y +CONFIG_CONNECTION_ADAPTER_4G=y +CONFIG_ADAPTER_EC200T=y +CONFIG_ADAPTER_4G_EC200T="ec200t" +CONFIG_ADAPTER_EC200T_DRIVER="/dev/ttyS2" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/encoding.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/encoding.h index 980e36f4c..a9a5e0353 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/encoding.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/encoding.h @@ -1,17 +1,32 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/encoding.h * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 + * 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. - */ + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/** +* @file encoding.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #ifndef RISCV_CSR_ENCODING_H #define RISCV_CSR_ENCODING_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c index 093ae74ec..67a93b161 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.c @@ -1,17 +1,32 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/fpioa.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 + * 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. - */ + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/** +* @file fpioa.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #include #include #include "fpioa.h" diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h index 15e86eaea..5b465556e 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/fpioa.h @@ -1,322 +1,43 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/fpioa.h * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 + * 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. - */ + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + /** - * @file - * @brief Field Programmable GPIO Array (FPIOA) - * - * The FPIOA peripheral supports the following features: - * - * - 48 IO with 256 functions - * - * - Schmitt trigger - * - * - Invert input and output - * - * - Pull up and pull down - * - * - Driving selector - * - * - Static input and output - * - */ +* @file fpioa.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ #ifndef _DRIVER_FPIOA_H #define _DRIVER_FPIOA_H #include -//#include "platform.h" #ifdef __cplusplus extern "C" { #endif -/* clang-format off */ -/* Pad number settings */ #define FPIOA_NUM_IO (48) -/* clang-format on */ -/** - * @brief FPIOA IO functions - * - * @note FPIOA pin function table - * - * | Function | Name | Description | - * |-----------|------------------|-----------------------------------| - * | 0 | JTAG_TCLK | JTAG Test Clock | - * | 1 | JTAG_TDI | JTAG Test Data In | - * | 2 | JTAG_TMS | JTAG Test Mode Select | - * | 3 | JTAG_TDO | JTAG Test Data Out | - * | 4 | SPI0_D0 | SPI0 Data 0 | - * | 5 | SPI0_D1 | SPI0 Data 1 | - * | 6 | SPI0_D2 | SPI0 Data 2 | - * | 7 | SPI0_D3 | SPI0 Data 3 | - * | 8 | SPI0_D4 | SPI0 Data 4 | - * | 9 | SPI0_D5 | SPI0 Data 5 | - * | 10 | SPI0_D6 | SPI0 Data 6 | - * | 11 | SPI0_D7 | SPI0 Data 7 | - * | 12 | SPI0_SS0 | SPI0 Chip Select 0 | - * | 13 | SPI0_SS1 | SPI0 Chip Select 1 | - * | 14 | SPI0_SS2 | SPI0 Chip Select 2 | - * | 15 | SPI0_SS3 | SPI0 Chip Select 3 | - * | 16 | SPI0_ARB | SPI0 Arbitration | - * | 17 | SPI0_SCLK | SPI0 Serial Clock | - * | 18 | UARTHS_RX | UART High speed Receiver | - * | 19 | UARTHS_TX | UART High speed Transmitter | - * | 20 | RESV6 | Reserved function | - * | 21 | RESV7 | Reserved function | - * | 22 | CLK_SPI1 | Clock SPI1 | - * | 23 | CLK_I2C1 | Clock I2C1 | - * | 24 | GPIOHS0 | GPIO High speed 0 | - * | 25 | GPIOHS1 | GPIO High speed 1 | - * | 26 | GPIOHS2 | GPIO High speed 2 | - * | 27 | GPIOHS3 | GPIO High speed 3 | - * | 28 | GPIOHS4 | GPIO High speed 4 | - * | 29 | GPIOHS5 | GPIO High speed 5 | - * | 30 | GPIOHS6 | GPIO High speed 6 | - * | 31 | GPIOHS7 | GPIO High speed 7 | - * | 32 | GPIOHS8 | GPIO High speed 8 | - * | 33 | GPIOHS9 | GPIO High speed 9 | - * | 34 | GPIOHS10 | GPIO High speed 10 | - * | 35 | GPIOHS11 | GPIO High speed 11 | - * | 36 | GPIOHS12 | GPIO High speed 12 | - * | 37 | GPIOHS13 | GPIO High speed 13 | - * | 38 | GPIOHS14 | GPIO High speed 14 | - * | 39 | GPIOHS15 | GPIO High speed 15 | - * | 40 | GPIOHS16 | GPIO High speed 16 | - * | 41 | GPIOHS17 | GPIO High speed 17 | - * | 42 | GPIOHS18 | GPIO High speed 18 | - * | 43 | GPIOHS19 | GPIO High speed 19 | - * | 44 | GPIOHS20 | GPIO High speed 20 | - * | 45 | GPIOHS21 | GPIO High speed 21 | - * | 46 | GPIOHS22 | GPIO High speed 22 | - * | 47 | GPIOHS23 | GPIO High speed 23 | - * | 48 | GPIOHS24 | GPIO High speed 24 | - * | 49 | GPIOHS25 | GPIO High speed 25 | - * | 50 | GPIOHS26 | GPIO High speed 26 | - * | 51 | GPIOHS27 | GPIO High speed 27 | - * | 52 | GPIOHS28 | GPIO High speed 28 | - * | 53 | GPIOHS29 | GPIO High speed 29 | - * | 54 | GPIOHS30 | GPIO High speed 30 | - * | 55 | GPIOHS31 | GPIO High speed 31 | - * | 56 | GPIO0 | GPIO pin 0 | - * | 57 | GPIO1 | GPIO pin 1 | - * | 58 | GPIO2 | GPIO pin 2 | - * | 59 | GPIO3 | GPIO pin 3 | - * | 60 | GPIO4 | GPIO pin 4 | - * | 61 | GPIO5 | GPIO pin 5 | - * | 62 | GPIO6 | GPIO pin 6 | - * | 63 | GPIO7 | GPIO pin 7 | - * | 64 | UART1_RX | UART1 Receiver | - * | 65 | UART1_TX | UART1 Transmitter | - * | 66 | UART2_RX | UART2 Receiver | - * | 67 | UART2_TX | UART2 Transmitter | - * | 68 | UART3_RX | UART3 Receiver | - * | 69 | UART3_TX | UART3 Transmitter | - * | 70 | SPI1_D0 | SPI1 Data 0 | - * | 71 | SPI1_D1 | SPI1 Data 1 | - * | 72 | SPI1_D2 | SPI1 Data 2 | - * | 73 | SPI1_D3 | SPI1 Data 3 | - * | 74 | SPI1_D4 | SPI1 Data 4 | - * | 75 | SPI1_D5 | SPI1 Data 5 | - * | 76 | SPI1_D6 | SPI1 Data 6 | - * | 77 | SPI1_D7 | SPI1 Data 7 | - * | 78 | SPI1_SS0 | SPI1 Chip Select 0 | - * | 79 | SPI1_SS1 | SPI1 Chip Select 1 | - * | 80 | SPI1_SS2 | SPI1 Chip Select 2 | - * | 81 | SPI1_SS3 | SPI1 Chip Select 3 | - * | 82 | SPI1_ARB | SPI1 Arbitration | - * | 83 | SPI1_SCLK | SPI1 Serial Clock | - * | 84 | SPI_SLAVE_D0 | SPI Slave Data 0 | - * | 85 | SPI_SLAVE_SS | SPI Slave Select | - * | 86 | SPI_SLAVE_SCLK | SPI Slave Serial Clock | - * | 87 | I2S0_MCLK | I2S0 Master Clock | - * | 88 | I2S0_SCLK | I2S0 Serial Clock(BCLK) | - * | 89 | I2S0_WS | I2S0 Word Select(LRCLK) | - * | 90 | I2S0_IN_D0 | I2S0 Serial Data Input 0 | - * | 91 | I2S0_IN_D1 | I2S0 Serial Data Input 1 | - * | 92 | I2S0_IN_D2 | I2S0 Serial Data Input 2 | - * | 93 | I2S0_IN_D3 | I2S0 Serial Data Input 3 | - * | 94 | I2S0_OUT_D0 | I2S0 Serial Data Output 0 | - * | 95 | I2S0_OUT_D1 | I2S0 Serial Data Output 1 | - * | 96 | I2S0_OUT_D2 | I2S0 Serial Data Output 2 | - * | 97 | I2S0_OUT_D3 | I2S0 Serial Data Output 3 | - * | 98 | I2S1_MCLK | I2S1 Master Clock | - * | 99 | I2S1_SCLK | I2S1 Serial Clock(BCLK) | - * | 100 | I2S1_WS | I2S1 Word Select(LRCLK) | - * | 101 | I2S1_IN_D0 | I2S1 Serial Data Input 0 | - * | 102 | I2S1_IN_D1 | I2S1 Serial Data Input 1 | - * | 103 | I2S1_IN_D2 | I2S1 Serial Data Input 2 | - * | 104 | I2S1_IN_D3 | I2S1 Serial Data Input 3 | - * | 105 | I2S1_OUT_D0 | I2S1 Serial Data Output 0 | - * | 106 | I2S1_OUT_D1 | I2S1 Serial Data Output 1 | - * | 107 | I2S1_OUT_D2 | I2S1 Serial Data Output 2 | - * | 108 | I2S1_OUT_D3 | I2S1 Serial Data Output 3 | - * | 109 | I2S2_MCLK | I2S2 Master Clock | - * | 110 | I2S2_SCLK | I2S2 Serial Clock(BCLK) | - * | 111 | I2S2_WS | I2S2 Word Select(LRCLK) | - * | 112 | I2S2_IN_D0 | I2S2 Serial Data Input 0 | - * | 113 | I2S2_IN_D1 | I2S2 Serial Data Input 1 | - * | 114 | I2S2_IN_D2 | I2S2 Serial Data Input 2 | - * | 115 | I2S2_IN_D3 | I2S2 Serial Data Input 3 | - * | 116 | I2S2_OUT_D0 | I2S2 Serial Data Output 0 | - * | 117 | I2S2_OUT_D1 | I2S2 Serial Data Output 1 | - * | 118 | I2S2_OUT_D2 | I2S2 Serial Data Output 2 | - * | 119 | I2S2_OUT_D3 | I2S2 Serial Data Output 3 | - * | 120 | RESV0 | Reserved function | - * | 121 | RESV1 | Reserved function | - * | 122 | RESV2 | Reserved function | - * | 123 | RESV3 | Reserved function | - * | 124 | RESV4 | Reserved function | - * | 125 | RESV5 | Reserved function | - * | 126 | I2C0_SCLK | I2C0 Serial Clock | - * | 127 | I2C0_SDA | I2C0 Serial Data | - * | 128 | I2C1_SCLK | I2C1 Serial Clock | - * | 129 | I2C1_SDA | I2C1 Serial Data | - * | 130 | I2C2_SCLK | I2C2 Serial Clock | - * | 131 | I2C2_SDA | I2C2 Serial Data | - * | 132 | CMOS_XCLK | DVP System Clock | - * | 133 | CMOS_RST | DVP System Reset | - * | 134 | CMOS_PWDN | DVP Power Down Mode | - * | 135 | CMOS_VSYNC | DVP Vertical Sync | - * | 136 | CMOS_HREF | DVP Horizontal Reference output | - * | 137 | CMOS_PCLK | Pixel Clock | - * | 138 | CMOS_D0 | Data Bit 0 | - * | 139 | CMOS_D1 | Data Bit 1 | - * | 140 | CMOS_D2 | Data Bit 2 | - * | 141 | CMOS_D3 | Data Bit 3 | - * | 142 | CMOS_D4 | Data Bit 4 | - * | 143 | CMOS_D5 | Data Bit 5 | - * | 144 | CMOS_D6 | Data Bit 6 | - * | 145 | CMOS_D7 | Data Bit 7 | - * | 146 | SCCB_SCLK | SCCB Serial Clock | - * | 147 | SCCB_SDA | SCCB Serial Data | - * | 148 | UART1_CTS | UART1 Clear To Send | - * | 149 | UART1_DSR | UART1 Data Set Ready | - * | 150 | UART1_DCD | UART1 Data Carrier Detect | - * | 151 | UART1_RI | UART1 Ring Indicator | - * | 152 | UART1_SIR_IN | UART1 Serial Infrared Input | - * | 153 | UART1_DTR | UART1 Data Terminal Ready | - * | 154 | UART1_RTS | UART1 Request To Send | - * | 155 | UART1_OUT2 | UART1 User-designated Output 2 | - * | 156 | UART1_OUT1 | UART1 User-designated Output 1 | - * | 157 | UART1_SIR_OUT | UART1 Serial Infrared Output | - * | 158 | UART1_BAUD | UART1 Transmit Clock Output | - * | 159 | UART1_RE | UART1 Receiver Output Enable | - * | 160 | UART1_DE | UART1 Driver Output Enable | - * | 161 | UART1_RS485_EN | UART1 RS485 Enable | - * | 162 | UART2_CTS | UART2 Clear To Send | - * | 163 | UART2_DSR | UART2 Data Set Ready | - * | 164 | UART2_DCD | UART2 Data Carrier Detect | - * | 165 | UART2_RI | UART2 Ring Indicator | - * | 166 | UART2_SIR_IN | UART2 Serial Infrared Input | - * | 167 | UART2_DTR | UART2 Data Terminal Ready | - * | 168 | UART2_RTS | UART2 Request To Send | - * | 169 | UART2_OUT2 | UART2 User-designated Output 2 | - * | 170 | UART2_OUT1 | UART2 User-designated Output 1 | - * | 171 | UART2_SIR_OUT | UART2 Serial Infrared Output | - * | 172 | UART2_BAUD | UART2 Transmit Clock Output | - * | 173 | UART2_RE | UART2 Receiver Output Enable | - * | 174 | UART2_DE | UART2 Driver Output Enable | - * | 175 | UART2_RS485_EN | UART2 RS485 Enable | - * | 176 | UART3_CTS | UART3 Clear To Send | - * | 177 | UART3_DSR | UART3 Data Set Ready | - * | 178 | UART3_DCD | UART3 Data Carrier Detect | - * | 179 | UART3_RI | UART3 Ring Indicator | - * | 180 | UART3_SIR_IN | UART3 Serial Infrared Input | - * | 181 | UART3_DTR | UART3 Data Terminal Ready | - * | 182 | UART3_RTS | UART3 Request To Send | - * | 183 | UART3_OUT2 | UART3 User-designated Output 2 | - * | 184 | UART3_OUT1 | UART3 User-designated Output 1 | - * | 185 | UART3_SIR_OUT | UART3 Serial Infrared Output | - * | 186 | UART3_BAUD | UART3 Transmit Clock Output | - * | 187 | UART3_RE | UART3 Receiver Output Enable | - * | 188 | UART3_DE | UART3 Driver Output Enable | - * | 189 | UART3_RS485_EN | UART3 RS485 Enable | - * | 190 | TIMER0_TOGGLE1 | TIMER0 Toggle Output 1 | - * | 191 | TIMER0_TOGGLE2 | TIMER0 Toggle Output 2 | - * | 192 | TIMER0_TOGGLE3 | TIMER0 Toggle Output 3 | - * | 193 | TIMER0_TOGGLE4 | TIMER0 Toggle Output 4 | - * | 194 | TIMER1_TOGGLE1 | TIMER1 Toggle Output 1 | - * | 195 | TIMER1_TOGGLE2 | TIMER1 Toggle Output 2 | - * | 196 | TIMER1_TOGGLE3 | TIMER1 Toggle Output 3 | - * | 197 | TIMER1_TOGGLE4 | TIMER1 Toggle Output 4 | - * | 198 | TIMER2_TOGGLE1 | TIMER2 Toggle Output 1 | - * | 199 | TIMER2_TOGGLE2 | TIMER2 Toggle Output 2 | - * | 200 | TIMER2_TOGGLE3 | TIMER2 Toggle Output 3 | - * | 201 | TIMER2_TOGGLE4 | TIMER2 Toggle Output 4 | - * | 202 | CLK_SPI2 | Clock SPI2 | - * | 203 | CLK_I2C2 | Clock I2C2 | - * | 204 | INTERNAL0 | Internal function signal 0 | - * | 205 | INTERNAL1 | Internal function signal 1 | - * | 206 | INTERNAL2 | Internal function signal 2 | - * | 207 | INTERNAL3 | Internal function signal 3 | - * | 208 | INTERNAL4 | Internal function signal 4 | - * | 209 | INTERNAL5 | Internal function signal 5 | - * | 210 | INTERNAL6 | Internal function signal 6 | - * | 211 | INTERNAL7 | Internal function signal 7 | - * | 212 | INTERNAL8 | Internal function signal 8 | - * | 213 | INTERNAL9 | Internal function signal 9 | - * | 214 | INTERNAL10 | Internal function signal 10 | - * | 215 | INTERNAL11 | Internal function signal 11 | - * | 216 | INTERNAL12 | Internal function signal 12 | - * | 217 | INTERNAL13 | Internal function signal 13 | - * | 218 | INTERNAL14 | Internal function signal 14 | - * | 219 | INTERNAL15 | Internal function signal 15 | - * | 220 | INTERNAL16 | Internal function signal 16 | - * | 221 | INTERNAL17 | Internal function signal 17 | - * | 222 | CONSTANT | Constant function | - * | 223 | INTERNAL18 | Internal function signal 18 | - * | 224 | DEBUG0 | Debug function 0 | - * | 225 | DEBUG1 | Debug function 1 | - * | 226 | DEBUG2 | Debug function 2 | - * | 227 | DEBUG3 | Debug function 3 | - * | 228 | DEBUG4 | Debug function 4 | - * | 229 | DEBUG5 | Debug function 5 | - * | 230 | DEBUG6 | Debug function 6 | - * | 231 | DEBUG7 | Debug function 7 | - * | 232 | DEBUG8 | Debug function 8 | - * | 233 | DEBUG9 | Debug function 9 | - * | 234 | DEBUG10 | Debug function 10 | - * | 235 | DEBUG11 | Debug function 11 | - * | 236 | DEBUG12 | Debug function 12 | - * | 237 | DEBUG13 | Debug function 13 | - * | 238 | DEBUG14 | Debug function 14 | - * | 239 | DEBUG15 | Debug function 15 | - * | 240 | DEBUG16 | Debug function 16 | - * | 241 | DEBUG17 | Debug function 17 | - * | 242 | DEBUG18 | Debug function 18 | - * | 243 | DEBUG19 | Debug function 19 | - * | 244 | DEBUG20 | Debug function 20 | - * | 245 | DEBUG21 | Debug function 21 | - * | 246 | DEBUG22 | Debug function 22 | - * | 247 | DEBUG23 | Debug function 23 | - * | 248 | DEBUG24 | Debug function 24 | - * | 249 | DEBUG25 | Debug function 25 | - * | 250 | DEBUG26 | Debug function 26 | - * | 251 | DEBUG27 | Debug function 27 | - * | 252 | DEBUG28 | Debug function 28 | - * | 253 | DEBUG29 | Debug function 29 | - * | 254 | DEBUG30 | Debug function 30 | - * | 255 | DEBUG31 | Debug function 31 | - * - * Any IO of FPIOA have 256 functions, it is a IO-function matrix. - * All IO have default reset function, after reset, re-configure - * IO function is required. - */ - -/* clang-format off */ typedef enum _fpioa_function { FUNC_JTAG_TCLK = 0, /*!< JTAG Test Clock */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c index 4e1836180..cf900b832 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_clockconfig.c @@ -18,6 +18,15 @@ * ****************************************************************************/ +/** +* @file k210_clockconfig.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + /**************************************************************************** * Included Files ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h index 11f3b0634..1ef7d0ea5 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_memorymap.h @@ -18,6 +18,15 @@ * ****************************************************************************/ +/** +* @file k210_memorymap.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #ifndef __ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H #define __ARCH_RISCV_SRC_K210_K210_MEMORYMAP_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c index c5371ebf2..d35ba2d02 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_serial.c @@ -18,6 +18,15 @@ * ****************************************************************************/ +/** +* @file k210_serial.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + /**************************************************************************** * Included Files ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c index 509b35c0e..39b5d8e42 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.c @@ -1,17 +1,32 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/k210_sysctl.c * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 + * 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. - */ + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/** +* @file k210_sysctl.c +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #include #include #include diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h index 625a3f3e3..fc4a2bbc6 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_sysctl.h @@ -1,17 +1,32 @@ -/* Copyright 2018 Canaan Inc. +/**************************************************************************** + * arch/risc-v/src/k210/k210_sysctl.h * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at + * 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 + * 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. - */ + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/** +* @file k210_sysctl.h +* @brief nuttx source code +* https://github.com/apache/incubator-nuttx.git +* @version 10.3.0 +* @author AIIT XUOS Lab +* @date 2022-09-28 +*/ + #ifndef _DRIVER_SYSCTL_H #define _DRIVER_SYSCTL_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c index ce7fe7fe1..d98e995ed 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_systemreset.c @@ -12,7 +12,7 @@ /** * @file k210_systemreset.c - * @briefk210_systemreset.c support reboot + * @brief k210 support reboot * @version 1.0 * @author AIIT XUOS Lab * @date 2022.06.27 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c index 0f9267408..c52c7cde9 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.c @@ -1,24 +1,22 @@ -/**************************************************************************** - * drivers/serial/uart_16550.c - * - * 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. - * - ****************************************************************************/ +/* +* 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. +*/ -/* Serial driver for 16550 UART */ +/** + * @file k210_uart_16550.c + * @brief k210 uart1-uart3 support + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.09.28 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h index 0cc6c2bd2..dbf2f4cbf 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_uart_16550.h @@ -1,23 +1,22 @@ -/**************************************************************************** - * include/nuttx/serial/uart_16550.h - * Serial driver for 16550 UART - * - * 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. - * - ****************************************************************************/ +/* +* 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_uart_16550.h + * @brief k210 uart1-uart3 support + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.09.28 + */ #ifndef __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H #define __INCLUDE_NUTTX_SERIAL_UART_K210_16550_H From 32b54cee33cbd2deb99c5913e3e0c4a9d4271189 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 28 Sep 2022 14:32:14 +0800 Subject: [PATCH 03/18] add GPIO_WIFI_EN register and change PrivSerialIoctl --- .../transform_layer/nuttx/transform.c | 20 +++++++++++++++++++ .../xidatong-riscv64/include/board.h | 2 +- .../xidatong-riscv64/src/k210_gpio.c | 8 ++++++-- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/APP_Framework/Framework/transform_layer/nuttx/transform.c b/APP_Framework/Framework/transform_layer/nuttx/transform.c index 878aa0f93..35e3a599d 100644 --- a/APP_Framework/Framework/transform_layer/nuttx/transform.c +++ b/APP_Framework/Framework/transform_layer/nuttx/transform.c @@ -139,10 +139,30 @@ static int PrivSerialIoctl(int fd, int cmd, void *args) { struct SerialDataCfg *serial_cfg = (struct SerialDataCfg *)args; unsigned long serial_baud_rate = (unsigned long)serial_cfg->serial_baud_rate; + struct termios term; + + /* Extended serial port */ if(serial_cfg->is_ext_uart == 1) { return ioctl(fd, OPE_INT, serial_baud_rate); } + + /* Standard serial port,only the baud rate is set */ + else if(serial_cfg->is_ext_uart == 0) + { + if(ioctl(fd, TCGETS, (unsigned long)&term) < 0) + { + return -1; + } + if ((cfsetispeed(&term, serial_baud_rate) < 0) ||(cfsetospeed(&term, serial_baud_rate) < 0)) + { + return -1; + } + if(ioctl(fd, TCSETS, (unsigned long)&term) < 0) + { + return -1; + } + } return 0; } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index 03564ace5..5677e9855 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -57,7 +57,7 @@ /* GPIO pins used by the GPIO Subsystem */ -#define BOARD_NGPIOOUT 3 /* Amount of GPIO Output pins */ +#define BOARD_NGPIOOUT 4 /* Amount of GPIO Output pins */ #define BOARD_NGPIOINT 0 /* Amount of GPIO Input */ /**************************************************************************** diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c index 12c88622b..a54b3714d 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c @@ -51,10 +51,12 @@ #define GPIO_E220_M0 44 #define GPIO_E220_M1 45 #define GPIO_E18_MODE 46 +#define GPIO_WIFI_EN 8 #define FPIOA_E220_M0 1 #define FPIOA_E220_M1 2 #define FPIOA_E18_MODE 3 +#define FPIOA_WIFI_EN 4 /**************************************************************************** * Private Types @@ -94,14 +96,16 @@ static const uint32_t g_gpiooutputs[BOARD_NGPIOOUT] = { GPIO_E220_M0, GPIO_E220_M1, - GPIO_E18_MODE + GPIO_E18_MODE, + GPIO_WIFI_EN }; static const uint32_t g_fpioa[BOARD_NGPIOOUT] = { FPIOA_E220_M0, FPIOA_E220_M1, - FPIOA_E18_MODE + FPIOA_E18_MODE, + FPIOA_WIFI_EN }; static struct k210gpio_dev_s g_gpout[BOARD_NGPIOOUT]; From 9fcd539f1bf1eeaf4ec3a74837408ac746aeff9c Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 10 Oct 2022 09:26:36 +0800 Subject: [PATCH 04/18] add ch376 for xidatong-riscv64 --- .../aiit_board/xidatong-riscv64/src/Makefile | 2 +- .../xidatong-riscv64/src/ch376inc.h | 926 +++++++++++++++++ .../xidatong-riscv64/src/k210_ch376.c | 978 ++++++++++++++++++ .../xidatong-riscv64/src/k210_ch376.h | 118 +++ 4 files changed, 2023 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile index d6fa521c7..3258528d7 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile @@ -20,7 +20,7 @@ include $(TOPDIR)/Make.defs -CSRCS = k210_bringup.c k210_boot.c +CSRCS = k210_bringup.c k210_boot.c k210_ch376.c ifeq ($(CONFIG_BOARDCTL_RESET),y) CSRCS += k210_reset.c diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h new file mode 100644 index 000000000..63d757a73 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h @@ -0,0 +1,926 @@ +/* +* 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 xidatong-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 + +/* ********************************************************************************************************************* */ +/* 常用类型和常量定义 */ + +#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 /* USB单个数据包, 数据块的最大长度, 默认缓冲区的长度 */ + +/* ********************************************************************************************************************* */ +/* 命令代码 */ +/* 部分命令兼容CH375芯片, 但是输入数据或者输出数据的可能局部不同) */ +/* 一个命令操作顺序包含: + 一个命令码(对于串口方式,命令码之前还需要两个同步码), + 若干个输入数据(可以是0个), + 产生中断通知 或者 若干个输出数据(可以是0个), 二选一, 有中断通知则一定没有输出数据, 有输出数据则一定不产生中断 + 仅CMD01_WR_REQ_DATA命令例外, 顺序包含: 一个命令码, 一个输出数据, 若干个输入数据 + 命令码起名规则: CMDxy_NAME + 其中的x和y都是数字, x说明最少输入数据个数(字节数), y说明最少输出数据个数(字节数), y如果是H则说明产生中断通知, + 有些命令能够实现0到多个字节的数据块读写, 数据块本身的字节数未包含在上述x或y之内 */ +/* 本文件默认会同时提供与CH375芯片命令码兼容的命令码格式(即去掉x和y之后), 如果不需要, 那么可以定义_NO_CH375_COMPATIBLE_禁止 */ + +/* ********************************************************************************************************************* */ +/* 主要命令(手册一), 常用 */ + +#define CMD01_GET_IC_VER 0x01 /* 获取芯片及固件版本 */ +/* 输出: 版本号( 位7为0, 位6为1, 位5~位0为版本号 ) */ +/* CH376返回版本号的值为041H即版本号为01H */ + +#define CMD21_SET_BAUDRATE 0x02 /* 串口方式: 设置串口通讯波特率(上电或者复位后的默认波特率为9600bps,由D4/D5/D6引脚选择) */ +/* 输入: 波特率分频系数, 波特率分频常数 */ +/* 输出: 操作状态( CMD_RET_SUCCESS或CMD_RET_ABORT, 其它值说明操作未完成 ) */ + +#define CMD00_ENTER_SLEEP 0x03 /* 进入睡眠状态 */ + +#define CMD00_RESET_ALL 0x05 /* 执行硬件复位 */ + +#define CMD11_CHECK_EXIST 0x06 /* 测试通讯接口和工作状态 */ +/* 输入: 任意数据 */ +/* 输出: 输入数据的按位取反 */ + +#define CMD20_CHK_SUSPEND 0x0B /* 设备方式: 设置检查USB总线挂起状态的方式 */ +/* 输入: 数据10H, 检查方式 */ +/* 00H=不检查USB挂起, 04H=以50mS为间隔检查USB挂起, 05H=以10mS为间隔检查USB挂起 */ + +#define CMD20_SET_SDO_INT 0x0B /* SPI接口方式: 设置SPI的SDO引脚的中断方式 */ +/* 输入: 数据16H, 中断方式 */ +/* 10H=禁止SDO引脚用于中断输出,在SCS片选无效时三态输出禁止, 90H=SDO引脚在SCS片选无效时兼做中断请求输出 */ + +#define CMD14_GET_FILE_SIZE 0x0C /* 主机文件模式: 获取当前文件长度 */ +/* 输入: 数据68H */ +/* 输出: 当前文件长度(总长度32位,低字节在前) */ + +#define CMD50_SET_FILE_SIZE 0x0D /* 主机文件模式: 设置当前文件长度 */ +/* 输入: 数据68H, 当前文件长度(总长度32位,低字节在前) */ + +#define CMD11_SET_USB_MODE 0x15 /* 设置USB工作模式 */ +/* 输入: 模式代码 */ +/* 00H=未启用的设备方式, 01H=已启用的设备方式并且使用外部固件模式(串口不支持), 02H=已启用的设备方式并且使用内置固件模式 */ +/* 03H=SD卡主机模式/未启用的主机模式,用于管理和存取SD卡中的文件 */ +/* 04H=未启用的主机方式, 05H=已启用的主机方式, 06H=已启用的主机方式并且自动产生SOF包, 07H=已启用的主机方式并且复位USB总线 */ +/* 输出: 操作状态( CMD_RET_SUCCESS或CMD_RET_ABORT, 其它值说明操作未完成 ) */ + +#define CMD01_GET_STATUS 0x22 /* 获取中断状态并取消中断请求 */ +/* 输出: 中断状态 */ + +#define CMD00_UNLOCK_USB 0x23 /* 设备方式: 释放当前USB缓冲区 */ + +#define CMD01_RD_USB_DATA0 0x27 /* 从当前USB中断的端点缓冲区或者主机端点的接收缓冲区读取数据块 */ +/* 输出: 长度, 数据流 */ + +#define CMD01_RD_USB_DATA 0x28 /* 设备方式: 从当前USB中断的端点缓冲区读取数据块, 并释放缓冲区, 相当于 CMD01_RD_USB_DATA0 + CMD00_UNLOCK_USB */ +/* 输出: 长度, 数据流 */ + +#define CMD10_WR_USB_DATA7 0x2B /* 设备方式: 向USB端点2的发送缓冲区写入数据块 */ +/* 输入: 长度, 数据流 */ + +#define CMD10_WR_HOST_DATA 0x2C /* 向USB主机端点的发送缓冲区写入数据块 */ +/* 输入: 长度, 数据流 */ + +#define CMD01_WR_REQ_DATA 0x2D /* 向内部指定缓冲区写入请求的数据块 */ +/* 输出: 长度 */ +/* 输入: 数据流 */ + +#define CMD20_WR_OFS_DATA 0x2E /* 向内部缓冲区指定偏移地址写入数据块 */ +/* 输入: 偏移, 长度, 数据流 */ + +#define CMD10_SET_FILE_NAME 0x2F /* 主机文件模式: 设置将要操作的文件的文件名 */ +/* 输入: 以0结束的字符串(含结束符0在内长度不超过14个字符) */ + +/* ********************************************************************************************************************* */ +/* 主要命令(手册一), 常用, 以下命令总是在操作结束时产生中断通知, 并且总是没有输出数据 */ + +#define CMD0H_DISK_CONNECT 0x30 /* 主机文件模式/不支持SD卡: 检查磁盘是否连接 */ +/* 输出中断 */ + +#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 /* 主机文件模式: 关闭当前已经打开的文件或者目录(文件夹) */ +/* 输入: 是否允许更新文件长度 */ +/* 00H=禁止更新长度, 01H=允许更新长度 */ +/* 输出中断 */ + +#define CMD1H_DIR_INFO_READ 0x37 /* 主机文件模式: 读取文件的目录信息 */ +/* 输入: 指定需要读取的目录信息结构在扇区内的索引号 */ +/* 索引号范围为00H~0FH, 索引号0FFH则为当前已经打开的文件 */ +/* 输出中断 */ + +#define CMD0H_DIR_INFO_SAVE 0x38 /* 主机文件模式: 保存文件的目录信息 */ +/* 输出中断 */ + +#define CMD4H_BYTE_LOCATE 0x39 /* 主机文件模式: 以字节为单位移动当前文件指针 */ +/* 输入: 偏移字节数(总长度32位,低字节在前) */ +/* 输出中断 */ + +#define CMD2H_BYTE_READ 0x3A /* 主机文件模式: 以字节为单位从当前位置读取数据块 */ +/* 输入: 请求读取的字节数(总长度16位,低字节在前) */ +/* 输出中断 */ + +#define CMD0H_BYTE_RD_GO 0x3B /* 主机文件模式: 继续字节读 */ +/* 输出中断 */ + +#define CMD2H_BYTE_WRITE 0x3C /* 主机文件模式: 以字节为单位向当前位置写入数据块 */ +/* 输入: 请求写入的字节数(总长度16位,低字节在前) */ +/* 输出中断 */ + +#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 /* 主机文件模式: 以扇区为单位移动当前文件指针 */ +/* 输入: 偏移扇区数(总长度32位,低字节在前) */ +/* 输出中断 */ + +#define CMD1H_SEC_READ 0x4B /* 主机文件模式/不支持SD卡: 以扇区为单位从当前位置读取数据块 */ +/* 输入: 请求读取的扇区数 */ +/* 输出中断 */ + +#define CMD1H_SEC_WRITE 0x4C /* 主机文件模式/不支持SD卡: 以扇区为单位在当前位置写入数据块 */ +/* 输入: 请求写入的扇区数 */ +/* 输出中断 */ + +#define CMD0H_DISK_BOC_CMD 0x50 /* 主机方式/不支持SD卡: 对USB存储器执行BulkOnly传输协议的命令 */ +/* 输出中断 */ + +#define CMD5H_DISK_READ 0x54 /* 主机方式/不支持SD卡: 从USB存储器读物理扇区 */ +/* 输入: LBA物理扇区地址(总长度32位, 低字节在前), 扇区数(01H~FFH) */ +/* 输出中断 */ + +#define CMD0H_DISK_RD_GO 0x55 /* 主机方式/不支持SD卡: 继续执行USB存储器的物理扇区读操作 */ +/* 输出中断 */ + +#define CMD5H_DISK_WRITE 0x56 /* 主机方式/不支持SD卡: 向USB存储器写物理扇区 */ +/* 输入: LBA物理扇区地址(总长度32位, 低字节在前), 扇区数(01H~FFH) */ +/* 输出中断 */ + +#define CMD0H_DISK_WR_GO 0x57 /* 主机方式/不支持SD卡: 继续执行USB存储器的物理扇区写操作 */ +/* 输出中断 */ + +/* ********************************************************************************************************************* */ +/* 辅助命令(手册二), 不太常用或者是为了与CH375和CH372兼容 */ + +#define CMD10_SET_USB_SPEED 0x04 /* 设置USB总线速度, 在每次CMD11_SET_USB_MODE设置USB工作模式时会自动恢复到12Mbps全速 */ +/* 输入: 总线速度代码 */ +/* 00H=12Mbps全速FullSpeed(默认值), 01H=1.5Mbps(仅修改频率), 02H=1.5Mbps低速LowSpeed */ + +#define CMD11_GET_DEV_RATE 0x0A /* 主机方式: 获取当前连接的USB设备的数据速率类型 */ +/* 输入: 数据07H */ +/* 输出: 数据速率类型 */ +/* 位4为1则是1.5Mbps低速USB设备, 否则是12Mbps全速USB设备 */ + +#define CMD11_GET_TOGGLE 0x0A /* 获取OUT事务的同步状态 */ +/* 输入: 数据1AH */ +/* 输出: 同步状态 */ +/* 位4为1则OUT事务同步, 否则OUT事务不同步 */ + +#define CMD11_READ_VAR8 0x0A /* 读取指定的8位文件系统变量 */ +/* 输入: 变量地址 */ +/* 输出: 数据 */ + +/*#define CMD11_GET_MAX_LUN = CMD11_READ_VAR8( VAR_UDISK_LUN )*/ /* 主机方式: 获取USB存储器最大和当前逻辑单元号 */ + +#define CMD20_SET_RETRY 0x0B /* 主机方式: 设置USB事务操作的重试次数 */ +/* 输入: 数据25H, 重试次数 */ +/* 位7为0则收到NAK时不重试, 位7为1位6为0则收到NAK时无限重试, 位7为1位6为1则收到NAK时最多重试3秒, 位5~位0为超时后的重试次数 */ + +#define CMD20_WRITE_VAR8 0x0B /* 设置指定的8位文件系统变量 */ +/* 输入: 变量地址, 数据 */ + +/*#define CMD20_SET_DISK_LUN = CMD20_WRITE_VAR8( VAR_UDISK_LUN )*/ /* 主机方式: 设置USB存储器的当前逻辑单元号 */ + +#define CMD14_READ_VAR32 0x0C /* 读取指定的32位文件系统变量 */ +/* 输入: 变量地址 */ +/* 输出: 数据(总长度32位,低字节在前) */ + +#define CMD50_WRITE_VAR32 0x0D /* 设置指定的32位文件系统变量 */ +/* 输入: 变量地址, 数据(总长度32位,低字节在前) */ + +#define CMD01_DELAY_100US 0x0F /* 延时100uS(串口不支持) */ +/* 输出: 延时期间输出0,延时结束输出非0 */ + +#define CMD40_SET_USB_ID 0x12 /* 设备方式: 设置USB厂商VID和产品PID */ +/* 输入: 厂商ID低字节, 厂商ID高字节, 产品ID低字节, 产品ID高字节 */ + +#define CMD10_SET_USB_ADDR 0x13 /* 设置USB地址 */ +/* 输入: 地址值 */ + +#define CMD01_TEST_CONNECT 0x16 /* 主机方式/不支持SD卡: 检查USB设备连接状态 */ +/* 输出: 状态( USB_INT_CONNECT或USB_INT_DISCONNECT或USB_INT_USB_READY, 其它值说明操作未完成 ) */ + +#define CMD00_ABORT_NAK 0x17 /* 主机方式: 放弃当前NAK的重试 */ + +#define CMD10_SET_ENDP2 0x18 /* 设备方式(串口不支持): 设置USB端点0的接收器 */ +/* 输入: 工作方式 */ +/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ +/* 位3~位0为事务响应方式: 0000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ + +#define CMD10_SET_ENDP3 0x19 /* 设备方式(串口不支持): 设置USB端点0的发送器 */ +/* 输入: 工作方式 */ +/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ +/* 位3~位0为事务响应方式: 0000~1000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ + +#define CMD10_SET_ENDP4 0x1A /* 设备方式(串口不支持): 设置USB端点1的接收器 */ +/* 输入: 工作方式 */ +/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ +/* 位3~位0为事务响应方式: 0000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ + +#define CMD10_SET_ENDP5 0x1B /* 设备方式(串口不支持): 设置USB端点1的发送器 */ +/* 输入: 工作方式 */ +/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ +/* 位3~位0为事务响应方式: 0000~1000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ + +#define CMD10_SET_ENDP6 0x1C /* 设置USB端点2/主机端点的接收器 */ +/* 输入: 工作方式 */ +/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ +/* 位3~位0为事务响应方式: 0000-就绪ACK, 1101-就绪但不返回ACK, 1110-正忙NAK, 1111-错误STALL */ + +#define CMD10_SET_ENDP7 0x1D /* 设置USB端点2/主机端点的发送器 */ +/* 输入: 工作方式 */ +/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ +/* 位3~位0为事务响应方式: 0000-就绪ACK, 1101-就绪但无须应答, 1110-正忙NAK, 1111-错误STALL */ + +#define CMD00_DIRTY_BUFFER 0x25 /* 主机文件模式: 清除内部的磁盘和文件缓冲区 */ + +#define CMD10_WR_USB_DATA3 0x29 /* 设备方式(串口不支持): 向USB端点0的发送缓冲区写入数据块 */ +/* 输入: 长度, 数据流 */ + +#define CMD10_WR_USB_DATA5 0x2A /* 设备方式(串口不支持): 向USB端点1的发送缓冲区写入数据块 */ +/* 输入: 长度, 数据流 */ + +/* ********************************************************************************************************************* */ +/* 辅助命令(手册二), 不太常用或者是为了与CH375和CH372兼容, 以下命令总是在操作结束时产生中断通知, 并且总是没有输出数据 */ + +#define CMD1H_CLR_STALL 0x41 /* 主机方式: 控制传输-清除端点错误 */ +/* 输入: 端点号 */ +/* 输出中断 */ + +#define CMD1H_SET_ADDRESS 0x45 /* 主机方式: 控制传输-设置USB地址 */ +/* 输入: 地址值 */ +/* 输出中断 */ + +#define CMD1H_GET_DESCR 0x46 /* 主机方式: 控制传输-获取描述符 */ +/* 输入: 描述符类型 */ +/* 输出中断 */ + +#define CMD1H_SET_CONFIG 0x49 /* 主机方式: 控制传输-设置USB配置 */ +/* 输入: 配置值 */ +/* 输出中断 */ + +#define CMD0H_AUTO_SETUP 0x4D /* 主机方式/不支持SD卡: 自动配置USB设备 */ +/* 输出中断 */ + +#define CMD2H_ISSUE_TKN_X 0x4E /* 主机方式: 发出同步令牌, 执行事务, 该命令可代替 CMD10_SET_ENDP6/CMD10_SET_ENDP7 + CMD1H_ISSUE_TOKEN */ +/* 输入: 同步标志, 事务属性 */ +/* 同步标志的位7为主机端点IN的同步触发位, 位6为主机端点OUT的同步触发位, 位5~位0必须为0 */ +/* 事务属性的低4位是令牌, 高4位是端点号 */ +/* 输出中断 */ + +#define CMD1H_ISSUE_TOKEN 0x4F /* 主机方式: 发出令牌, 执行事务, 建议用CMD2H_ISSUE_TKN_X命令 */ +/* 输入: 事务属性 */ +/* 低4位是令牌, 高4位是端点号 */ +/* 输出中断 */ + +#define CMD0H_DISK_INIT 0x51 /* 主机方式/不支持SD卡: 初始化USB存储器 */ +/* 输出中断 */ + +#define CMD0H_DISK_RESET 0x52 /* 主机方式/不支持SD卡: 控制传输-复位USB存储器 */ +/* 输出中断 */ + +#define CMD0H_DISK_SIZE 0x53 /* 主机方式/不支持SD卡: 获取USB存储器的容量 */ +/* 输出中断 */ + +#define CMD0H_DISK_INQUIRY 0x58 /* 主机方式/不支持SD卡: 查询USB存储器特性 */ +/* 输出中断 */ + +#define CMD0H_DISK_READY 0x59 /* 主机方式/不支持SD卡: 检查USB存储器就绪 */ +/* 输出中断 */ + +#define CMD0H_DISK_R_SENSE 0x5A /* 主机方式/不支持SD卡: 检查USB存储器错误 */ +/* 输出中断 */ + +#define CMD0H_RD_DISK_SEC 0x5B /* 主机文件模式: 从磁盘读取一个扇区的数据到内部缓冲区 */ +/* 输出中断 */ + +#define CMD0H_WR_DISK_SEC 0x5C /* 主机文件模式: 将内部缓冲区的一个扇区的数据写入磁盘 */ +/* 输出中断 */ + +#define CMD0H_DISK_MAX_LUN 0x5D /* 主机方式: 控制传输-获取USB存储器最大逻辑单元号 */ +/* 输出中断 */ + +/* ********************************************************************************************************************* */ +/* 以下定义只是为了兼容CH375的INCLUDE文件中的命令名称格式 */ + +#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 /* 并口方式状态端口的位7: 中断标志,低有效 */ +#define PARA_STATE_BUSY 0x10 /* 并口方式状态端口的位4: 忙标志,高有效 */ +#endif + +/* ********************************************************************************************************************* */ +/* 串口方式, 操作命令前的引导同步码 */ +#ifndef SER_CMD_TIMEOUT +#define SER_CMD_TIMEOUT 32 /* 串口命令超时时间, 单位为mS, 同步码之间及同步码与命令码之间的间隔应该尽量短, 超时后的处理方式为丢弃 */ +#define SER_SYNC_CODE1 0x57 /* 启动操作的第1个串口同步码 */ +#define SER_SYNC_CODE2 0xAB /* 启动操作的第2个串口同步码 */ +#endif + +/* ********************************************************************************************************************* */ +/* 操作状态 */ + +#ifndef CMD_RET_SUCCESS +#define CMD_RET_SUCCESS 0x51 /* 命令操作成功 */ +#define CMD_RET_ABORT 0x5F /* 命令操作失败 */ +#endif + +/* ********************************************************************************************************************* */ +/* USB中断状态 */ + +#ifndef USB_INT_EP0_SETUP + +/* 以下状态代码为特殊事件中断, 如果通过CMD20_CHK_SUSPEND启用USB总线挂起检查, 那么必须处理USB总线挂起和睡眠唤醒的中断状态 */ +#define USB_INT_USB_SUSPEND 0x05 /* USB总线挂起事件 */ +#define USB_INT_WAKE_UP 0x06 /* 从睡眠中被唤醒事件 */ + +/* 以下状态代码0XH用于USB设备方式 */ +/* 内置固件模式下只需要处理: USB_INT_EP1_OUT, USB_INT_EP1_IN, USB_INT_EP2_OUT, USB_INT_EP2_IN */ +/* 位7-位4为0000 */ +/* 位3-位2指示当前事务, 00=OUT, 10=IN, 11=SETUP */ +/* 位1-位0指示当前端点, 00=端点0, 01=端点1, 10=端点2, 11=USB总线复位 */ +#define USB_INT_EP0_SETUP 0x0C /* USB端点0的SETUP */ +#define USB_INT_EP0_OUT 0x00 /* USB端点0的OUT */ +#define USB_INT_EP0_IN 0x08 /* USB端点0的IN */ +#define USB_INT_EP1_OUT 0x01 /* USB端点1的OUT */ +#define USB_INT_EP1_IN 0x09 /* USB端点1的IN */ +#define USB_INT_EP2_OUT 0x02 /* USB端点2的OUT */ +#define USB_INT_EP2_IN 0x0A /* USB端点2的IN */ +/* USB_INT_BUS_RESET 0x0000XX11B */ /* USB总线复位 */ +#define USB_INT_BUS_RESET1 0x03 /* USB总线复位 */ +#define USB_INT_BUS_RESET2 0x07 /* USB总线复位 */ +#define USB_INT_BUS_RESET3 0x0B /* USB总线复位 */ +#define USB_INT_BUS_RESET4 0x0F /* USB总线复位 */ + +#endif + +/* 以下状态代码2XH-3XH用于USB主机方式的通讯失败代码 */ +/* 位7-位6为00 */ +/* 位5为1 */ +/* 位4指示当前接收的数据包是否同步 */ +/* 位3-位0指示导致通讯失败时USB设备的应答: 0010=ACK, 1010=NAK, 1110=STALL, 0011=DATA0, 1011=DATA1, XX00=超时 */ +/* USB_INT_RET_ACK 0x001X0010B */ /* 错误:对于IN事务返回ACK */ +/* USB_INT_RET_NAK 0x001X1010B */ /* 错误:返回NAK */ +/* USB_INT_RET_STALL 0x001X1110B */ /* 错误:返回STALL */ +/* USB_INT_RET_DATA0 0x001X0011B */ /* 错误:对于OUT/SETUP事务返回DATA0 */ +/* USB_INT_RET_DATA1 0x001X1011B */ /* 错误:对于OUT/SETUP事务返回DATA1 */ +/* USB_INT_RET_TOUT 0x001XXX00B */ /* 错误:返回超时 */ +/* USB_INT_RET_TOGX 0x0010X011B */ /* 错误:对于IN事务返回数据不同步 */ +/* USB_INT_RET_PID 0x001XXXXXB */ /* 错误:未定义 */ + +/* 以下状态代码1XH用于USB主机方式的操作状态代码 */ +#ifndef USB_INT_SUCCESS +#define USB_INT_SUCCESS 0x14 /* USB事务或者传输操作成功 */ +#define USB_INT_CONNECT 0x15 /* 检测到USB设备连接事件, 可能是新连接或者断开后重新连接 */ +#define USB_INT_DISCONNECT 0x16 /* 检测到USB设备断开事件 */ +#define USB_INT_BUF_OVER 0x17 /* USB传输的数据有误或者数据太多缓冲区溢出 */ +#define USB_INT_USB_READY 0x18 /* USB设备已经被初始化(已经分配USB地址) */ +#define USB_INT_DISK_READ 0x1D /* USB存储器请求数据读出 */ +#define USB_INT_DISK_WRITE 0x1E /* USB存储器请求数据写入 */ +#define USB_INT_DISK_ERR 0x1F /* USB存储器操作失败 */ +#endif + +/* 以下状态代码用于主机文件模式下的文件系统错误码 */ +#ifndef ERR_DISK_DISCON +#define ERR_DISK_DISCON 0x82 /* 磁盘尚未连接,可能磁盘已经断开 */ +#define ERR_LARGE_SECTOR 0x84 /* 磁盘的扇区太大,只支持每扇区512字节 */ +#define ERR_TYPE_ERROR 0x92 /* 磁盘分区类型不支持,只支持FAT12/FAT16/BigDOS/FAT32,需要由磁盘管理工具重新分区 */ +#define ERR_BPB_ERROR 0xA1 /* 磁盘尚未格式化,或者参数错误,需要由WINDOWS采用默认参数重新格式化 */ +#define ERR_DISK_FULL 0xB1 /* 磁盘文件太满,剩余空间太少或者已经没有,需要磁盘整理 */ +#define ERR_FDT_OVER 0xB2 /* 目录(文件夹)内文件太多,没有空闲的目录项,FAT12/FAT16根目录下的文件数应该少于512个,需要磁盘整理 */ +#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 + +/* ********************************************************************************************************************* */ +/* 以下状态代码用于主机文件模式下的磁盘及文件状态, VAR_DISK_STATUS */ +#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 /* 已经打开根目录,使用后必须关闭,注意FAT12/FAT16根目录是固定长度 */ +#define DEF_DISK_OPEN_DIR 0x13 /* 已经打开子目录(文件夹) */ +#define DEF_DISK_OPEN_FILE 0x14 /* 已经打开文件 */ +#endif + +/* ********************************************************************************************************************* */ +/* 文件系统常用定义 */ + +#ifndef DEF_SECTOR_SIZE +#define DEF_SECTOR_SIZE 512 /* U盘或者SD卡默认的物理扇区的大小 */ +#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 /* 默认文件日期: 2004年 */ +#define DEF_FILE_MONTH 1 /* 默认文件日期: 1月 */ +#define DEF_FILE_DATE 1 /* 默认文件日期: 1日 */ +#endif + +#ifndef ATTR_DIRECTORY + +/* FAT数据区中文件目录信息 */ +typedef struct _FAT_DIR_INFO { + UINT8 DIR_Name[11]; /* 00H,文件名,共11字节,不足处填空格 */ + UINT8 DIR_Attr; /* 0BH,文件属性,参考后面的说明 */ + UINT8 DIR_NTRes; /* 0CH */ + UINT8 DIR_CrtTimeTenth; /* 0DH,文件创建的时间,以0.1秒单位计数 */ + UINT16 DIR_CrtTime; /* 0EH,文件创建的时间 */ + UINT16 DIR_CrtDate; /* 10H,文件创建的日期 */ + UINT16 DIR_LstAccDate; /* 12H,最近一次存取操作的日期 */ + UINT16 DIR_FstClusHI; /* 14H */ + UINT16 DIR_WrtTime; /* 16H,文件修改时间,参考前面的宏MAKE_FILE_TIME */ + UINT16 DIR_WrtDate; /* 18H,文件修改日期,参考前面的宏MAKE_FILE_DATE */ + UINT16 DIR_FstClusLO; /* 1AH */ + UINT32 DIR_FileSize; /* 1CH,文件长度 */ +} FAT_DIR_INFO, *P_FAT_DIR_INFO; /* 20H */ + +/* 文件属性 */ +#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 ) +/* 文件属性 UINT8 */ +/* bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 */ +/* 只 隐 系 卷 目 存 未定义 */ +/* 读 藏 统 标 录 档 */ +/* 文件时间 UINT16 */ +/* Time = (Hour<<11) + (Minute<<5) + (Second>>1) */ +#define MAKE_FILE_TIME( h, m, s ) ( (h<<11) + (m<<5) + (s>>1) ) /* 生成指定时分秒的文件时间数据 */ +/* 文件日期 UINT16 */ +/* Date = ((Year-1980)<<9) + (Month<<5) + Day */ +#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 + +/* ********************************************************************************************************************* */ +/* SCSI命令和数据输入输出结构 */ + +#ifndef SPC_CMD_INQUIRY + +/* SCSI命令码 */ +#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 + +/* BulkOnly协议的命令块 */ +typedef struct _BULK_ONLY_CBW { + UINT32 CBW_Sig; + UINT32 CBW_Tag; + UINT8 CBW_DataLen0; /* 08H,输入: 数据传输长度,对于输入数据其有效值是0到48,对于输出数据其有效值为0到33 */ + UINT8 CBW_DataLen1; + UINT16 CBW_DataLen2; + UINT8 CBW_Flag; /* 0CH,输入: 传输方向等标志,位7为1则输入数据,位为0则输出数据或者没有数据 */ + UINT8 CBW_LUN; + UINT8 CBW_CB_Len; /* 0EH,输入: 命令块的长度,有效值是1到16 */ + UINT8 CBW_CB_Buf[16]; /* 0FH,输入: 命令块,该缓冲区最多为16个字节 */ +} BULK_ONLY_CBW, *P_BULK_ONLY_CBW; /* BulkOnly协议的命令块, 输入CBW结构 */ + +/* INQUIRY命令的返回数据 */ +typedef struct _INQUIRY_DATA { + UINT8 DeviceType; /* 00H, 设备类型 */ + UINT8 RemovableMedia; /* 01H, 位7为1说明是移动存储 */ + UINT8 Versions; /* 02H, 协议版本 */ + UINT8 DataFormatAndEtc; /* 03H, 指定返回数据格式 */ + UINT8 AdditionalLength; /* 04H, 后续数据的长度 */ + UINT8 Reserved1; + UINT8 Reserved2; + UINT8 MiscFlag; /* 07H, 一些控制标志 */ + UINT8 VendorIdStr[8]; /* 08H, 厂商信息 */ + UINT8 ProductIdStr[16]; /* 10H, 产品信息 */ + UINT8 ProductRevStr[4]; /* 20H, 产品版本 */ +} INQUIRY_DATA, *P_INQUIRY_DATA; /* 24H */ + +/* REQUEST SENSE命令的返回数据 */ +typedef struct _SENSE_DATA { + UINT8 ErrorCode; /* 00H, 错误代码及有效位 */ + UINT8 SegmentNumber; + UINT8 SenseKeyAndEtc; /* 02H, 主键码 */ + UINT8 Information0; + UINT8 Information1; + UINT8 Information2; + UINT8 Information3; + UINT8 AdditSenseLen; /* 07H, 后续数据的长度 */ + UINT8 CmdSpecInfo[4]; + UINT8 AdditSenseCode; /* 0CH, 附加键码 */ + UINT8 AddSenCodeQual; /* 0DH, 详细的附加键码 */ + UINT8 FieldReplaUnit; + UINT8 SenseKeySpec[3]; +} SENSE_DATA, *P_SENSE_DATA; /* 12H */ + +#endif + +/* ********************************************************************************************************************* */ +/* 主机文件模式下的数据输入和输出结构 */ + +#ifndef MAX_FILE_NAME_LEN + +#define MAX_FILE_NAME_LEN (13+1) /* 文件名最大长度,最大长度是1个根目录符+8个主文件名+1个小数点+3个类型名+结束符=14 */ + +/* 命令的输入数据和输出数据 */ +typedef union _CH376_CMD_DATA { + struct { + UINT8 mBuffer[ MAX_FILE_NAME_LEN ]; + } Default; + + INQUIRY_DATA DiskMountInq; /* 返回: INQUIRY命令的返回数据 */ + /* CMD0H_DISK_MOUNT: 初始化磁盘并测试磁盘是否就绪,首次执行时 */ + + FAT_DIR_INFO OpenDirInfo; /* 返回: 枚举到的文件目录信息 */ + /* CMD0H_FILE_OPEN: 枚举文件和目录(文件夹) */ + + FAT_DIR_INFO EnumDirInfo; /* 返回: 枚举到的文件目录信息 */ + /* CMD0H_FILE_ENUM_GO: 继续枚举文件和目录(文件夹) */ + + struct { + UINT8 mUpdateFileSz; /* 输入参数: 是否允许更新文件长度, 0则禁止更新长度 */ + } FileCLose; /* CMD1H_FILE_CLOSE: 关闭当前已经打开的文件 */ + + struct { + UINT8 mDirInfoIndex; /* 输入参数: 指定需要读取的目录信息结构在扇区内的索引号, 0FFH则为当前已经打开的文件 */ + } DirInfoRead; /* CMD1H_DIR_INFO_READ: 读取文件的目录信息 */ + + union { + UINT32 mByteOffset; /* 输入参数: 偏移字节数,以字节为单位的偏移量(总长度32位,低字节在前) */ + UINT32 mSectorLba; /* 返回: 当前文件指针对应的绝对线性扇区号,0FFFFFFFFH则已到文件尾(总长度32位,低字节在前) */ + } ByteLocate; /* CMD4H_BYTE_LOCATE: 以字节为单位移动当前文件指针 */ + + struct { + UINT16 mByteCount; /* 输入参数: 请求读取的字节数(总长度16位,低字节在前) */ + } ByteRead; /* CMD2H_BYTE_READ: 以字节为单位从当前位置读取数据块 */ + + struct { + UINT16 mByteCount; /* 输入参数: 请求写入的字节数(总长度16位,低字节在前) */ + } ByteWrite; /* CMD2H_BYTE_WRITE: 以字节为单位向当前位置写入数据块 */ + + union { + UINT32 mSectorOffset; /* 输入参数: 偏移扇区数,以扇区为单位的偏移量(总长度32位,低字节在前) */ + UINT32 mSectorLba; /* 返回: 当前文件指针对应的绝对线性扇区号,0FFFFFFFFH则已到文件尾(总长度32位,低字节在前) */ + } SectorLocate; /* CMD4H_SEC_LOCATE: 以扇区为单位移动当前文件指针 */ + + struct { + UINT8 mSectorCount; /* 输入参数: 请求读取的扇区数 */ + /* 返回: 允许读取的扇区数 */ + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; /* 返回: 允许读取的扇区块的起始绝对线性扇区号(总长度32位,低字节在前) */ + } SectorRead; /* CMD1H_SEC_READ: 以扇区为单位从当前位置读取数据块 */ + + struct { + UINT8 mSectorCount; /* 输入参数: 请求写入的扇区数 */ + /* 返回: 允许写入的扇区数 */ + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; /* 返回: 允许写入的扇区块的起始绝对线性扇区号(总长度32位,低字节在前) */ + } SectorWrite; /* CMD1H_SEC_WRITE: 以扇区为单位在当前位置写入数据块 */ + + struct { + UINT32 mDiskSizeSec; /* 返回: 整个物理磁盘的总扇区数(总长度32位,低字节在前) */ + } DiskCapacity; /* CMD0H_DISK_CAPACITY: 查询磁盘物理容量 */ + + struct { + UINT32 mTotalSector; /* 返回: 当前逻辑盘的总扇区数(总长度32位,低字节在前) */ + UINT32 mFreeSector; /* 返回: 当前逻辑盘的剩余扇区数(总长度32位,低字节在前) */ + UINT8 mDiskFat; /* 返回: 当前逻辑盘的FAT类型,1-FAT12,2-FAT16,3-FAT32 */ + } DiskQuery; /* CMD_DiskQuery, 查询磁盘信息 */ + + BULK_ONLY_CBW DiskBocCbw; /* 输入参数: CBW命令结构 */ + /* CMD0H_DISK_BOC_CMD: 对USB存储器执行BulkOnly传输协议的命令 */ + + struct { + UINT8 mMaxLogicUnit; /* 返回: USB存储器的最大逻辑单元号 */ + } DiskMaxLun; /* CMD0H_DISK_MAX_LUN: 控制传输-获取USB存储器最大逻辑单元号 */ + + INQUIRY_DATA DiskInitInq; /* 返回: INQUIRY命令的返回数据 */ + /* CMD0H_DISK_INIT: 初始化USB存储器 */ + + INQUIRY_DATA DiskInqData; /* 返回: INQUIRY命令的返回数据 */ + /* CMD0H_DISK_INQUIRY: 查询USB存储器特性 */ + + SENSE_DATA ReqSenseData; /* 返回: REQUEST SENSE命令的返回数据 */ + /* CMD0H_DISK_R_SENSE: 检查USB存储器错误 */ + + struct { + UINT32 mDiskSizeSec; /* 返回: 整个物理磁盘的总扇区数(总长度32位,高字节在前) */ + } DiskSize; /* CMD0H_DISK_SIZE: 获取USB存储器的容量 */ + + struct { + UINT32 mStartSector; /* 输入参数: LBA扇区地址(总长度32位,低字节在前) */ + UINT8 mSectorCount; /* 输入参数: 请求读取的扇区数 */ + } DiskRead; /* CMD5H_DISK_READ: 从USB存储器读数据块(以扇区为单位) */ + + struct { + UINT32 mStartSector; /* 输入参数: LBA扇区地址(总长度32位,低字节在前) */ + UINT8 mSectorCount; /* 输入参数: 请求写入的扇区数 */ + } DiskWrite; /* CMD5H_DISK_WRITE: 向USB存储器写数据块(以扇区为单位) */ +} CH376_CMD_DATA, *P_CH376_CMD_DATA; + +#endif + +/* ********************************************************************************************************************* */ +/* 主机文件模式下的文件系统变量的地址 */ + +#ifndef VAR_FILE_SIZE + +/* 8位/单字节变量 */ +#define VAR_SYS_BASE_INFO 0x20 /* 当前系统的基本信息 */ +/* 位6用于指示USB存储设备的子类别SubClass-Code, 位6为0则说明子类别为6, 位6为1则说明子类别是非6的其它值 */ +/* 位5用于指示USB设备方式下的USB配置状态和USB主机方式下的USB设备连接状态 */ +/* USB设备方式下, 位5为1则USB配置完成, 位5位0则尚未配置 */ +/* USB主机方式下, 位5为1则USB端口存在USB设备, 位5位0则USB端口没有USB设备 */ +/* 位4用于指示USB设备方式下的缓冲区锁定状态, 位4为1则说明USB缓冲区处于锁定状态, 位6为1则说明已经释放 */ +/* 其它位, 保留,请勿修改 */ +#define VAR_RETRY_TIMES 0x25 /* USB事务操作的重试次数 */ +/* 位7为0则收到NAK时不重试, 位7为1位6为0则收到NAK时无限重试(可以用CMD_ABORT_NAK命令放弃重试), 位7为1位6为1则收到NAK时最多重试3秒 */ +/* 位5~位0为超时后的重试次数 */ +#define VAR_FILE_BIT_FLAG 0x26 /* 主机文件模式下的位标志 */ +/* 位1和位0, 逻辑盘的FAT文件系统标志, 00-FAT12, 01-FAT16, 10-FAT32, 11-非法 */ +/* 位2, 当前缓冲区中的FAT表数据是否被修改标志, 0-未修改, 1-已修改 */ +/* 位3, 文件长度需要修改标志, 当前文件被追加数据, 0-未追加无需修改, 1-已追加需要修改 */ +/* 其它位, 保留,请勿修改 */ +#define VAR_DISK_STATUS 0x2B /* 主机文件模式下的磁盘及文件状态 */ +#define VAR_SD_BIT_FLAG 0x30 /* 主机文件模式下SD卡的位标志 */ +/* 位0, SD卡版本, 0-只支持SD第一版,1-支持SD第二版 */ +/* 位1, 自动识别, 0-SD卡, 1-MMC卡 */ +/* 位2, 自动识别, 0-标准容量SD卡, 1-大容量SD卡(HC-SD) */ +/* 位4, ACMD41命令超时 */ +/* 位5, CMD1命令超时 */ +/* 位6, CMD58命令超时 */ +/* 其它位, 保留,请勿修改 */ +#define VAR_UDISK_TOGGLE 0x31 /* USB存储设备的BULK-IN/BULK-OUT端点的同步标志 */ +/* 位7, Bulk-In端点的同步标志 */ +/* 位6, Bulk-In端点的同步标志 */ +/* 位5~位0, 必须为0 */ +#define VAR_UDISK_LUN 0x34 /* USB存储设备的逻辑单元号 */ +/* 位7~位4, USB存储设备的当前逻辑单元号,CH376初始化USB存储设备后,默认是访问0#逻辑单元 */ +/* 位3~位0, USB存储设备的最大逻辑单元号,加1后等于逻辑单元数 */ +#define VAR_SEC_PER_CLUS 0x38 /* 逻辑盘的每簇扇区数 */ +#define VAR_FILE_DIR_INDEX 0x3B /* 当前文件目录信息在扇区内的索引号 */ +#define VAR_CLUS_SEC_OFS 0x3C /* 当前文件指针在簇内的扇区偏移,为0xFF则指向文件末尾,簇结束 */ + +/* 32位/4字节变量 */ +#define VAR_DISK_ROOT 0x44 /* 对于FAT16盘为根目录占用扇区数,对于FAT32盘为根目录起始簇号(总长度32位,低字节在前) */ +#define VAR_DSK_TOTAL_CLUS 0x48 /* 逻辑盘的总簇数(总长度32位,低字节在前) */ +#define VAR_DSK_START_LBA 0x4C /* 逻辑盘的起始绝对扇区号LBA(总长度32位,低字节在前) */ +#define VAR_DSK_DAT_START 0x50 /* 逻辑盘的数据区域的起始LBA(总长度32位,低字节在前) */ +#define VAR_LBA_BUFFER 0x54 /* 当前磁盘数据缓冲区的数据对应的LBA(总长度32位,低字节在前) */ +#define VAR_LBA_CURRENT 0x58 /* 当前读写的磁盘起始LBA地址(总长度32位,低字节在前) */ +#define VAR_FAT_DIR_LBA 0x5C /* 当前文件目录信息所在的扇区LBA地址(总长度32位,低字节在前) */ +#define VAR_START_CLUSTER 0x60 /* 当前文件或者目录(文件夹)的起始簇号(总长度32位,低字节在前) */ +#define VAR_CURRENT_CLUST 0x64 /* 当前文件的当前簇号(总长度32位,低字节在前) */ +#define VAR_FILE_SIZE 0x68 /* 当前文件的长度(总长度32位,低字节在前) */ +#define VAR_CURRENT_OFFSET 0x6C /* 当前文件指针,当前读写位置的字节偏移(总长度32位,低字节在前) */ + +#endif + +/* ********************************************************************************************************************* */ +/* 常用USB定义 */ + +/* USB的包标识PID, 主机方式可能用到 */ +#ifndef DEF_USB_PID_SETUP +#define DEF_USB_PID_NULL 0x00 /* 保留PID, 未定义 */ +#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 + +/* USB请求类型, 外置固件模式可能用到 */ +#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 + +/* USB标准设备请求, RequestType的位6位5=00(Standard), 外置固件模式可能用到 */ +#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 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c new file mode 100644 index 000000000..75be34c2c --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c @@ -0,0 +1,978 @@ +/* +* 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 xidatong-riscv64 k210_ch376.c + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2022.10.10 + */ + +/* CH376芯片 文件系统层 V1.3 */ +/* 提供文件系统常用子程序,提供命令打包 */ +/* 不使用的子程序可以注释掉,从而节约单片机的程序ROM空间和数据RAM空间 */ +/* 这里的子程序是通过括号中的变量传递参数,如果参数较多,为了节约RAM,也可以参考CH375子程序库改成通过同一全局变量/联合结构CH376_CMD_DATA传递 */ + +/* name 参数是指短文件名, 可以包括根目录符, 但不含有路径分隔符, 总长度不超过1+8+1+3+1字节 */ +/* PathName 参数是指全路径的短文件名, 包括根目录符、多级子目录及路径分隔符、文件名/目录名 */ +/* LongName 参数是指长文件名, 以UNICODE小端顺序编码, 以两个0字节结束, 使用长文件名子程序必须先定义全局缓冲区GlobalBuf, 长度不小于64字节, 可以与其它子程序共用 */ + +/* 定义 NO_DEFAULT_CH376_INT 用于禁止默认的Wait376Interrupt子程序,禁止后,应用程序必须自行定义一个同名子程序 */ +/* 定义 DEF_INT_TIMEOUT 用于设置默认的Wait376Interrupt子程序中的等待中断的超时时间/循环计数值, 0则不检查超时而一直等待 */ +/* 定义 EN_DIR_CREATE 用于提供新建多级子目录的子程序,默认是不提供 */ +/* 定义 EN_DISK_QUERY 用于提供磁盘容量查询和剩余空间查询的子程序,默认是不提供 */ +/* 定义 EN_SECTOR_ACCESS 用于提供以扇区为单位读写文件的子程序,默认是不提供 */ +/* 定义 EN_LONG_NAME 用于提供支持长文件名的子程序,默认是不提供 */ +/* 定义 DEF_IC_V43_U 用于去掉支持低版本的程序代码,仅支持V4.3及以上版本的CH376芯片,默认是支持低版本 */ + +#if 0 +#define DEF_IC_V43_U 1 /* 推荐定义 DEF_IC_V43_U 以优化代码 */ +#endif + +#include "k210_ch376.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ +static int fd; + +/* 串口方式未用到 */ +void xEndCH376Cmd(void) +{ +} + +void xWriteCH376Cmd( UINT8 cmd ) { /* 向CH376的命令端口写入命令,周期不小于2uS,如果单片机较快则延时 */ + UINT8 temp[3]; + temp[0] = 0x57; + temp[1] = 0xab; + temp[2] = cmd; + up_udelay(5); + write(fd, temp, 3); +} + +//写数据 +void xWriteCH376Data( UINT8 dat ) { /* 向CH376的数据端口写入数据,周期不小于1uS,如果单片机较快则延时 */ + 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 ); +} + +/* 查询CH376中断(INT#低电平) */ +UINT8 Query376Interrupt( void ) +{ + //产生中断的同时,串口会收到一个数据,直接读出来丢掉 + if(xReadCH376Data() == ERR_USB_UNKNOWN) return FALSE ; + else return TRUE ; +} + +/* CH376初始化代码 */ +UINT8 mInitCH376Host( void ) /* 初始化CH376 */ +{ + UINT8 res; + up_mdelay(50); /* 上电后至少延时50ms操作 */ + fd = open("/dev/ttyS3", O_RDWR); + up_mdelay(600); + xWriteCH376Cmd( CMD11_CHECK_EXIST ); /* 测试单片机与CH376之间的通讯接口 */ + xWriteCH376Data( 0x65 ); + res = xReadCH376Data( ); + xEndCH376Cmd( ); + if ( res != 0x9A ) return( ERR_USB_UNKNOWN ); /* 通讯接口不正常,可能原因有:接口连接异常,其它设备影响(片选不唯一),串口波特率,一直在复位,晶振不工作 */ + + xWriteCH376Cmd( CMD11_SET_USB_MODE ); /* 设备USB工作模式 */ + xWriteCH376Data( 0x06 ); + up_udelay( 20 ); + res = xReadCH376Data( ); + xEndCH376Cmd( ); + if ( res == CMD_RET_SUCCESS ) return( USB_INT_SUCCESS ); + else return( ERR_USB_UNKNOWN ); /* 设置模式错误 */ + +} + +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 ); +} + +void CH376WriteHostBlock( PUINT8 buf, UINT8 len ) /* 向USB主机端点的发送缓冲区写入数据块 */ +{ + xWriteCH376Cmd( CMD10_WR_HOST_DATA ); + xWriteCH376Data( len ); /* 长度 */ + if ( len ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + xEndCH376Cmd( ); +} + +void CH376WriteOfsBlock( PUINT8 buf, UINT8 ofs, UINT8 len ) /* 向内部缓冲区指定偏移地址写入数据块 */ +{ + xWriteCH376Cmd( CMD20_WR_OFS_DATA ); + xWriteCH376Data( ofs ); /* 偏移地址 */ + xWriteCH376Data( len ); /* 长度 */ + if ( len ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + xEndCH376Cmd( ); +} + +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; + if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) c = 0; /* 强行将文件名截止 */ + xWriteCH376Data( c ); + } + xEndCH376Cmd( ); +} + +UINT32 CH376Read32bitDat( void ) /* 从CH376芯片读取32位的数据并结束命令 */ +{ + 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 ) /* 读CH376芯片内部的8位变量 */ +{ + UINT8 c0; + xWriteCH376Cmd( CMD11_READ_VAR8 ); + xWriteCH376Data( var ); + c0 = xReadCH376Data( ); + xEndCH376Cmd( ); + return( c0 ); +} + +void CH376WriteVar8( UINT8 var, UINT8 dat ) /* 写CH376芯片内部的8位变量 */ +{ + xWriteCH376Cmd( CMD20_WRITE_VAR8 ); + xWriteCH376Data( var ); + xWriteCH376Data( dat ); + xEndCH376Cmd( ); +} + +UINT32 CH376ReadVar32( UINT8 var ) /* 读CH376芯片内部的32位变量 */ +{ + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( var ); + return( CH376Read32bitDat( ) ); /* 从CH376芯片读取32位的数据并结束命令 */ +} + +void CH376WriteVar32( UINT8 var, UINT32 dat ) /* 写CH376芯片内部的32位变量 */ +{ + 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 ) /* 在调用CH376DirInfoRead获取FAT_DIR_INFO结构之后应该通知CH376结束 */ +{ + 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 ) /* 等待CH376中断(INT#低电平),返回中断状态码, 超时则返回ERR_USB_UNKNOWN */ +{ +#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( ) ); /* 检测到中断 */ +/* 在等待CH376中断的过程中,可以做些需要及时处理的其它事情 */ + } + return( ERR_USB_UNKNOWN ); /* 不应该发生的情况 */ +#endif +#else + UINT32 i; + for ( i = 0; i < 5000000; i ++ ) { /* 计数防止超时,默认的超时时间,与单片机主频有关 */ + if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) ); /* 检测到中断 */ +/* 在等待CH376中断的过程中,可以做些需要及时处理的其它事情 */ + } + 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 ) /* 检查USB存储器错误 */ +{ + UINT8 s; + up_mdelay( 5 ); + s = CH376SendCmdWaitInt( CMD0H_DISK_R_SENSE ); + up_mdelay( 5 ); + return( s ); +} + +UINT8 CH376DiskConnect( void ) /* 检查U盘是否连接,不支持SD卡 */ +{ + 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 ) /* 打开多级目录下的文件或者目录的上级目录,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ +/* 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 ); /* 路径结束,USB_INT_SUCCESS为成功打开文件,ERR_OPEN_DIR为成功打开目录(文件夹),其它为操作出错 */ + } +} + +UINT8 CH376FileOpenPath( PUINT8 PathName ) /* 打开多级目录下的文件或者目录(文件夹),支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ +{ + return( CH376FileOpenDir( PathName, 0xFF ) ); +} + +UINT8 CH376FileCreatePath( PUINT8 PathName ) /* 新建多级目录下的文件,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ +{ + 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 ) /* 新建多级目录下的目录(文件夹)并打开,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ +{ + 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 ); /* 写入上级目录的起始簇号的高16位 */ + 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 ); /* 写入上级目录的起始簇号的低16位 */ + 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 ) { /* 参考CH376INC.H文件中CH376_CMD_DATA结构的DiskCapacity */ + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.DiskCapacity) */ + *DiskCap = CH376Read32bitDat( ); /* CH376_CMD_DATA.DiskCapacity.mDiskSizeSec,从CH376芯片读取32位的数据并结束命令 */ + } + 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 ) { /* 参考CH376INC.H文件中CH376_CMD_DATA结构的DiskQuery */ + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.DiskQuery) */ + xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mTotalSector */ + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + c0 = xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mFreeSector */ + c1 = xReadCH376Data( ); + c2 = xReadCH376Data( ); + c3 = xReadCH376Data( ); + *DiskFre = c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24; + xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mDiskFat */ + 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 ) /* 从U盘读取多个扇区的数据块到缓冲区,不支持SD卡 */ +/* iLbaStart 是准备读取的线性起始扇区号, iSectorCount 是准备读取的扇区数 */ +{ + UINT8 s, err; + UINT16 mBlockCount; + for ( err = 0; err != 3; ++ err ) { /* 出错重试 */ + xWriteCH376Cmd( CMD5H_DISK_READ ); /* 从USB存储器读扇区 */ + xWriteCH376Data( (UINT8)iLbaStart ); /* LBA的最低8位 */ + xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */ + xWriteCH376Data( iSectorCount ); /* 扇区数 */ + xEndCH376Cmd( ); + for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) { /* 数据块计数 */ + s = Wait376Interrupt( ); /* 等待中断并获取状态 */ + if ( s == USB_INT_DISK_READ ) { /* USB存储器读数据块,请求数据读出 */ + s = CH376ReadBlock( buf ); /* 从当前主机端点的接收缓冲区读取数据块,返回长度 */ + xWriteCH376Cmd( CMD0H_DISK_RD_GO ); /* 继续执行USB存储器的读操作 */ + 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 ); /* U盘被移除 */ + CH376DiskReqSense( ); /* 检查USB存储器错误 */ + } + return( s ); /* 操作失败 */ +} + +UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ) /* 将缓冲区中的多个扇区的数据块写入U盘,不支持SD卡 */ +/* iLbaStart 是写入的线起始性扇区号, iSectorCount 是写入的扇区数 */ +{ + UINT8 s, err; + UINT16 mBlockCount; + for ( err = 0; err != 3; ++ err ) { /* 出错重试 */ + xWriteCH376Cmd( CMD5H_DISK_WRITE ); /* 向USB存储器写扇区 */ + xWriteCH376Data( (UINT8)iLbaStart ); /* LBA的最低8位 */ + xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) ); + xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */ + xWriteCH376Data( iSectorCount ); /* 扇区数 */ + xEndCH376Cmd( ); + for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) { /* 数据块计数 */ + s = Wait376Interrupt( ); /* 等待中断并获取状态 */ + if ( s == USB_INT_DISK_WRITE ) { /* USB存储器写数据块,请求数据写入 */ + CH376WriteHostBlock( buf, CH376_DAT_BLOCK_LEN ); /* 向USB主机端点的发送缓冲区写入数据块 */ + xWriteCH376Cmd( CMD0H_DISK_WR_GO ); /* 继续执行USB存储器的写操作 */ + 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 ); /* U盘被移除 */ + CH376DiskReqSense( ); /* 检查USB存储器错误 */ + } + return( s ); /* 操作失败 */ +} + +UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇区为单位从当前位置读取数据块,不支持SD卡 */ +{ + 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( ); /* 长度总是sizeof(CH376_CMD_DATA.SectorRead) */ + cnt = xReadCH376Data( ); /* CH376_CMD_DATA.SectorRead.mSectorCount */ + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + StaSec = CH376Read32bitDat( ); /* CH376_CMD_DATA.SectorRead.mStartSector,从CH376芯片读取32位的数据并结束命令 */ + if ( cnt == 0 ) break; + s = CH376DiskReadSec( buf, StaSec, cnt ); /* 从U盘读取多个扇区的数据块到缓冲区 */ + 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 ) /* 以扇区为单位在当前位置写入数据块,不支持SD卡 */ +{ + 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( ); /* 长度总是sizeof(CH376_CMD_DATA.SectorWrite) */ + cnt = xReadCH376Data( ); /* CH376_CMD_DATA.SectorWrite.mSectorCount */ + xReadCH376Data( ); + xReadCH376Data( ); + xReadCH376Data( ); + StaSec = CH376Read32bitDat( ); /* CH376_CMD_DATA.SectorWrite.mStartSector,从CH376芯片读取32位的数据并结束命令 */ + if ( cnt == 0 ) break; + s = CH376DiskWriteSec( buf, StaSec, cnt ); /* 将缓冲区中的多个扇区的数据块写入U盘 */ + 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 ); /* 填充0 */ + } + xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); + xEndCH376Cmd( ); + } +/* else if ( s == USB_INT_SUCCESS ) return( s );*/ /* 结束 */ + else { +#ifndef DEF_IC_V43_U + if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, c ); +#endif + return( s ); /* 错误 */ + } + } +} + +UINT8 CH376CheckNameSum( PUINT8 DirName ) /* 计算长文件名的短文件名检验和,输入为无小数点分隔符的固定11字节格式 */ +{ + 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 ) /* 在上级目录(文件夹)中移动文件指针到当前文件目录信息所在的扇区 */ +/* 另外,顺便将当前文件目录信息所在的扇区的前一个扇区的LBA地址写入CH376内部VAR_FAT_DIR_LBA变量(为了方便收集长文件名时向前搜索,否则要多移动一次) */ +/* 使用了全局缓冲区GlobalBuf的前12个字节 */ +{ + UINT8 s; + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( VAR_FAT_DIR_LBA ); /* 当前文件目录信息所在的扇区LBA地址 */ + for ( s = 4; s != 8; s ++ ) GlobalBuf[ s ] = xReadCH376Data( ); /* 临时保存于全局缓冲区中,节约RAM */ + xEndCH376Cmd( ); + s = CH376SeparatePath( PathName ); /* 从路径中分离出最后一级文件名或者目录名,返回最后一级文件名或者目录名的偏移 */ + if ( s ) s = CH376FileOpenDir( PathName, s ); /* 是多级目录,打开多级目录下的最后一级目录,即打开文件的上级目录 */ + else s = CH376FileOpen( "/" ); /* 根目录下的文件,则打开根目录 */ + if ( s != ERR_OPEN_DIR ) return( s ); + *(PUINT32)(&GlobalBuf[0]) = 0; /* 目录扇区偏移扇区数,保存在全局缓冲区中,节约RAM */ + while ( 1 ) { /* 不断移动文件指针,直到与当前文件目录信息所在的扇区LBA地址匹配 */ + s = CH376SecLocate( *(PUINT32)(&GlobalBuf[0]) ); /* 以扇区为单位在上级目录中移动文件指针 */ + if ( s != USB_INT_SUCCESS ) return( s ); + CH376ReadBlock( &GlobalBuf[8] ); /* 从内存缓冲区读取CH376_CMD_DATA.SectorLocate.mSectorLba数据块,返回长度总是sizeof(CH376_CMD_DATA.SectorLocate) */ + if ( *(PUINT32)(&GlobalBuf[8]) == *(PUINT32)(&GlobalBuf[4]) ) return( USB_INT_SUCCESS ); /* 已到当前文件目录信息扇区 */ + xWriteCH376Cmd( CMD50_WRITE_VAR32 ); + xWriteCH376Data( VAR_FAT_DIR_LBA ); /* 得到前一个扇区,设置为新的文件目录信息扇区LBA地址 */ + for ( s = 8; s != 12; s ++ ) xWriteCH376Data( GlobalBuf[ s ] ); + xEndCH376Cmd( ); + ++ *(PUINT32)(&GlobalBuf[0]); + } +} + +UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName ) /* 由短文件名或者目录(文件夹)名获得相应的长文件名 */ +/* 需要输入短文件名的完整路径PathName,需要提供缓冲区接收长文件名LongName(以UNICODE小端编码,以双0结束) */ +/* 使用了全局缓冲区GlobalBuf的前34个字节,sizeof(GlobalBuf)>=sizeof(FAT_DIR_INFO)+2 */ +{ + UINT8 s; + UINT16 NameCount; /* 长文件名字节计数 */ + s = CH376FileOpenPath( PathName ); /* 打开多级目录下的文件或者目录 */ + if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s ); + s = CH376DirInfoRead( ); /* 读取当前文件的目录信息FAT_DIR_INFO,将相关数据调到内存中 */ + if ( s != USB_INT_SUCCESS ) return( s ); + CH376ReadBlock( GlobalBuf ); /* 从内存缓冲区读取FAT_DIR_INFO数据块,返回长度总是sizeof(FAT_DIR_INFO) */ + CH376EndDirInfo( ); /* 获取完FAT_DIR_INFO结构 */ + GlobalBuf[32] = CH376CheckNameSum( GlobalBuf ); /* 计算长文件名的短文件名检验和,保存在全局缓冲区中,节约RAM */ + GlobalBuf[33] = CH376ReadVar8( VAR_FILE_DIR_INDEX ); /* 当前文件目录信息在扇区内的索引号,保存在全局缓冲区中,节约RAM */ + 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] ); /* 读取指定的目录信息FAT_DIR_INFO,将相关数据调到内存中 */ + if ( s != USB_INT_SUCCESS ) break; + CH376ReadBlock( GlobalBuf ); /* 从内存缓冲区读取FAT_DIR_INFO数据块,返回长度总是sizeof(FAT_DIR_INFO) */ + CH376EndDirInfo( ); /* 获取完FAT_DIR_INFO结构 */ + 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 ) { /* 收集长文件名,长文件名的字符在磁盘上UNICODE用小端方式存放 */ + if ( s == 1 + 5 * 2 ) s = 14; /* 从长文件名的第一组1-5个字符跳到第二组6-11个字符 */ + else if ( s == 14 + 6 * 2 ) s = 28; /* 从长文件名的第二组6-11个字符跳到第三组12-13个字符 */ + 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 ) /* 新建具有长文件名的文件,关闭文件后返回,LongName输入路径必须在RAM中 */ +/* 需要输入短文件名的完整路径PathName(请事先参考FAT规范由长文件名自行产生),需要输入以UNICODE小端编码的以双0结束的长文件名LongName */ +/* 使用了全局缓冲区GlobalBuf的前64个字节,sizeof(GlobalBuf)>=sizeof(FAT_DIR_INFO)*2 */ +{ + 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; /* 加上0结束符后的长度 */ + i += 2; + if ( i < LONG_NAME_PER_DIR ) { /* 最末的文件目录结构不满 */ + while ( i++ < LONG_NAME_PER_DIR ) LongName[count++] = 0xFF; /* 把剩余数据填为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 ); /* 以字节为单位读取数据,获得当前文件的目录信息FAT_DIR_INFO */ + if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; + for ( i = DirBlockCnt; i != 0; -- i ) { /* 搜索空闲的文件目录结构用于存放长文件名 */ + s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count ); /* 以字节为单位读取数据,获得下一个文件目录信息FAT_DIR_INFO */ + 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 ); /* 以字节为单位读取数据,获得下一个文件目录信息FAT_DIR_INFO */ + 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 ) { /* FAT12/FAT16的根目录,容量是固定的,无法增加文件目录结构 */ + s = ERR_FDT_OVER; /* FAT12/FAT16根目录下的文件数应该少于512个,需要磁盘整理 */ + goto CH376CreateLongNameE; + } + count = s * DEF_SECTOR_SIZE; /* 每簇字节数 */ + if ( count < i * sizeof(FAT_DIR_INFO) ) count <<= 1; /* 一簇不够则增加一簇,这种情况只会发生于每簇为512字节的情况下 */ + s = CH376LongNameWrite( NULL, count ); /* 以字节为单位向当前位置写入全0数据块,清空新增加的文件目录簇 */ + 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 ) { /* 输出长文件名,长文件名的字符在磁盘上UNICODE用小端方式存放 */ + if ( s == 1 + 5 * 2 ) s = 14; /* 从长文件名的第一组1-5个字符跳到第二组6-11个字符 */ + else if ( s == 14 + 6 * 2 ) s = 28; /* 从长文件名的第二组6-11个字符跳到第三组12-13个字符 */ + 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 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h new file mode 100644 index 000000000..f87a8169a --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h @@ -0,0 +1,118 @@ +/* +* 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 xidatong-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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "k210_uart_16550.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 ); +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 ); +UINT8 CH376DiskCapacity( PUINT32 DiskCap ); +UINT8 CH376DiskQuery( PUINT32 DiskFre ); +UINT8 CH376SecLocate( UINT32 offset ); +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 From 540c9a84d55cb16c6175dfb42bb1c07989cadd59 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 10 Oct 2022 16:23:42 +0800 Subject: [PATCH 05/18] add esp8285 wifi on nuttx for xidatong-riscv64 --- .../Framework/connection/wifi/Kconfig | 8 + .../Framework/connection/wifi/adapter_wifi.c | 20 + .../connection/wifi/esp8285_wifi/Kconfig | 10 + .../connection/wifi/esp8285_wifi/Make.defs | 6 + .../connection/wifi/esp8285_wifi/Makefile | 7 + .../wifi/esp8285_wifi/esp8285_wifi.c | 589 ++++++++++++++++++ .../app_match_nuttx/apps/nshlib/nsh.h | 2 +- .../apps/nshlib/nsh_Applicationscmd.c | 2 +- .../app_match_nuttx/apps/nshlib/nsh_command.c | 2 +- 9 files changed, 643 insertions(+), 3 deletions(-) create mode 100644 APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig create mode 100644 APP_Framework/Framework/connection/wifi/esp8285_wifi/Make.defs create mode 100644 APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile create mode 100644 APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c diff --git a/APP_Framework/Framework/connection/wifi/Kconfig b/APP_Framework/Framework/connection/wifi/Kconfig index 9afa7bf28..fcc6b31d2 100644 --- a/APP_Framework/Framework/connection/wifi/Kconfig +++ b/APP_Framework/Framework/connection/wifi/Kconfig @@ -8,6 +8,14 @@ if ADAPTER_HFA21_WIFI source "$APP_DIR/Framework/connection/wifi/hfa21_wifi/Kconfig" endif +config ADAPTER_ESP8285_WIFI + bool "Using wifi adapter device esp8285" + default n + +if ADAPTER_ESP8285_WIFI + source "$APP_DIR/Framework/connection/wifi/esp8285_wifi/Kconfig" +endif + config ADAPTER_ESP07S_WIFI bool "Using wifi adapter device esp07s" default n diff --git a/APP_Framework/Framework/connection/wifi/adapter_wifi.c b/APP_Framework/Framework/connection/wifi/adapter_wifi.c index a42942ac6..a6866f5d8 100644 --- a/APP_Framework/Framework/connection/wifi/adapter_wifi.c +++ b/APP_Framework/Framework/connection/wifi/adapter_wifi.c @@ -31,6 +31,10 @@ extern AdapterProductInfoType Hfa21WifiAttach(struct Adapter *adapter); extern AdapterProductInfoType Esp07sWifiAttach(struct Adapter *adapter); #endif +#ifdef ADAPTER_ESP8285_WIFI +extern AdapterProductInfoType Esp8285WifiAttach(struct Adapter *adapter); +#endif + static int AdapterWifiRegister(struct Adapter *adapter) { int ret = 0; @@ -94,11 +98,27 @@ int AdapterWifiInit(void) adapter->info = product_info; adapter->done = product_info->model_done; +#endif + + +#ifdef ADAPTER_ESP8285_WIFI + AdapterProductInfoType product_info = Esp8285WifiAttach(adapter); + if (!product_info) { + printf("AdapterWifiInit ESP8285 attach error\n"); + PrivFree(adapter); + return -1; + } + + adapter->product_info_flag = 1; + adapter->info = product_info; + adapter->done = product_info->model_done; + #endif return ret; } + /******************wifi TEST*********************/ #ifdef ADD_XIZI_FETURES int AdapterWifiTest(void) diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig new file mode 100644 index 000000000..4b3b5b8d9 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig @@ -0,0 +1,10 @@ +config ADAPTER_WIFI_ESP8285 + string "ESP8285 WIFI adapter name" + default "esp8285_wifi" + +if ADD_NUTTX_FETURES + config ADAPTER_ESP8285_DRIVER + string "ESP8285 device uart driver path" + default "/dev/ttyS2" +endif + diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Make.defs b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Make.defs new file mode 100644 index 000000000..2c5d833a3 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Make.defs @@ -0,0 +1,6 @@ +############################################################################ +# APP_Framework/Framework/connection/wifi/esp8285/Make.defs +############################################################################ +ifneq ($(CONFIG_ADAPTER_ESP8285_WIFI),) +CONFIGURED_APPS += $(APPDIR)/../../../APP_Framework/Framework/connection/wifi/esp8285_wifi +endif diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile new file mode 100644 index 000000000..c1ee6bd29 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Makefile @@ -0,0 +1,7 @@ +include $(KERNEL_ROOT)/.config +ifeq ($(CONFIG_ADD_NUTTX_FETURES),y) + include $(APPDIR)/Make.defs + CSRCS += esp8285_wifi.c + include $(APPDIR)/Application.mk + +endif diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c b/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c new file mode 100644 index 000000000..07a050333 --- /dev/null +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/esp8285_wifi.c @@ -0,0 +1,589 @@ +/* +* 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 esp07_wifi.c + * @brief Implement the connection wifi adapter function, using ESP8285 device + * @version 1.1 + * @author AIIT XUOS Lab + * @date 2022.04.08 + */ + +#include +#include +#include "../adapter_wifi.h" +#include + +#define LEN_PARA_BUF 128 + +static int Esp8285WifiSetDown(struct Adapter *adapter_at); + +/** + * @description: check AT startup status + * @param at_agent - wifi device agent pointer + * @return success: EOK + */ +static int Esp8285WifiTestAtCmd(ATAgentType at_agent) +{ + int ret = 0; + + ret = AtCmdConfigAndCheck(at_agent, "ATE0\r\n", "OK"); ///< close echo function + if(ret < 0) { + printf("%s %d cmd[ATE0] config failed!\n",__func__,__LINE__); + ret = -1; + } + + PrivTaskDelay(2000); + ret = AtCmdConfigAndCheck(at_agent, "AT\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd[AT] config failed!\n",__func__,__LINE__); + ret = -1; + } + return ret; +} + +static int Esp8285UartOpen(struct Adapter *adapter) +{ + if (NULL == adapter) { + return -1; + } + + /* Open device in read-write mode */ + adapter->fd = PrivOpen(ADAPTER_ESP8285_DRIVER, O_RDWR); + if (adapter->fd < 0) { + printf("Esp8285WifiOpen get serial %s fd error\n", ADAPTER_ESP8285_DRIVER); + return -1; + } + /* set serial config, serial_baud_rate = 115200 */ + + struct SerialDataCfg cfg; + memset(&cfg, 0 ,sizeof(struct SerialDataCfg)); + + cfg.serial_baud_rate = BAUD_RATE_115200; + cfg.serial_data_bits = DATA_BITS_8; + cfg.serial_stop_bits = STOP_BITS_1; + cfg.serial_parity_mode = PARITY_NONE; + cfg.serial_bit_order = BIT_ORDER_LSB; + cfg.serial_invert_mode = NRZ_NORMAL; + cfg.serial_buffer_size = SERIAL_RB_BUFSZ; + cfg.is_ext_uart = 0; +#ifdef ADAPTER_ESP8285_DRIVER_EXT_PORT + cfg.is_ext_uart = 1; + cfg.ext_uart_no = ADAPTER_ESP8285_DRIVER_EXT_PORT; + cfg.port_configure = PORT_CFG_INIT; +#endif + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; + ioctl_cfg.args = &cfg; + + PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg); + PrivTaskDelay(1000); + + printf("esp8285 uart config ready\n"); + return 0; +} + +/** + * @description: Open wifi + * @param adapter - wifi device pointer + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiOpen(struct Adapter *adapter) +{ + /*step1: open esp8285 serial port*/ + Esp8285UartOpen(adapter); + + /*step2: init AT agent*/ + if (!adapter->agent) { + char *agent_name = "wifi_uart_client"; + if (EOK != InitATAgent(agent_name, adapter->fd, 512)) { + printf("at agent init failed !\n"); + return -1; + } + ATAgentType at_agent = GetATAgent(agent_name); + + adapter->agent = at_agent; + } + + AtSetReplyEndChar(adapter->agent,'O','K'); + + ADAPTER_DEBUG("Esp8285Wifi open done\n"); + + return 0; +} + +/** + * @description: Close wifi + * @param adapter - wifi device pointer + * @return success: EOK + */ +static int Esp8285WifiClose(struct Adapter *adapter) +{ + Esp8285WifiSetDown(adapter); + PrivClose(adapter->fd); + return 0; +} + +/** + * @description: send data to adapter + * @param adapter - wifi device pointer + * @param data - data buffer + * @param data - data length + * @return success: EOK + */ +static int Esp8285WifiSend(struct Adapter *adapter, const void *data, size_t len) +{ + x_err_t result = EOK; + if (adapter->agent) { + EntmSend(adapter->agent, (const char *)data, len); + }else { + printf("Esp8285WifiSend can not find agent!\n"); + } + + return result; +} + +/** + * @description: receive data from adapter + * @param adapter - wifi device pointer + * @param data - data buffer + * @param data - data length + * @return success: EOK + */ +static int Esp8285WifiReceive(struct Adapter *adapter, void *rev_buffer, size_t buffer_len) +{ + x_err_t result = EOK; + printf("esp8285 receive waiting ... \n"); + + if (adapter->agent) { + return EntmRecv(adapter->agent, (char *)rev_buffer, buffer_len, 40); + } else { + printf("Esp8285WifiReceive can not find agent!\n"); + } + + return result; +} + +/** + * @description: connnect wifi to internet + * @param adapter - wifi device pointer + * @return success: EOK + */ +static int Esp8285WifiSetUp(struct Adapter *adapter) +{ + char cmd[LEN_PARA_BUF]; + int ret = 0; + char *result = NULL; + + struct WifiParam *param = (struct WifiParam *)adapter->adapter_param; + struct ATAgent *agent = adapter->agent; + + PrivTaskDelay(2000); + + if(Esp8285WifiTestAtCmd(agent) < 0) + { + printf("wifi at cmd startup failed.\n"); + return -1; + } + PrivTaskDelay(2000); + /* config as softAP+station mode */ + ret = AtCmdConfigAndCheck(agent, "AT+CWMODE=3\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd[AT+CWMODE=3] config failed!\n",__func__,__LINE__); + return -1; + } + PrivTaskDelay(2000); + /* connect the router */ + memset(cmd,0,sizeof(cmd)); + strncpy(cmd,"AT+CWJAP=",strlen("AT+CWJAP=")); + strncat(cmd,"\"",1); + strncat(cmd,param->wifi_ssid,strlen(param->wifi_ssid)); + + strncat(cmd,"\"",1); + strncat(cmd,",",1); + strncat(cmd,"\"",1); + strncat(cmd,param->wifi_pwd,strlen(param->wifi_pwd)); + + strncat(cmd,"\"",1); + strcat(cmd,"\r\n"); + + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d cmd[%s] connect[%s] failed!\n",__func__,__LINE__,cmd,param->wifi_ssid); + return -1; + } + + /* check the wifi ip address */ + ATReplyType reply = CreateATReply(256); + if (NULL == reply) { + printf("%s %d at_create_resp failed!\n",__func__,__LINE__); + return -1; + } + ret = ATOrderSend(agent, REPLY_TIME_OUT, reply, "AT+CIFSR\r\n"); + if(ret < 0){ + printf("%s %d ATOrderSend AT+CIFSR failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + + result = GetReplyText(reply); + if (!result) { + printf("%s %n get reply failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + printf("[%s]\n", result); + +__exit: + DeleteATReply(reply); + + return ret; +} + +/** + * @description: disconnnect wifi from internet + * @param adapter - wifi device pointer + * @return success: EOK + */ +static int Esp8285WifiSetDown(struct Adapter *adapter) +{ + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+RESTORE\r\n"); + PrivTaskDelay(2000); + + return 0; +} + +/** + * @description: set wifi ip/gateway/netmask address(in sta mode) + * @param adapter - wifi device pointer + * @param ip - ip address + * @param gateway - gateway address + * @param netmask - netmask address + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiSetAddr(struct Adapter *adapter, const char *ip, const char *gateway, const char *netmask) +{ + int ret = 0; + char cmd[LEN_PARA_BUF]; + + /* e.g. AT+CIPSTA_DEF="192.168.6.100","192.168.6.1","255.255.255.0" */ + memset(cmd,0,sizeof(cmd)); + strncpy(cmd,"AT+CIPAP_DEF=",strlen(" AT+CIPAP_DEF=")); + strncat(cmd,"\"",1); + strncat(cmd,ip,strlen(ip)); + strncat(cmd,"\"",1); + strncat(cmd,",",1); + strncat(cmd,"\"",1); + strncat(cmd,gateway,strlen(gateway)); + strncat(cmd,"\"",1); + strncat(cmd,",",1); + strncat(cmd,"\"",1); + strncat(cmd,netmask,strlen(netmask)); + strncat(cmd,"\"",1); + strcat(cmd,"\r\n"); + + ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d cmd[%s] config ip failed!\n",__func__,__LINE__,cmd); + return -1; + } + + return 0; +} + +/** + * @description: wifi ping function + * @param adapter - wifi device pointer + * @param destination - domain name or ip address + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiPing(struct Adapter *adapter, const char *destination) +{ + char cmd[LEN_PARA_BUF]; + int ret = 0; + + memset(cmd,0,sizeof(cmd)); + strncpy(cmd,"AT+PING=",strlen("AT+PING=")); + strncat(cmd,"\"",1); + strncat(cmd,destination,strlen(destination)); + strncat(cmd,"\"",1); + strcat(cmd,"\r\n"); + + ret = AtCmdConfigAndCheck(adapter->agent, cmd, "OK"); ///< config as softAP+station mode + if(ret < 0) { + printf("%s %d ping [%s] failed!\n",__func__,__LINE__,destination); + return -1; + } + + printf("ping [%s] ok\n", destination); + + return 0; +} + +/** + * @description: display wifi network configuration + * @param adapter - wifi device pointer + * @return success: EOK, failure: ENOMEMORY + */ +static int Esp8285WifiNetstat(struct Adapter *adapter) +{ + int ret = 0; + char *result = NULL; + + /* check the wifi ip address */ + ATReplyType reply = CreateATReply(256); + if (NULL == reply) { + printf("%s %d at_create_resp failed!\n",__func__,__LINE__); + return -1; + } + ret = ATOrderSend(adapter->agent, REPLY_TIME_OUT, reply, "AT+CIFSR\r\n"); + if(ret < 0){ + printf("%s %d ATOrderSend AT+CIFSR failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + + result = GetReplyText(reply); + if (!result) { + printf("%s %n get reply failed.\n",__func__,__LINE__); + ret = -1; + goto __exit; + } + printf("[%s]\n", result); + +__exit: + DeleteATReply(reply); + + return ret; +} + +/** + * @description: wifi connect function + * @param adapter - wifi device pointer + * @param net_role - net role, CLIENT or SERVER + * @param ip - ip address + * @param port - port num + * @param ip_type - ip type, IPV4 or IPV6 + * @return success: 0, failure: -1 + */ +static int Esp8285WifiConnect(struct Adapter *adapter, enum NetRoleType net_role, const char *ip, const char *port, enum IpType ip_type) +{ + int ret = EOK; + char cmd[LEN_PARA_BUF]; + struct ATAgent *agent = adapter->agent; + + memset(cmd,0,sizeof(cmd)); + if(adapter->socket.protocal == SOCKET_PROTOCOL_TCP && net_role == CLIENT) //esp8285 as tcp client to connect server + { + //e.g. AT+CIPSTART="TCP","192.168.3.116",8080 protocol, server IP and port + strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART=")); + strncat(cmd,"\"",1); + strncat(cmd,"TCP",strlen("TCP")); + strncat(cmd,"\"",1); + strncat(cmd, ",", 1); + strncat(cmd,"\"",1); + strncat(cmd, ip, strlen(ip)); + strncat(cmd, "\"", 1); + strncat(cmd, ",", 1); + strncat(cmd, port, strlen(port)); + strcat(cmd,"\r\n"); + + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d tcp connect [%s] failed!\n",__func__,__LINE__,ip); + return -1; + } + } + else if(adapter->socket.protocal == SOCKET_PROTOCOL_UDP) + { + //e.g. AT+CIPSTART="UDP","192.168.3.116",8080,2233,0 UDP protocol, server IP, port,local port,udp mode + strncpy(cmd,"AT+CIPSTART=",strlen("AT+CIPSTART=")); + strncat(cmd,"\"",1); + strncat(cmd,"UDP",strlen("UDP")); + strncat(cmd,"\"",1); + strncat(cmd, ",", 1); + strncat(cmd,"\"",1); + strncat(cmd, ip, strlen(ip)); + strncat(cmd, "\"", 1); + strncat(cmd, ",", 1); + strncat(cmd, port, strlen(port)); + strncat(cmd, ",", 1); + strncat(cmd, "2233", strlen("2233")); ///< local port + strncat(cmd, ",", 1); + strncat(cmd, "0", 1); ///< udp transparent transmission mode must be 0 + strcat(cmd,"\r\n"); + + ret = AtCmdConfigAndCheck(agent, cmd, "OK"); + if(ret < 0) { + printf("%s %d udp connect [%s] failed!\n",__func__,__LINE__,ip); + return -1; + } + } + + ret = AtCmdConfigAndCheck(agent, "AT+CIPMODE=1\r\n", "OK"); ///< config as transparent transmission + if(ret < 0) { + printf("%s %d cmd[%s] config as transparent transmission failed!\n",__func__,__LINE__,cmd); + return -1; + } + ATOrderSend(agent, REPLY_TIME_OUT, NULL, "AT+CIPSEND\r\n"); + + printf("[%s] connection config as transparent transmission\n",adapter->socket.protocal == SOCKET_PROTOCOL_UDP ? "udp" : "tcp"); + adapter->net_role = net_role; + + return 0; +} + +/** + * @description: wifi disconnect function + * @param adapter - wifi device pointer + * @return success: 0, failure: -1 + */ +static int Esp8285WifiDisconnect(struct Adapter *adapter) +{ + int ret = EOK; + char cmd[LEN_PARA_BUF]; + struct ATAgent *agent = adapter->agent; + memset(cmd,0,sizeof(cmd)); + + /* step1: stop transparent transmission mode */ + ATOrderSend(agent, REPLY_TIME_OUT, NULL, "+++\r\n"); + + /* step2: exit transparent transmission mode */ + ret = AtCmdConfigAndCheck(agent, "AT+CIPMODE=0\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd[AT+CIPMODE=0] exit failed!\n",__func__,__LINE__); + return -1; + } + + /* step3: disconnect */ + ret = AtCmdConfigAndCheck(agent, "AT+CIPCLOSE\r\n", "OK"); + if(ret < 0) { + printf("%s %d cmd [AT+CIPCLOSE] disconnect failed!\n",__func__,__LINE__); + return -1; + } + + return 0; +} + +static int Esp8285WifiIoctl(struct Adapter *adapter, int cmd, void *args) +{ + int32_t ret = 0; + char baud_str[LEN_PARA_BUF]; + struct SerialDataCfg cfg; + char at_cmd[LEN_PARA_BUF]; + uint32_t baud_rate = 0 ; + + switch (cmd) + { + case CONFIG_WIFI_RESET: /* reset wifi */ + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+RST\r\n"); + break; + case CONFIG_WIFI_RESTORE: /* resore wifi */ + ATOrderSend(adapter->agent, REPLY_TIME_OUT, NULL, "AT+RESTORE\r\n"); + break; + case CONFIG_WIFI_BAUDRATE: + /* step1: config mcu uart*/ + baud_rate = *((uint32_t *)args); + + memset(at_cmd, 0, sizeof(at_cmd)); + memset(baud_str, 0, sizeof(baud_str)); + memset(&cfg, 0 ,sizeof(struct SerialDataCfg)); + + cfg.serial_baud_rate = baud_rate; + cfg.serial_data_bits = DATA_BITS_8; + cfg.serial_stop_bits = STOP_BITS_1; + cfg.serial_parity_mode = PARITY_NONE; + cfg.serial_bit_order = BIT_ORDER_LSB; + cfg.serial_invert_mode = NRZ_NORMAL; + cfg.serial_buffer_size = SERIAL_RB_BUFSZ; + cfg.is_ext_uart = 0; +#ifdef ADAPTER_ESP8285_DRIVER_EXT_PORT + cfg.is_ext_uart = 1; + cfg.ext_uart_no = ADAPTER_ESP8285_DRIVER_EXT_PORT; + cfg.port_configure = PORT_CFG_INIT; +#endif + + struct PrivIoctlCfg ioctl_cfg; + ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; + ioctl_cfg.args = &cfg; + + PrivIoctl(adapter->fd, OPE_INT, &ioctl_cfg); + + /* step2: config wifi uart*/ + itoa(baud_rate, baud_str, 10); + + strncpy(at_cmd, "AT+UART_DEF=", strlen("AT+UART_DEF=")); + strncat(at_cmd, baud_str, strlen(baud_str)); + strncat(at_cmd, ",", 1); + strncat(at_cmd, "8", 1); + strncat(at_cmd, ",", 1); + strncat(at_cmd, "1", 1); + strncat(at_cmd, ",", 1); + strncat(at_cmd, "0", 1); + strncat(at_cmd, ",", 1); + strncat(at_cmd, "3", 1); + strcat(at_cmd,"\r\n"); + + ret = AtCmdConfigAndCheck(adapter->agent, at_cmd, "OK"); + if(ret < 0) { + printf("%s %d cmd [%s] config uart failed!\n",__func__,__LINE__,at_cmd); + ret = -1; + } + + break; + default: + ret = -1; + break; + } + + return ret; +} + +static const struct IpProtocolDone esp8285_wifi_done = +{ + .open = Esp8285WifiOpen, + .close = Esp8285WifiClose, + .ioctl = Esp8285WifiIoctl, + .setup = Esp8285WifiSetUp, + .setdown = Esp8285WifiSetDown, + .setaddr = Esp8285WifiSetAddr, + .setdns = NULL, + .setdhcp = NULL, + .ping = Esp8285WifiPing, + .netstat = Esp8285WifiNetstat, + .connect = Esp8285WifiConnect, + .send = Esp8285WifiSend, + .recv = Esp8285WifiReceive, + .disconnect = Esp8285WifiDisconnect, +}; + +/** + * @description: Register wifi device esp8285 + * @return success: EOK, failure: ERROR + */ +AdapterProductInfoType Esp8285WifiAttach(struct Adapter *adapter) +{ + struct AdapterProductInfo *product_info = PrivMalloc(sizeof(struct AdapterProductInfo)); + if (!product_info) + { + printf("Esp8285WifiAttach Attach malloc product_info error\n"); + PrivFree(product_info); + return NULL; + } + + strncpy(product_info->model_name, ADAPTER_WIFI_ESP8285, strlen(ADAPTER_WIFI_ESP8285)); + + product_info->model_done = (void *)&esp8285_wifi_done; + + return product_info; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h index df3e0f488..a54df4a9c 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h @@ -1556,7 +1556,7 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, int cmd_AdapterBlueToothTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif -#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index ef6d6b2be..65507a192 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -313,7 +313,7 @@ int cmd_recvzigbee(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif -#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) extern int AdapterWifiTest(int argc, char *argv[]); int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c index 7f542859b..5dbd550c6 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c @@ -701,7 +701,7 @@ static const struct cmdmap_s g_cmdmap[] = { "AdapterBlueToothTest", cmd_AdapterBlueToothTest, 1, 1, "[BlueTooth hc08 test.]" }, #endif -#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) { "wifitest", cmd_AdapterWifiTest, 1, 8, "[WIFI test.]" }, #endif From 0f1d2a4868c357c2af4b1a1eaf9fb10f90f01977 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 11 Oct 2022 21:16:40 +0800 Subject: [PATCH 06/18] add ch376 usb demo on xidatong-riscv64 --- .../aiit_board/xidatong-riscv64/Kconfig | 21 + .../aiit_board/xidatong-riscv64/src/Makefile | 6 +- .../xidatong-riscv64/src/ch376_demo.c | 68 + .../xidatong-riscv64/src/ch376inc.h | 1252 ++++++----------- .../xidatong-riscv64/src/k210_ch376.c | 1120 ++++++++------- .../xidatong-riscv64/src/k210_ch376.h | 130 +- .../app_match_nuttx/apps/nshlib/Kconfig | 4 + .../app_match_nuttx/apps/nshlib/nsh.h | 4 + .../apps/nshlib/nsh_Applicationscmd.c | 13 + .../app_match_nuttx/apps/nshlib/nsh_command.c | 4 + 10 files changed, 1193 insertions(+), 1429 deletions(-) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig index 56405367b..90cfa7ee5 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig @@ -5,6 +5,27 @@ if ARCH_BOARD_XIDATONG_RISCV64 +menuconfig BSP_USING_CH376 + bool "Using ch376 device" + default n + select K210_16550_UART + select K210_16550_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 + +endif # BSP_USING_CH376 + menuconfig BSP_USING_CH438 bool "Using CH438 device" default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile index 3258528d7..90a9d8f65 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile @@ -20,7 +20,7 @@ include $(TOPDIR)/Make.defs -CSRCS = k210_bringup.c k210_boot.c k210_ch376.c +CSRCS = k210_bringup.c k210_boot.c ifeq ($(CONFIG_BOARDCTL_RESET),y) CSRCS += k210_reset.c @@ -46,4 +46,8 @@ ifeq ($(CONFIG_BSP_USING_CH438),y) CSRCS += k210_ch438.c ch438_demo.c endif +ifeq ($(CONFIG_BSP_USING_CH376),y) +CSRCS += k210_ch376.c ch376_demo.c +endif + include $(TOPDIR)/boards/Board.mk diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c new file mode 100644 index 000000000..d4302842a --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c @@ -0,0 +1,68 @@ +/* +* 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 xidatong-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); + + printf( "Wait Udisk/SD\n" ); + while ( CH376DiskConnect( ) != USB_INT_SUCCESS ) + { + up_mdelay( 100 ); + } + + 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 演示数据\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 ); +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h index 63d757a73..ec8a4d08f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376inc.h @@ -25,896 +25,554 @@ extern "C" { #endif -/* ********************************************************************************************************************* */ -/* 常用类型和常量定义 */ +/* Common types and constant definitions */ -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 #endif -#ifndef NULL -#define NULL 0 +#ifndef NULL +#define NULL 0 #endif #ifndef UINT8 -typedef unsigned char UINT8; +typedef unsigned char UINT8; #endif #ifndef UINT16 -typedef unsigned short UINT16; +typedef unsigned short UINT16; #endif #ifndef UINT32 -typedef unsigned long UINT32; +typedef unsigned long UINT32; #endif #ifndef PUINT8 -typedef unsigned char *PUINT8; +typedef unsigned char *PUINT8; #endif #ifndef PUINT16 -typedef unsigned short *PUINT16; +typedef unsigned short *PUINT16; #endif #ifndef PUINT32 -typedef unsigned long *PUINT32; +typedef unsigned long *PUINT32; #endif #ifndef UINT8V -typedef unsigned char volatile UINT8V; +typedef unsigned char volatile UINT8V; #endif #ifndef PUINT8V -typedef unsigned char volatile *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 /* ********************************************************************************************************************* */ -/* 硬件特性 */ - -#define CH376_DAT_BLOCK_LEN 0x40 /* USB单个数据包, 数据块的最大长度, 默认缓冲区的长度 */ - -/* ********************************************************************************************************************* */ -/* 命令代码 */ -/* 部分命令兼容CH375芯片, 但是输入数据或者输出数据的可能局部不同) */ -/* 一个命令操作顺序包含: - 一个命令码(对于串口方式,命令码之前还需要两个同步码), - 若干个输入数据(可以是0个), - 产生中断通知 或者 若干个输出数据(可以是0个), 二选一, 有中断通知则一定没有输出数据, 有输出数据则一定不产生中断 - 仅CMD01_WR_REQ_DATA命令例外, 顺序包含: 一个命令码, 一个输出数据, 若干个输入数据 - 命令码起名规则: CMDxy_NAME - 其中的x和y都是数字, x说明最少输入数据个数(字节数), y说明最少输出数据个数(字节数), y如果是H则说明产生中断通知, - 有些命令能够实现0到多个字节的数据块读写, 数据块本身的字节数未包含在上述x或y之内 */ -/* 本文件默认会同时提供与CH375芯片命令码兼容的命令码格式(即去掉x和y之后), 如果不需要, 那么可以定义_NO_CH375_COMPATIBLE_禁止 */ - -/* ********************************************************************************************************************* */ -/* 主要命令(手册一), 常用 */ - -#define CMD01_GET_IC_VER 0x01 /* 获取芯片及固件版本 */ -/* 输出: 版本号( 位7为0, 位6为1, 位5~位0为版本号 ) */ -/* CH376返回版本号的值为041H即版本号为01H */ - -#define CMD21_SET_BAUDRATE 0x02 /* 串口方式: 设置串口通讯波特率(上电或者复位后的默认波特率为9600bps,由D4/D5/D6引脚选择) */ -/* 输入: 波特率分频系数, 波特率分频常数 */ -/* 输出: 操作状态( CMD_RET_SUCCESS或CMD_RET_ABORT, 其它值说明操作未完成 ) */ - -#define CMD00_ENTER_SLEEP 0x03 /* 进入睡眠状态 */ - -#define CMD00_RESET_ALL 0x05 /* 执行硬件复位 */ - -#define CMD11_CHECK_EXIST 0x06 /* 测试通讯接口和工作状态 */ -/* 输入: 任意数据 */ -/* 输出: 输入数据的按位取反 */ - -#define CMD20_CHK_SUSPEND 0x0B /* 设备方式: 设置检查USB总线挂起状态的方式 */ -/* 输入: 数据10H, 检查方式 */ -/* 00H=不检查USB挂起, 04H=以50mS为间隔检查USB挂起, 05H=以10mS为间隔检查USB挂起 */ - -#define CMD20_SET_SDO_INT 0x0B /* SPI接口方式: 设置SPI的SDO引脚的中断方式 */ -/* 输入: 数据16H, 中断方式 */ -/* 10H=禁止SDO引脚用于中断输出,在SCS片选无效时三态输出禁止, 90H=SDO引脚在SCS片选无效时兼做中断请求输出 */ - -#define CMD14_GET_FILE_SIZE 0x0C /* 主机文件模式: 获取当前文件长度 */ -/* 输入: 数据68H */ -/* 输出: 当前文件长度(总长度32位,低字节在前) */ - -#define CMD50_SET_FILE_SIZE 0x0D /* 主机文件模式: 设置当前文件长度 */ -/* 输入: 数据68H, 当前文件长度(总长度32位,低字节在前) */ - -#define CMD11_SET_USB_MODE 0x15 /* 设置USB工作模式 */ -/* 输入: 模式代码 */ -/* 00H=未启用的设备方式, 01H=已启用的设备方式并且使用外部固件模式(串口不支持), 02H=已启用的设备方式并且使用内置固件模式 */ -/* 03H=SD卡主机模式/未启用的主机模式,用于管理和存取SD卡中的文件 */ -/* 04H=未启用的主机方式, 05H=已启用的主机方式, 06H=已启用的主机方式并且自动产生SOF包, 07H=已启用的主机方式并且复位USB总线 */ -/* 输出: 操作状态( CMD_RET_SUCCESS或CMD_RET_ABORT, 其它值说明操作未完成 ) */ - -#define CMD01_GET_STATUS 0x22 /* 获取中断状态并取消中断请求 */ -/* 输出: 中断状态 */ - -#define CMD00_UNLOCK_USB 0x23 /* 设备方式: 释放当前USB缓冲区 */ - -#define CMD01_RD_USB_DATA0 0x27 /* 从当前USB中断的端点缓冲区或者主机端点的接收缓冲区读取数据块 */ -/* 输出: 长度, 数据流 */ - -#define CMD01_RD_USB_DATA 0x28 /* 设备方式: 从当前USB中断的端点缓冲区读取数据块, 并释放缓冲区, 相当于 CMD01_RD_USB_DATA0 + CMD00_UNLOCK_USB */ -/* 输出: 长度, 数据流 */ - -#define CMD10_WR_USB_DATA7 0x2B /* 设备方式: 向USB端点2的发送缓冲区写入数据块 */ -/* 输入: 长度, 数据流 */ - -#define CMD10_WR_HOST_DATA 0x2C /* 向USB主机端点的发送缓冲区写入数据块 */ -/* 输入: 长度, 数据流 */ - -#define CMD01_WR_REQ_DATA 0x2D /* 向内部指定缓冲区写入请求的数据块 */ -/* 输出: 长度 */ -/* 输入: 数据流 */ - -#define CMD20_WR_OFS_DATA 0x2E /* 向内部缓冲区指定偏移地址写入数据块 */ -/* 输入: 偏移, 长度, 数据流 */ - -#define CMD10_SET_FILE_NAME 0x2F /* 主机文件模式: 设置将要操作的文件的文件名 */ -/* 输入: 以0结束的字符串(含结束符0在内长度不超过14个字符) */ - -/* ********************************************************************************************************************* */ -/* 主要命令(手册一), 常用, 以下命令总是在操作结束时产生中断通知, 并且总是没有输出数据 */ - -#define CMD0H_DISK_CONNECT 0x30 /* 主机文件模式/不支持SD卡: 检查磁盘是否连接 */ -/* 输出中断 */ - -#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 /* 主机文件模式: 关闭当前已经打开的文件或者目录(文件夹) */ -/* 输入: 是否允许更新文件长度 */ -/* 00H=禁止更新长度, 01H=允许更新长度 */ -/* 输出中断 */ - -#define CMD1H_DIR_INFO_READ 0x37 /* 主机文件模式: 读取文件的目录信息 */ -/* 输入: 指定需要读取的目录信息结构在扇区内的索引号 */ -/* 索引号范围为00H~0FH, 索引号0FFH则为当前已经打开的文件 */ -/* 输出中断 */ - -#define CMD0H_DIR_INFO_SAVE 0x38 /* 主机文件模式: 保存文件的目录信息 */ -/* 输出中断 */ - -#define CMD4H_BYTE_LOCATE 0x39 /* 主机文件模式: 以字节为单位移动当前文件指针 */ -/* 输入: 偏移字节数(总长度32位,低字节在前) */ -/* 输出中断 */ - -#define CMD2H_BYTE_READ 0x3A /* 主机文件模式: 以字节为单位从当前位置读取数据块 */ -/* 输入: 请求读取的字节数(总长度16位,低字节在前) */ -/* 输出中断 */ - -#define CMD0H_BYTE_RD_GO 0x3B /* 主机文件模式: 继续字节读 */ -/* 输出中断 */ - -#define CMD2H_BYTE_WRITE 0x3C /* 主机文件模式: 以字节为单位向当前位置写入数据块 */ -/* 输入: 请求写入的字节数(总长度16位,低字节在前) */ -/* 输出中断 */ - -#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 /* 主机文件模式: 以扇区为单位移动当前文件指针 */ -/* 输入: 偏移扇区数(总长度32位,低字节在前) */ -/* 输出中断 */ - -#define CMD1H_SEC_READ 0x4B /* 主机文件模式/不支持SD卡: 以扇区为单位从当前位置读取数据块 */ -/* 输入: 请求读取的扇区数 */ -/* 输出中断 */ - -#define CMD1H_SEC_WRITE 0x4C /* 主机文件模式/不支持SD卡: 以扇区为单位在当前位置写入数据块 */ -/* 输入: 请求写入的扇区数 */ -/* 输出中断 */ - -#define CMD0H_DISK_BOC_CMD 0x50 /* 主机方式/不支持SD卡: 对USB存储器执行BulkOnly传输协议的命令 */ -/* 输出中断 */ - -#define CMD5H_DISK_READ 0x54 /* 主机方式/不支持SD卡: 从USB存储器读物理扇区 */ -/* 输入: LBA物理扇区地址(总长度32位, 低字节在前), 扇区数(01H~FFH) */ -/* 输出中断 */ - -#define CMD0H_DISK_RD_GO 0x55 /* 主机方式/不支持SD卡: 继续执行USB存储器的物理扇区读操作 */ -/* 输出中断 */ - -#define CMD5H_DISK_WRITE 0x56 /* 主机方式/不支持SD卡: 向USB存储器写物理扇区 */ -/* 输入: LBA物理扇区地址(总长度32位, 低字节在前), 扇区数(01H~FFH) */ -/* 输出中断 */ - -#define CMD0H_DISK_WR_GO 0x57 /* 主机方式/不支持SD卡: 继续执行USB存储器的物理扇区写操作 */ -/* 输出中断 */ - -/* ********************************************************************************************************************* */ -/* 辅助命令(手册二), 不太常用或者是为了与CH375和CH372兼容 */ - -#define CMD10_SET_USB_SPEED 0x04 /* 设置USB总线速度, 在每次CMD11_SET_USB_MODE设置USB工作模式时会自动恢复到12Mbps全速 */ -/* 输入: 总线速度代码 */ -/* 00H=12Mbps全速FullSpeed(默认值), 01H=1.5Mbps(仅修改频率), 02H=1.5Mbps低速LowSpeed */ - -#define CMD11_GET_DEV_RATE 0x0A /* 主机方式: 获取当前连接的USB设备的数据速率类型 */ -/* 输入: 数据07H */ -/* 输出: 数据速率类型 */ -/* 位4为1则是1.5Mbps低速USB设备, 否则是12Mbps全速USB设备 */ - -#define CMD11_GET_TOGGLE 0x0A /* 获取OUT事务的同步状态 */ -/* 输入: 数据1AH */ -/* 输出: 同步状态 */ -/* 位4为1则OUT事务同步, 否则OUT事务不同步 */ - -#define CMD11_READ_VAR8 0x0A /* 读取指定的8位文件系统变量 */ -/* 输入: 变量地址 */ -/* 输出: 数据 */ - -/*#define CMD11_GET_MAX_LUN = CMD11_READ_VAR8( VAR_UDISK_LUN )*/ /* 主机方式: 获取USB存储器最大和当前逻辑单元号 */ - -#define CMD20_SET_RETRY 0x0B /* 主机方式: 设置USB事务操作的重试次数 */ -/* 输入: 数据25H, 重试次数 */ -/* 位7为0则收到NAK时不重试, 位7为1位6为0则收到NAK时无限重试, 位7为1位6为1则收到NAK时最多重试3秒, 位5~位0为超时后的重试次数 */ - -#define CMD20_WRITE_VAR8 0x0B /* 设置指定的8位文件系统变量 */ -/* 输入: 变量地址, 数据 */ - -/*#define CMD20_SET_DISK_LUN = CMD20_WRITE_VAR8( VAR_UDISK_LUN )*/ /* 主机方式: 设置USB存储器的当前逻辑单元号 */ - -#define CMD14_READ_VAR32 0x0C /* 读取指定的32位文件系统变量 */ -/* 输入: 变量地址 */ -/* 输出: 数据(总长度32位,低字节在前) */ - -#define CMD50_WRITE_VAR32 0x0D /* 设置指定的32位文件系统变量 */ -/* 输入: 变量地址, 数据(总长度32位,低字节在前) */ - -#define CMD01_DELAY_100US 0x0F /* 延时100uS(串口不支持) */ -/* 输出: 延时期间输出0,延时结束输出非0 */ - -#define CMD40_SET_USB_ID 0x12 /* 设备方式: 设置USB厂商VID和产品PID */ -/* 输入: 厂商ID低字节, 厂商ID高字节, 产品ID低字节, 产品ID高字节 */ - -#define CMD10_SET_USB_ADDR 0x13 /* 设置USB地址 */ -/* 输入: 地址值 */ - -#define CMD01_TEST_CONNECT 0x16 /* 主机方式/不支持SD卡: 检查USB设备连接状态 */ -/* 输出: 状态( USB_INT_CONNECT或USB_INT_DISCONNECT或USB_INT_USB_READY, 其它值说明操作未完成 ) */ - -#define CMD00_ABORT_NAK 0x17 /* 主机方式: 放弃当前NAK的重试 */ - -#define CMD10_SET_ENDP2 0x18 /* 设备方式(串口不支持): 设置USB端点0的接收器 */ -/* 输入: 工作方式 */ -/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ -/* 位3~位0为事务响应方式: 0000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ - -#define CMD10_SET_ENDP3 0x19 /* 设备方式(串口不支持): 设置USB端点0的发送器 */ -/* 输入: 工作方式 */ -/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ -/* 位3~位0为事务响应方式: 0000~1000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ - -#define CMD10_SET_ENDP4 0x1A /* 设备方式(串口不支持): 设置USB端点1的接收器 */ -/* 输入: 工作方式 */ -/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ -/* 位3~位0为事务响应方式: 0000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ - -#define CMD10_SET_ENDP5 0x1B /* 设备方式(串口不支持): 设置USB端点1的发送器 */ -/* 输入: 工作方式 */ -/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ -/* 位3~位0为事务响应方式: 0000~1000-就绪ACK, 1110-正忙NAK, 1111-错误STALL */ - -#define CMD10_SET_ENDP6 0x1C /* 设置USB端点2/主机端点的接收器 */ -/* 输入: 工作方式 */ -/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ -/* 位3~位0为事务响应方式: 0000-就绪ACK, 1101-就绪但不返回ACK, 1110-正忙NAK, 1111-错误STALL */ - -#define CMD10_SET_ENDP7 0x1D /* 设置USB端点2/主机端点的发送器 */ -/* 输入: 工作方式 */ -/* 位7为1则位6为同步触发位, 否则同步触发位不变 */ -/* 位3~位0为事务响应方式: 0000-就绪ACK, 1101-就绪但无须应答, 1110-正忙NAK, 1111-错误STALL */ - -#define CMD00_DIRTY_BUFFER 0x25 /* 主机文件模式: 清除内部的磁盘和文件缓冲区 */ - -#define CMD10_WR_USB_DATA3 0x29 /* 设备方式(串口不支持): 向USB端点0的发送缓冲区写入数据块 */ -/* 输入: 长度, 数据流 */ - -#define CMD10_WR_USB_DATA5 0x2A /* 设备方式(串口不支持): 向USB端点1的发送缓冲区写入数据块 */ -/* 输入: 长度, 数据流 */ - -/* ********************************************************************************************************************* */ -/* 辅助命令(手册二), 不太常用或者是为了与CH375和CH372兼容, 以下命令总是在操作结束时产生中断通知, 并且总是没有输出数据 */ - -#define CMD1H_CLR_STALL 0x41 /* 主机方式: 控制传输-清除端点错误 */ -/* 输入: 端点号 */ -/* 输出中断 */ - -#define CMD1H_SET_ADDRESS 0x45 /* 主机方式: 控制传输-设置USB地址 */ -/* 输入: 地址值 */ -/* 输出中断 */ - -#define CMD1H_GET_DESCR 0x46 /* 主机方式: 控制传输-获取描述符 */ -/* 输入: 描述符类型 */ -/* 输出中断 */ - -#define CMD1H_SET_CONFIG 0x49 /* 主机方式: 控制传输-设置USB配置 */ -/* 输入: 配置值 */ -/* 输出中断 */ - -#define CMD0H_AUTO_SETUP 0x4D /* 主机方式/不支持SD卡: 自动配置USB设备 */ -/* 输出中断 */ - -#define CMD2H_ISSUE_TKN_X 0x4E /* 主机方式: 发出同步令牌, 执行事务, 该命令可代替 CMD10_SET_ENDP6/CMD10_SET_ENDP7 + CMD1H_ISSUE_TOKEN */ -/* 输入: 同步标志, 事务属性 */ -/* 同步标志的位7为主机端点IN的同步触发位, 位6为主机端点OUT的同步触发位, 位5~位0必须为0 */ -/* 事务属性的低4位是令牌, 高4位是端点号 */ -/* 输出中断 */ - -#define CMD1H_ISSUE_TOKEN 0x4F /* 主机方式: 发出令牌, 执行事务, 建议用CMD2H_ISSUE_TKN_X命令 */ -/* 输入: 事务属性 */ -/* 低4位是令牌, 高4位是端点号 */ -/* 输出中断 */ - -#define CMD0H_DISK_INIT 0x51 /* 主机方式/不支持SD卡: 初始化USB存储器 */ -/* 输出中断 */ - -#define CMD0H_DISK_RESET 0x52 /* 主机方式/不支持SD卡: 控制传输-复位USB存储器 */ -/* 输出中断 */ - -#define CMD0H_DISK_SIZE 0x53 /* 主机方式/不支持SD卡: 获取USB存储器的容量 */ -/* 输出中断 */ - -#define CMD0H_DISK_INQUIRY 0x58 /* 主机方式/不支持SD卡: 查询USB存储器特性 */ -/* 输出中断 */ - -#define CMD0H_DISK_READY 0x59 /* 主机方式/不支持SD卡: 检查USB存储器就绪 */ -/* 输出中断 */ - -#define CMD0H_DISK_R_SENSE 0x5A /* 主机方式/不支持SD卡: 检查USB存储器错误 */ -/* 输出中断 */ - -#define CMD0H_RD_DISK_SEC 0x5B /* 主机文件模式: 从磁盘读取一个扇区的数据到内部缓冲区 */ -/* 输出中断 */ - -#define CMD0H_WR_DISK_SEC 0x5C /* 主机文件模式: 将内部缓冲区的一个扇区的数据写入磁盘 */ -/* 输出中断 */ - -#define CMD0H_DISK_MAX_LUN 0x5D /* 主机方式: 控制传输-获取USB存储器最大逻辑单元号 */ -/* 输出中断 */ - -/* ********************************************************************************************************************* */ -/* 以下定义只是为了兼容CH375的INCLUDE文件中的命令名称格式 */ - -#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 +#ifndef PARA_STATE_INTB +#define PARA_STATE_INTB 0x80 +#define PARA_STATE_BUSY 0x10 #endif -/* ********************************************************************************************************************* */ -/* 并口方式, 状态端口(读命令端口)的位定义 */ -#ifndef PARA_STATE_INTB -#define PARA_STATE_INTB 0x80 /* 并口方式状态端口的位7: 中断标志,低有效 */ -#define PARA_STATE_BUSY 0x10 /* 并口方式状态端口的位4: 忙标志,高有效 */ +#ifndef SER_CMD_TIMEOUT +#define SER_CMD_TIMEOUT 32 +#define SER_SYNC_CODE1 0x57 +#define SER_SYNC_CODE2 0xAB #endif -/* ********************************************************************************************************************* */ -/* 串口方式, 操作命令前的引导同步码 */ -#ifndef SER_CMD_TIMEOUT -#define SER_CMD_TIMEOUT 32 /* 串口命令超时时间, 单位为mS, 同步码之间及同步码与命令码之间的间隔应该尽量短, 超时后的处理方式为丢弃 */ -#define SER_SYNC_CODE1 0x57 /* 启动操作的第1个串口同步码 */ -#define SER_SYNC_CODE2 0xAB /* 启动操作的第2个串口同步码 */ +#ifndef CMD_RET_SUCCESS +#define CMD_RET_SUCCESS 0x51 +#define CMD_RET_ABORT 0x5F #endif -/* ********************************************************************************************************************* */ -/* 操作状态 */ +/***********************************************************************************************************************/ +#ifndef USB_INT_EP0_SETUP -#ifndef CMD_RET_SUCCESS -#define CMD_RET_SUCCESS 0x51 /* 命令操作成功 */ -#define CMD_RET_ABORT 0x5F /* 命令操作失败 */ -#endif - -/* ********************************************************************************************************************* */ -/* USB中断状态 */ - -#ifndef USB_INT_EP0_SETUP - -/* 以下状态代码为特殊事件中断, 如果通过CMD20_CHK_SUSPEND启用USB总线挂起检查, 那么必须处理USB总线挂起和睡眠唤醒的中断状态 */ -#define USB_INT_USB_SUSPEND 0x05 /* USB总线挂起事件 */ -#define USB_INT_WAKE_UP 0x06 /* 从睡眠中被唤醒事件 */ - -/* 以下状态代码0XH用于USB设备方式 */ -/* 内置固件模式下只需要处理: USB_INT_EP1_OUT, USB_INT_EP1_IN, USB_INT_EP2_OUT, USB_INT_EP2_IN */ -/* 位7-位4为0000 */ -/* 位3-位2指示当前事务, 00=OUT, 10=IN, 11=SETUP */ -/* 位1-位0指示当前端点, 00=端点0, 01=端点1, 10=端点2, 11=USB总线复位 */ -#define USB_INT_EP0_SETUP 0x0C /* USB端点0的SETUP */ -#define USB_INT_EP0_OUT 0x00 /* USB端点0的OUT */ -#define USB_INT_EP0_IN 0x08 /* USB端点0的IN */ -#define USB_INT_EP1_OUT 0x01 /* USB端点1的OUT */ -#define USB_INT_EP1_IN 0x09 /* USB端点1的IN */ -#define USB_INT_EP2_OUT 0x02 /* USB端点2的OUT */ -#define USB_INT_EP2_IN 0x0A /* USB端点2的IN */ -/* USB_INT_BUS_RESET 0x0000XX11B */ /* USB总线复位 */ -#define USB_INT_BUS_RESET1 0x03 /* USB总线复位 */ -#define USB_INT_BUS_RESET2 0x07 /* USB总线复位 */ -#define USB_INT_BUS_RESET3 0x0B /* USB总线复位 */ -#define USB_INT_BUS_RESET4 0x0F /* USB总线复位 */ +#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 -/* 以下状态代码2XH-3XH用于USB主机方式的通讯失败代码 */ -/* 位7-位6为00 */ -/* 位5为1 */ -/* 位4指示当前接收的数据包是否同步 */ -/* 位3-位0指示导致通讯失败时USB设备的应答: 0010=ACK, 1010=NAK, 1110=STALL, 0011=DATA0, 1011=DATA1, XX00=超时 */ -/* USB_INT_RET_ACK 0x001X0010B */ /* 错误:对于IN事务返回ACK */ -/* USB_INT_RET_NAK 0x001X1010B */ /* 错误:返回NAK */ -/* USB_INT_RET_STALL 0x001X1110B */ /* 错误:返回STALL */ -/* USB_INT_RET_DATA0 0x001X0011B */ /* 错误:对于OUT/SETUP事务返回DATA0 */ -/* USB_INT_RET_DATA1 0x001X1011B */ /* 错误:对于OUT/SETUP事务返回DATA1 */ -/* USB_INT_RET_TOUT 0x001XXX00B */ /* 错误:返回超时 */ -/* USB_INT_RET_TOGX 0x0010X011B */ /* 错误:对于IN事务返回数据不同步 */ -/* USB_INT_RET_PID 0x001XXXXXB */ /* 错误:未定义 */ -/* 以下状态代码1XH用于USB主机方式的操作状态代码 */ -#ifndef USB_INT_SUCCESS -#define USB_INT_SUCCESS 0x14 /* USB事务或者传输操作成功 */ -#define USB_INT_CONNECT 0x15 /* 检测到USB设备连接事件, 可能是新连接或者断开后重新连接 */ -#define USB_INT_DISCONNECT 0x16 /* 检测到USB设备断开事件 */ -#define USB_INT_BUF_OVER 0x17 /* USB传输的数据有误或者数据太多缓冲区溢出 */ -#define USB_INT_USB_READY 0x18 /* USB设备已经被初始化(已经分配USB地址) */ -#define USB_INT_DISK_READ 0x1D /* USB存储器请求数据读出 */ -#define USB_INT_DISK_WRITE 0x1E /* USB存储器请求数据写入 */ -#define USB_INT_DISK_ERR 0x1F /* USB存储器操作失败 */ +#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 /* 磁盘的扇区太大,只支持每扇区512字节 */ -#define ERR_TYPE_ERROR 0x92 /* 磁盘分区类型不支持,只支持FAT12/FAT16/BigDOS/FAT32,需要由磁盘管理工具重新分区 */ -#define ERR_BPB_ERROR 0xA1 /* 磁盘尚未格式化,或者参数错误,需要由WINDOWS采用默认参数重新格式化 */ -#define ERR_DISK_FULL 0xB1 /* 磁盘文件太满,剩余空间太少或者已经没有,需要磁盘整理 */ -#define ERR_FDT_OVER 0xB2 /* 目录(文件夹)内文件太多,没有空闲的目录项,FAT12/FAT16根目录下的文件数应该少于512个,需要磁盘整理 */ -#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 /* 同名的短文件已经存在,建议重新生成另外一个短文件名 */ +#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 -/* ********************************************************************************************************************* */ -/* 以下状态代码用于主机文件模式下的磁盘及文件状态, VAR_DISK_STATUS */ -#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 /* 已经打开根目录,使用后必须关闭,注意FAT12/FAT16根目录是固定长度 */ -#define DEF_DISK_OPEN_DIR 0x13 /* 已经打开子目录(文件夹) */ -#define DEF_DISK_OPEN_FILE 0x14 /* 已经打开文件 */ +/* **********************************************************************************************************************/ +#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 -#ifndef DEF_SECTOR_SIZE -#define DEF_SECTOR_SIZE 512 /* U盘或者SD卡默认的物理扇区的大小 */ -#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 /* 默认文件日期: 2004年 */ -#define DEF_FILE_MONTH 1 /* 默认文件日期: 1月 */ -#define DEF_FILE_DATE 1 /* 默认文件日期: 1日 */ -#endif - -#ifndef ATTR_DIRECTORY - -/* FAT数据区中文件目录信息 */ typedef struct _FAT_DIR_INFO { - UINT8 DIR_Name[11]; /* 00H,文件名,共11字节,不足处填空格 */ - UINT8 DIR_Attr; /* 0BH,文件属性,参考后面的说明 */ - UINT8 DIR_NTRes; /* 0CH */ - UINT8 DIR_CrtTimeTenth; /* 0DH,文件创建的时间,以0.1秒单位计数 */ - UINT16 DIR_CrtTime; /* 0EH,文件创建的时间 */ - UINT16 DIR_CrtDate; /* 10H,文件创建的日期 */ - UINT16 DIR_LstAccDate; /* 12H,最近一次存取操作的日期 */ - UINT16 DIR_FstClusHI; /* 14H */ - UINT16 DIR_WrtTime; /* 16H,文件修改时间,参考前面的宏MAKE_FILE_TIME */ - UINT16 DIR_WrtDate; /* 18H,文件修改日期,参考前面的宏MAKE_FILE_DATE */ - UINT16 DIR_FstClusLO; /* 1AH */ - UINT32 DIR_FileSize; /* 1CH,文件长度 */ -} FAT_DIR_INFO, *P_FAT_DIR_INFO; /* 20H */ + 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 ) -/* 文件属性 UINT8 */ -/* bit0 bit1 bit2 bit3 bit4 bit5 bit6 bit7 */ -/* 只 隐 系 卷 目 存 未定义 */ -/* 读 藏 统 标 录 档 */ -/* 文件时间 UINT16 */ -/* Time = (Hour<<11) + (Minute<<5) + (Second>>1) */ -#define MAKE_FILE_TIME( h, m, s ) ( (h<<11) + (m<<5) + (s>>1) ) /* 生成指定时分秒的文件时间数据 */ -/* 文件日期 UINT16 */ -/* Date = ((Year-1980)<<9) + (Month<<5) + Day */ -#define MAKE_FILE_DATE( y, m, d ) ( ((y-1980)<<9) + (m<<5) + d ) /* 生成指定年月日的文件日期数据 */ +#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 LONE_NAME_MAX_CHAR (255*2) /* 长文件名最多字符数/字节数 */ -#define LONG_NAME_PER_DIR (13*2) /* 长文件名在每个文件目录信息结构中的字符数/字节数 */ +#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 /* ********************************************************************************************************************* */ -/* SCSI命令和数据输入输出结构 */ - #ifndef SPC_CMD_INQUIRY -/* SCSI命令码 */ -#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 +#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 -/* BulkOnly协议的命令块 */ typedef struct _BULK_ONLY_CBW { - UINT32 CBW_Sig; - UINT32 CBW_Tag; - UINT8 CBW_DataLen0; /* 08H,输入: 数据传输长度,对于输入数据其有效值是0到48,对于输出数据其有效值为0到33 */ - UINT8 CBW_DataLen1; - UINT16 CBW_DataLen2; - UINT8 CBW_Flag; /* 0CH,输入: 传输方向等标志,位7为1则输入数据,位为0则输出数据或者没有数据 */ - UINT8 CBW_LUN; - UINT8 CBW_CB_Len; /* 0EH,输入: 命令块的长度,有效值是1到16 */ - UINT8 CBW_CB_Buf[16]; /* 0FH,输入: 命令块,该缓冲区最多为16个字节 */ -} BULK_ONLY_CBW, *P_BULK_ONLY_CBW; /* BulkOnly协议的命令块, 输入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; -/* INQUIRY命令的返回数据 */ typedef struct _INQUIRY_DATA { - UINT8 DeviceType; /* 00H, 设备类型 */ - UINT8 RemovableMedia; /* 01H, 位7为1说明是移动存储 */ - UINT8 Versions; /* 02H, 协议版本 */ - UINT8 DataFormatAndEtc; /* 03H, 指定返回数据格式 */ - UINT8 AdditionalLength; /* 04H, 后续数据的长度 */ - UINT8 Reserved1; - UINT8 Reserved2; - UINT8 MiscFlag; /* 07H, 一些控制标志 */ - UINT8 VendorIdStr[8]; /* 08H, 厂商信息 */ - UINT8 ProductIdStr[16]; /* 10H, 产品信息 */ - UINT8 ProductRevStr[4]; /* 20H, 产品版本 */ -} INQUIRY_DATA, *P_INQUIRY_DATA; /* 24H */ + 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; + -/* REQUEST SENSE命令的返回数据 */ typedef struct _SENSE_DATA { - UINT8 ErrorCode; /* 00H, 错误代码及有效位 */ - UINT8 SegmentNumber; - UINT8 SenseKeyAndEtc; /* 02H, 主键码 */ - UINT8 Information0; - UINT8 Information1; - UINT8 Information2; - UINT8 Information3; - UINT8 AdditSenseLen; /* 07H, 后续数据的长度 */ - UINT8 CmdSpecInfo[4]; - UINT8 AdditSenseCode; /* 0CH, 附加键码 */ - UINT8 AddSenCodeQual; /* 0DH, 详细的附加键码 */ - UINT8 FieldReplaUnit; - UINT8 SenseKeySpec[3]; -} SENSE_DATA, *P_SENSE_DATA; /* 12H */ + 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 -#ifndef MAX_FILE_NAME_LEN +#define MAX_FILE_NAME_LEN (13+1) -#define MAX_FILE_NAME_LEN (13+1) /* 文件名最大长度,最大长度是1个根目录符+8个主文件名+1个小数点+3个类型名+结束符=14 */ - -/* 命令的输入数据和输出数据 */ typedef union _CH376_CMD_DATA { - struct { - UINT8 mBuffer[ MAX_FILE_NAME_LEN ]; - } Default; + struct { + UINT8 mBuffer[ MAX_FILE_NAME_LEN ]; + } Default; - INQUIRY_DATA DiskMountInq; /* 返回: INQUIRY命令的返回数据 */ - /* CMD0H_DISK_MOUNT: 初始化磁盘并测试磁盘是否就绪,首次执行时 */ + INQUIRY_DATA DiskMountInq; + FAT_DIR_INFO OpenDirInfo; + FAT_DIR_INFO EnumDirInfo; + struct { + UINT8 mUpdateFileSz; + } FileCLose; - FAT_DIR_INFO OpenDirInfo; /* 返回: 枚举到的文件目录信息 */ - /* CMD0H_FILE_OPEN: 枚举文件和目录(文件夹) */ + struct { + UINT8 mDirInfoIndex; + } DirInfoRead; - FAT_DIR_INFO EnumDirInfo; /* 返回: 枚举到的文件目录信息 */ - /* CMD0H_FILE_ENUM_GO: 继续枚举文件和目录(文件夹) */ + union { + UINT32 mByteOffset; + UINT32 mSectorLba; + } ByteLocate; - struct { - UINT8 mUpdateFileSz; /* 输入参数: 是否允许更新文件长度, 0则禁止更新长度 */ - } FileCLose; /* CMD1H_FILE_CLOSE: 关闭当前已经打开的文件 */ + struct { + UINT16 mByteCount; + } ByteRead; - struct { - UINT8 mDirInfoIndex; /* 输入参数: 指定需要读取的目录信息结构在扇区内的索引号, 0FFH则为当前已经打开的文件 */ - } DirInfoRead; /* CMD1H_DIR_INFO_READ: 读取文件的目录信息 */ + struct { + UINT16 mByteCount; + } ByteWrite; - union { - UINT32 mByteOffset; /* 输入参数: 偏移字节数,以字节为单位的偏移量(总长度32位,低字节在前) */ - UINT32 mSectorLba; /* 返回: 当前文件指针对应的绝对线性扇区号,0FFFFFFFFH则已到文件尾(总长度32位,低字节在前) */ - } ByteLocate; /* CMD4H_BYTE_LOCATE: 以字节为单位移动当前文件指针 */ + union { + UINT32 mSectorOffset; + UINT32 mSectorLba; + } SectorLocate; - struct { - UINT16 mByteCount; /* 输入参数: 请求读取的字节数(总长度16位,低字节在前) */ - } ByteRead; /* CMD2H_BYTE_READ: 以字节为单位从当前位置读取数据块 */ + struct { + UINT8 mSectorCount; + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; + } SectorRead; - struct { - UINT16 mByteCount; /* 输入参数: 请求写入的字节数(总长度16位,低字节在前) */ - } ByteWrite; /* CMD2H_BYTE_WRITE: 以字节为单位向当前位置写入数据块 */ + struct { + UINT8 mSectorCount; + UINT8 mReserved1; + UINT8 mReserved2; + UINT8 mReserved3; + UINT32 mStartSector; +} SectorWrite; - union { - UINT32 mSectorOffset; /* 输入参数: 偏移扇区数,以扇区为单位的偏移量(总长度32位,低字节在前) */ - UINT32 mSectorLba; /* 返回: 当前文件指针对应的绝对线性扇区号,0FFFFFFFFH则已到文件尾(总长度32位,低字节在前) */ - } SectorLocate; /* CMD4H_SEC_LOCATE: 以扇区为单位移动当前文件指针 */ + struct { + UINT32 mDiskSizeSec; + } DiskCapacity; - struct { - UINT8 mSectorCount; /* 输入参数: 请求读取的扇区数 */ - /* 返回: 允许读取的扇区数 */ - UINT8 mReserved1; - UINT8 mReserved2; - UINT8 mReserved3; - UINT32 mStartSector; /* 返回: 允许读取的扇区块的起始绝对线性扇区号(总长度32位,低字节在前) */ - } SectorRead; /* CMD1H_SEC_READ: 以扇区为单位从当前位置读取数据块 */ + struct { + UINT32 mTotalSector; + UINT32 mFreeSector; + UINT8 mDiskFat; + } DiskQuery; - struct { - UINT8 mSectorCount; /* 输入参数: 请求写入的扇区数 */ - /* 返回: 允许写入的扇区数 */ - UINT8 mReserved1; - UINT8 mReserved2; - UINT8 mReserved3; - UINT32 mStartSector; /* 返回: 允许写入的扇区块的起始绝对线性扇区号(总长度32位,低字节在前) */ - } SectorWrite; /* CMD1H_SEC_WRITE: 以扇区为单位在当前位置写入数据块 */ + BULK_ONLY_CBW DiskBocCbw; - struct { - UINT32 mDiskSizeSec; /* 返回: 整个物理磁盘的总扇区数(总长度32位,低字节在前) */ - } DiskCapacity; /* CMD0H_DISK_CAPACITY: 查询磁盘物理容量 */ + struct { + UINT8 mMaxLogicUnit; + } DiskMaxLun; - struct { - UINT32 mTotalSector; /* 返回: 当前逻辑盘的总扇区数(总长度32位,低字节在前) */ - UINT32 mFreeSector; /* 返回: 当前逻辑盘的剩余扇区数(总长度32位,低字节在前) */ - UINT8 mDiskFat; /* 返回: 当前逻辑盘的FAT类型,1-FAT12,2-FAT16,3-FAT32 */ - } DiskQuery; /* CMD_DiskQuery, 查询磁盘信息 */ + INQUIRY_DATA DiskInitInq; + INQUIRY_DATA DiskInqData; + SENSE_DATA ReqSenseData; + struct { + UINT32 mDiskSizeSec; + } DiskSize; - BULK_ONLY_CBW DiskBocCbw; /* 输入参数: CBW命令结构 */ - /* CMD0H_DISK_BOC_CMD: 对USB存储器执行BulkOnly传输协议的命令 */ + struct { + UINT32 mStartSector; + UINT8 mSectorCount; + } DiskRead; - struct { - UINT8 mMaxLogicUnit; /* 返回: USB存储器的最大逻辑单元号 */ - } DiskMaxLun; /* CMD0H_DISK_MAX_LUN: 控制传输-获取USB存储器最大逻辑单元号 */ - - INQUIRY_DATA DiskInitInq; /* 返回: INQUIRY命令的返回数据 */ - /* CMD0H_DISK_INIT: 初始化USB存储器 */ - - INQUIRY_DATA DiskInqData; /* 返回: INQUIRY命令的返回数据 */ - /* CMD0H_DISK_INQUIRY: 查询USB存储器特性 */ - - SENSE_DATA ReqSenseData; /* 返回: REQUEST SENSE命令的返回数据 */ - /* CMD0H_DISK_R_SENSE: 检查USB存储器错误 */ - - struct { - UINT32 mDiskSizeSec; /* 返回: 整个物理磁盘的总扇区数(总长度32位,高字节在前) */ - } DiskSize; /* CMD0H_DISK_SIZE: 获取USB存储器的容量 */ - - struct { - UINT32 mStartSector; /* 输入参数: LBA扇区地址(总长度32位,低字节在前) */ - UINT8 mSectorCount; /* 输入参数: 请求读取的扇区数 */ - } DiskRead; /* CMD5H_DISK_READ: 从USB存储器读数据块(以扇区为单位) */ - - struct { - UINT32 mStartSector; /* 输入参数: LBA扇区地址(总长度32位,低字节在前) */ - UINT8 mSectorCount; /* 输入参数: 请求写入的扇区数 */ - } DiskWrite; /* CMD5H_DISK_WRITE: 向USB存储器写数据块(以扇区为单位) */ + struct { + UINT32 mStartSector; + UINT8 mSectorCount; + } DiskWrite; } CH376_CMD_DATA, *P_CH376_CMD_DATA; #endif /* ********************************************************************************************************************* */ -/* 主机文件模式下的文件系统变量的地址 */ -#ifndef VAR_FILE_SIZE +#ifndef VAR_FILE_SIZE -/* 8位/单字节变量 */ -#define VAR_SYS_BASE_INFO 0x20 /* 当前系统的基本信息 */ -/* 位6用于指示USB存储设备的子类别SubClass-Code, 位6为0则说明子类别为6, 位6为1则说明子类别是非6的其它值 */ -/* 位5用于指示USB设备方式下的USB配置状态和USB主机方式下的USB设备连接状态 */ -/* USB设备方式下, 位5为1则USB配置完成, 位5位0则尚未配置 */ -/* USB主机方式下, 位5为1则USB端口存在USB设备, 位5位0则USB端口没有USB设备 */ -/* 位4用于指示USB设备方式下的缓冲区锁定状态, 位4为1则说明USB缓冲区处于锁定状态, 位6为1则说明已经释放 */ -/* 其它位, 保留,请勿修改 */ -#define VAR_RETRY_TIMES 0x25 /* USB事务操作的重试次数 */ -/* 位7为0则收到NAK时不重试, 位7为1位6为0则收到NAK时无限重试(可以用CMD_ABORT_NAK命令放弃重试), 位7为1位6为1则收到NAK时最多重试3秒 */ -/* 位5~位0为超时后的重试次数 */ -#define VAR_FILE_BIT_FLAG 0x26 /* 主机文件模式下的位标志 */ -/* 位1和位0, 逻辑盘的FAT文件系统标志, 00-FAT12, 01-FAT16, 10-FAT32, 11-非法 */ -/* 位2, 当前缓冲区中的FAT表数据是否被修改标志, 0-未修改, 1-已修改 */ -/* 位3, 文件长度需要修改标志, 当前文件被追加数据, 0-未追加无需修改, 1-已追加需要修改 */ -/* 其它位, 保留,请勿修改 */ -#define VAR_DISK_STATUS 0x2B /* 主机文件模式下的磁盘及文件状态 */ -#define VAR_SD_BIT_FLAG 0x30 /* 主机文件模式下SD卡的位标志 */ -/* 位0, SD卡版本, 0-只支持SD第一版,1-支持SD第二版 */ -/* 位1, 自动识别, 0-SD卡, 1-MMC卡 */ -/* 位2, 自动识别, 0-标准容量SD卡, 1-大容量SD卡(HC-SD) */ -/* 位4, ACMD41命令超时 */ -/* 位5, CMD1命令超时 */ -/* 位6, CMD58命令超时 */ -/* 其它位, 保留,请勿修改 */ -#define VAR_UDISK_TOGGLE 0x31 /* USB存储设备的BULK-IN/BULK-OUT端点的同步标志 */ -/* 位7, Bulk-In端点的同步标志 */ -/* 位6, Bulk-In端点的同步标志 */ -/* 位5~位0, 必须为0 */ -#define VAR_UDISK_LUN 0x34 /* USB存储设备的逻辑单元号 */ -/* 位7~位4, USB存储设备的当前逻辑单元号,CH376初始化USB存储设备后,默认是访问0#逻辑单元 */ -/* 位3~位0, USB存储设备的最大逻辑单元号,加1后等于逻辑单元数 */ -#define VAR_SEC_PER_CLUS 0x38 /* 逻辑盘的每簇扇区数 */ -#define VAR_FILE_DIR_INDEX 0x3B /* 当前文件目录信息在扇区内的索引号 */ -#define VAR_CLUS_SEC_OFS 0x3C /* 当前文件指针在簇内的扇区偏移,为0xFF则指向文件末尾,簇结束 */ +#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 -/* 32位/4字节变量 */ -#define VAR_DISK_ROOT 0x44 /* 对于FAT16盘为根目录占用扇区数,对于FAT32盘为根目录起始簇号(总长度32位,低字节在前) */ -#define VAR_DSK_TOTAL_CLUS 0x48 /* 逻辑盘的总簇数(总长度32位,低字节在前) */ -#define VAR_DSK_START_LBA 0x4C /* 逻辑盘的起始绝对扇区号LBA(总长度32位,低字节在前) */ -#define VAR_DSK_DAT_START 0x50 /* 逻辑盘的数据区域的起始LBA(总长度32位,低字节在前) */ -#define VAR_LBA_BUFFER 0x54 /* 当前磁盘数据缓冲区的数据对应的LBA(总长度32位,低字节在前) */ -#define VAR_LBA_CURRENT 0x58 /* 当前读写的磁盘起始LBA地址(总长度32位,低字节在前) */ -#define VAR_FAT_DIR_LBA 0x5C /* 当前文件目录信息所在的扇区LBA地址(总长度32位,低字节在前) */ -#define VAR_START_CLUSTER 0x60 /* 当前文件或者目录(文件夹)的起始簇号(总长度32位,低字节在前) */ -#define VAR_CURRENT_CLUST 0x64 /* 当前文件的当前簇号(总长度32位,低字节在前) */ -#define VAR_FILE_SIZE 0x68 /* 当前文件的长度(总长度32位,低字节在前) */ -#define VAR_CURRENT_OFFSET 0x6C /* 当前文件指针,当前读写位置的字节偏移(总长度32位,低字节在前) */ +#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 /* ********************************************************************************************************************* */ -/* 常用USB定义 */ - -/* USB的包标识PID, 主机方式可能用到 */ -#ifndef DEF_USB_PID_SETUP -#define DEF_USB_PID_NULL 0x00 /* 保留PID, 未定义 */ -#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 +#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 -/* USB请求类型, 外置固件模式可能用到 */ -#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 /* 保留请求 */ +#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 -/* USB标准设备请求, RequestType的位6位5=00(Standard), 外置固件模式可能用到 */ -#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 +#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 /* ********************************************************************************************************************* */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c index 75be34c2c..9478b2668 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c @@ -18,25 +18,9 @@ * @date 2022.10.10 */ -/* CH376芯片 文件系统层 V1.3 */ -/* 提供文件系统常用子程序,提供命令打包 */ -/* 不使用的子程序可以注释掉,从而节约单片机的程序ROM空间和数据RAM空间 */ -/* 这里的子程序是通过括号中的变量传递参数,如果参数较多,为了节约RAM,也可以参考CH375子程序库改成通过同一全局变量/联合结构CH376_CMD_DATA传递 */ - -/* name 参数是指短文件名, 可以包括根目录符, 但不含有路径分隔符, 总长度不超过1+8+1+3+1字节 */ -/* PathName 参数是指全路径的短文件名, 包括根目录符、多级子目录及路径分隔符、文件名/目录名 */ -/* LongName 参数是指长文件名, 以UNICODE小端顺序编码, 以两个0字节结束, 使用长文件名子程序必须先定义全局缓冲区GlobalBuf, 长度不小于64字节, 可以与其它子程序共用 */ - -/* 定义 NO_DEFAULT_CH376_INT 用于禁止默认的Wait376Interrupt子程序,禁止后,应用程序必须自行定义一个同名子程序 */ -/* 定义 DEF_INT_TIMEOUT 用于设置默认的Wait376Interrupt子程序中的等待中断的超时时间/循环计数值, 0则不检查超时而一直等待 */ -/* 定义 EN_DIR_CREATE 用于提供新建多级子目录的子程序,默认是不提供 */ -/* 定义 EN_DISK_QUERY 用于提供磁盘容量查询和剩余空间查询的子程序,默认是不提供 */ -/* 定义 EN_SECTOR_ACCESS 用于提供以扇区为单位读写文件的子程序,默认是不提供 */ -/* 定义 EN_LONG_NAME 用于提供支持长文件名的子程序,默认是不提供 */ -/* 定义 DEF_IC_V43_U 用于去掉支持低版本的程序代码,仅支持V4.3及以上版本的CH376芯片,默认是支持低版本 */ #if 0 -#define DEF_IC_V43_U 1 /* 推荐定义 DEF_IC_V43_U 以优化代码 */ +#define DEF_IC_V43_U 1 #endif #include "k210_ch376.h" @@ -46,13 +30,14 @@ ****************************************************************************/ static int fd; -/* 串口方式未用到 */ +/* Serial port mode is not used */ void xEndCH376Cmd(void) { } -void xWriteCH376Cmd( UINT8 cmd ) { /* 向CH376的命令端口写入命令,周期不小于2uS,如果单片机较快则延时 */ - UINT8 temp[3]; +void xWriteCH376Cmd(UINT8 cmd) +{ + UINT8 temp[3]; temp[0] = 0x57; temp[1] = 0xab; temp[2] = cmd; @@ -60,611 +45,615 @@ void xWriteCH376Cmd( UINT8 cmd ) { /* 向CH376的命令端口写入命令, write(fd, temp, 3); } -//写数据 -void xWriteCH376Data( UINT8 dat ) { /* 向CH376的数据端口写入数据,周期不小于1uS,如果单片机较快则延时 */ +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 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 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 s, l; + xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); + s = l = xReadCH376Data( ); + if ( l ) { + do { + *buf = xReadCH376Data( ); + buf ++; + } while ( -- l ); + } + xEndCH376Cmd( ); + return( s ); } -/* 查询CH376中断(INT#低电平) */ -UINT8 Query376Interrupt( void ) +UINT8 Query376Interrupt(void) { - //产生中断的同时,串口会收到一个数据,直接读出来丢掉 - if(xReadCH376Data() == ERR_USB_UNKNOWN) return FALSE ; - else return TRUE ; + //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初始化代码 */ -UINT8 mInitCH376Host( void ) /* 初始化CH376 */ +/* CH376 INIT */ +UINT8 mInitCH376Host(void) { - UINT8 res; - up_mdelay(50); /* 上电后至少延时50ms操作 */ + UINT8 res; + /* After power on, delay operation for at least 50ms */ + up_mdelay(50); fd = open("/dev/ttyS3", O_RDWR); up_mdelay(600); - xWriteCH376Cmd( CMD11_CHECK_EXIST ); /* 测试单片机与CH376之间的通讯接口 */ - xWriteCH376Data( 0x65 ); - res = xReadCH376Data( ); - xEndCH376Cmd( ); - if ( res != 0x9A ) return( ERR_USB_UNKNOWN ); /* 通讯接口不正常,可能原因有:接口连接异常,其它设备影响(片选不唯一),串口波特率,一直在复位,晶振不工作 */ + /* 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 ); /* 设备USB工作模式 */ - xWriteCH376Data( 0x06 ); - up_udelay( 20 ); - res = xReadCH376Data( ); - xEndCH376Cmd( ); - if ( res == CMD_RET_SUCCESS ) return( USB_INT_SUCCESS ); - else return( ERR_USB_UNKNOWN ); /* 设置模式错误 */ - + xWriteCH376Cmd(CMD11_SET_USB_MODE); /* SET USB MODE */ + xWriteCH376Data(0x06); + up_udelay(20); + res = xReadCH376Data(); + xEndCH376Cmd(); + if (res == CMD_RET_SUCCESS) return(USB_INT_SUCCESS); + else return(ERR_USB_UNKNOWN); /* SET MODE ERROR */ + } -UINT8 CH376WriteReqBlock( PUINT8 buf ) /* 向内部指定缓冲区写入请求的数据块,返回长度 */ +/* 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 ); + UINT8 s, l; + xWriteCH376Cmd( CMD01_WR_REQ_DATA ); + s = l = xReadCH376Data(); + if ( l ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- l ); + } + xEndCH376Cmd( ); + return( s ); } -void CH376WriteHostBlock( PUINT8 buf, UINT8 len ) /* 向USB主机端点的发送缓冲区写入数据块 */ +/* 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( ); + xWriteCH376Cmd( CMD10_WR_HOST_DATA ); + xWriteCH376Data( len ); + if ( len ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + xEndCH376Cmd( ); } -void CH376WriteOfsBlock( PUINT8 buf, UINT8 ofs, UINT8 len ) /* 向内部缓冲区指定偏移地址写入数据块 */ +/* 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 ); /* 偏移地址 */ - xWriteCH376Data( len ); /* 长度 */ - if ( len ) { - do { - xWriteCH376Data( *buf ); - buf ++; - } while ( -- len ); - } - xEndCH376Cmd( ); + xWriteCH376Cmd( CMD20_WR_OFS_DATA ); + xWriteCH376Data( ofs ); /* Offset address */ + xWriteCH376Data( len ); /* length */ + if ( len ) { + do { + xWriteCH376Data( *buf ); + buf ++; + } while ( -- len ); + } + xEndCH376Cmd( ); } -void CH376SetFileName( PUINT8 name ) /* 设置将要操作的文件的文件名 */ +/* 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 ); - } - } - } - } + 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; - if ( c == DEF_SEPAR_CHAR1 || c == DEF_SEPAR_CHAR2 ) c = 0; /* 强行将文件名截止 */ - xWriteCH376Data( c ); - } - xEndCH376Cmd( ); + 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( ); } -UINT32 CH376Read32bitDat( void ) /* 从CH376芯片读取32位的数据并结束命令 */ +/* 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 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 ) /* 读CH376芯片内部的8位变量 */ + +UINT8 CH376ReadVar8( UINT8 var ) { - UINT8 c0; - xWriteCH376Cmd( CMD11_READ_VAR8 ); - xWriteCH376Data( var ); - c0 = xReadCH376Data( ); - xEndCH376Cmd( ); - return( c0 ); + UINT8 c0; + xWriteCH376Cmd( CMD11_READ_VAR8 ); + xWriteCH376Data( var ); + c0 = xReadCH376Data( ); + xEndCH376Cmd( ); + return( c0 ); } -void CH376WriteVar8( UINT8 var, UINT8 dat ) /* 写CH376芯片内部的8位变量 */ +void CH376WriteVar8( UINT8 var, UINT8 dat ) { - xWriteCH376Cmd( CMD20_WRITE_VAR8 ); - xWriteCH376Data( var ); - xWriteCH376Data( dat ); - xEndCH376Cmd( ); + xWriteCH376Cmd( CMD20_WRITE_VAR8 ); + xWriteCH376Data( var ); + xWriteCH376Data( dat ); + xEndCH376Cmd( ); } -UINT32 CH376ReadVar32( UINT8 var ) /* 读CH376芯片内部的32位变量 */ +UINT32 CH376ReadVar32( UINT8 var ) { - xWriteCH376Cmd( CMD14_READ_VAR32 ); - xWriteCH376Data( var ); - return( CH376Read32bitDat( ) ); /* 从CH376芯片读取32位的数据并结束命令 */ + xWriteCH376Cmd( CMD14_READ_VAR32 ); + xWriteCH376Data( var ); + return( CH376Read32bitDat( ) ); } -void CH376WriteVar32( UINT8 var, UINT32 dat ) /* 写CH376芯片内部的32位变量 */ +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( ); + 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 ) /* 在调用CH376DirInfoRead获取FAT_DIR_INFO结构之后应该通知CH376结束 */ +void CH376EndDirInfo( void ) { - CH376WriteVar8( 0x0D, 0x00 ); + CH376WriteVar8( 0x0D, 0x00 ); } -UINT32 CH376GetFileSize( void ) /* 读取当前文件长度 */ +UINT32 CH376GetFileSize( void ) { - return( CH376ReadVar32( VAR_FILE_SIZE ) ); + return( CH376ReadVar32( VAR_FILE_SIZE ) ); } -UINT8 CH376GetDiskStatus( void ) /* 获取磁盘和文件系统的工作状态 */ +UINT8 CH376GetDiskStatus( void ) { - return( CH376ReadVar8( VAR_DISK_STATUS ) ); + return( CH376ReadVar8( VAR_DISK_STATUS ) ); } -UINT8 CH376GetIntStatus( void ) /* 获取中断状态并取消中断请求 */ +UINT8 CH376GetIntStatus( void ) { - UINT8 s; - xWriteCH376Cmd( CMD01_GET_STATUS ); - s = xReadCH376Data( ); - xEndCH376Cmd( ); - return( s ); + UINT8 s; + xWriteCH376Cmd( CMD01_GET_STATUS ); + s = xReadCH376Data( ); + xEndCH376Cmd( ); + return( s ); } -#ifndef NO_DEFAULT_CH376_INT -UINT8 Wait376Interrupt( void ) /* 等待CH376中断(INT#低电平),返回中断状态码, 超时则返回ERR_USB_UNKNOWN */ +#ifndef NO_DEFAULT_CH376_INT +UINT8 Wait376Interrupt( void ) { -#ifdef DEF_INT_TIMEOUT -#if DEF_INT_TIMEOUT < 1 - while ( Query376Interrupt( ) == FALSE ); /* 一直等中断 */ - return( CH376GetIntStatus( ) ); /* 检测到中断 */ +#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( ) ); /* 检测到中断 */ -/* 在等待CH376中断的过程中,可以做些需要及时处理的其它事情 */ - } - return( ERR_USB_UNKNOWN ); /* 不应该发生的情况 */ + 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( ) ); /* 检测到中断 */ -/* 在等待CH376中断的过程中,可以做些需要及时处理的其它事情 */ - } - return( ERR_USB_UNKNOWN ); /* 不应该发生的情况 */ + UINT32 i; + for ( i = 0; i < 5000000; i ++ ) { + if ( Query376Interrupt( ) ) return( CH376GetIntStatus( ) ); + } + return( ERR_USB_UNKNOWN ); #endif } #endif -UINT8 CH376SendCmdWaitInt( UINT8 mCmd ) /* 发出命令码后,等待中断 */ +UINT8 CH376SendCmdWaitInt( UINT8 mCmd ) { - xWriteCH376Cmd( mCmd ); - xEndCH376Cmd( ); - return( Wait376Interrupt( ) ); + xWriteCH376Cmd( mCmd ); + xEndCH376Cmd( ); + return( Wait376Interrupt( ) ); } -UINT8 CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat ) /* 发出命令码和一字节数据后,等待中断 */ +UINT8 CH376SendCmdDatWaitInt( UINT8 mCmd, UINT8 mDat ) { - xWriteCH376Cmd( mCmd ); - xWriteCH376Data( mDat ); - xEndCH376Cmd( ); - return( Wait376Interrupt( ) ); + xWriteCH376Cmd( mCmd ); + xWriteCH376Data( mDat ); + xEndCH376Cmd( ); + return(Wait376Interrupt()); } -UINT8 CH376DiskReqSense( void ) /* 检查USB存储器错误 */ +UINT8 CH376DiskReqSense( void ) { - UINT8 s; - up_mdelay( 5 ); - s = CH376SendCmdWaitInt( CMD0H_DISK_R_SENSE ); - up_mdelay( 5 ); - return( s ); + UINT8 s; + up_mdelay( 5 ); + s = CH376SendCmdWaitInt( CMD0H_DISK_R_SENSE ); + up_mdelay( 5 ); + return( s ); } -UINT8 CH376DiskConnect( void ) /* 检查U盘是否连接,不支持SD卡 */ +UINT8 CH376DiskConnect( void ) { - if ( Query376Interrupt( ) ) CH376GetIntStatus( ); /* 检测到中断 */ - return( CH376SendCmdWaitInt( CMD0H_DISK_CONNECT ) ); + if ( Query376Interrupt( ) ) CH376GetIntStatus( ); + return( CH376SendCmdWaitInt( CMD0H_DISK_CONNECT ) ); } -UINT8 CH376DiskMount( void ) /* 初始化磁盘并测试磁盘是否就绪 */ +UINT8 CH376DiskMount( void ) { - return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) ); + return( CH376SendCmdWaitInt( CMD0H_DISK_MOUNT ) ); } -UINT8 CH376FileOpen( PUINT8 name ) /* 在根目录或者当前目录下打开文件或者目录(文件夹) */ +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 ); + 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 ) ); + return( CH376SendCmdWaitInt( CMD0H_FILE_OPEN ) ); } -UINT8 CH376FileCreate( PUINT8 name ) /* 在根目录或者当前目录下新建文件,如果文件已经存在那么先删除 */ +UINT8 CH376FileCreate( PUINT8 name ) { - if ( name ) CH376SetFileName( name ); /* 设置将要操作的文件的文件名 */ - return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) ); + if ( name ) CH376SetFileName( name ); + return( CH376SendCmdWaitInt( CMD0H_FILE_CREATE ) ); } -UINT8 CH376DirCreate( PUINT8 name ) /* 在根目录下新建目录(文件夹)并打开,如果目录已经存在那么直接打开 */ +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 ); + 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 ) ); + return( CH376SendCmdWaitInt( CMD0H_DIR_CREATE ) ); } -UINT8 CH376SeparatePath( PUINT8 path ) /* 从路径中分离出最后一级文件名或者目录(文件夹)名,返回最后一级文件名或者目录名的字节偏移 */ +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 ); + 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 ) /* 打开多级目录下的文件或者目录的上级目录,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ -/* StopName 指向最后一级文件名或者目录名 */ +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 ); /* 路径结束,USB_INT_SUCCESS为成功打开文件,ERR_OPEN_DIR为成功打开目录(文件夹),其它为操作出错 */ - } + 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 ) /* 打开多级目录下的文件或者目录(文件夹),支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ +UINT8 CH376FileOpenPath( PUINT8 PathName ) { - return( CH376FileOpenDir( PathName, 0xFF ) ); + return( CH376FileOpenDir( PathName, 0xFF ) ); } -UINT8 CH376FileCreatePath( PUINT8 PathName ) /* 新建多级目录下的文件,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ +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] ) ); /* 在根目录或者当前目录下新建文件 */ + 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 ) /* 新建多级目录下的目录(文件夹)并打开,支持多级目录路径,支持路径分隔符,路径长度不超过255个字符 */ +#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 ); /* 写入上级目录的起始簇号的高16位 */ - 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 ); /* 写入上级目录的起始簇号的低16位 */ - 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 ); /* 必须提供完整路径才能实现在当前目录下新建目录 */ - } + 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 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 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 ) /* 关闭当前已经打开的文件或者目录(文件夹) */ +UINT8 CH376FileClose( UINT8 UpdateSz ) { return( CH376SendCmdDatWaitInt( CMD1H_FILE_CLOSE, UpdateSz ) ); } -UINT8 CH376DirInfoRead( void ) /* 读取当前文件的目录信息 */ +UINT8 CH376DirInfoRead( void ) { - return( CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, 0xFF ) ); + return( CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, 0xFF ) ); } -UINT8 CH376DirInfoSave( void ) /* 保存文件的目录信息 */ +UINT8 CH376DirInfoSave( void ) { - return( CH376SendCmdWaitInt( CMD0H_DIR_INFO_SAVE ) ); + return( CH376SendCmdWaitInt( CMD0H_DIR_INFO_SAVE ) ); } -UINT8 CH376ByteLocate( UINT32 offset ) /* 以字节为单位移动当前文件指针 */ +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( ) ); + 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 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 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 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 ); /* 向内部指定缓冲区写入请求的数据块,返回长度 */ + 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 ); /* 错误 */ + else return( s ); } } #ifdef EN_DISK_QUERY -UINT8 CH376DiskCapacity( PUINT32 DiskCap ) /* 查询磁盘物理容量,扇区数 */ +UINT8 CH376DiskCapacity( PUINT32 DiskCap ) { - UINT8 s; - s = CH376SendCmdWaitInt( CMD0H_DISK_CAPACITY ); - if ( s == USB_INT_SUCCESS ) { /* 参考CH376INC.H文件中CH376_CMD_DATA结构的DiskCapacity */ - xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); - xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.DiskCapacity) */ - *DiskCap = CH376Read32bitDat( ); /* CH376_CMD_DATA.DiskCapacity.mDiskSizeSec,从CH376芯片读取32位的数据并结束命令 */ - } - else *DiskCap = 0; - return( s ); + 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 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 ); - } + 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 ) { /* 参考CH376INC.H文件中CH376_CMD_DATA结构的DiskQuery */ - xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); - xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.DiskQuery) */ - xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mTotalSector */ - xReadCH376Data( ); - xReadCH376Data( ); - xReadCH376Data( ); - c0 = xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mFreeSector */ - c1 = xReadCH376Data( ); - c2 = xReadCH376Data( ); - c3 = xReadCH376Data( ); - *DiskFre = c0 | (UINT16)c1 << 8 | (UINT32)c2 << 16 | (UINT32)c3 << 24; - xReadCH376Data( ); /* CH376_CMD_DATA.DiskQuery.mDiskFat */ - xEndCH376Cmd( ); - } - else *DiskFre = 0; - return( s ); + 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 ) /* 以扇区为单位移动当前文件指针 */ +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( ) ); + 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 ) /* 从U盘读取多个扇区的数据块到缓冲区,不支持SD卡 */ -/* iLbaStart 是准备读取的线性起始扇区号, iSectorCount 是准备读取的扇区数 */ +UINT8 CH376DiskReadSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ) + { - UINT8 s, err; - UINT16 mBlockCount; - for ( err = 0; err != 3; ++ err ) { /* 出错重试 */ - xWriteCH376Cmd( CMD5H_DISK_READ ); /* 从USB存储器读扇区 */ - xWriteCH376Data( (UINT8)iLbaStart ); /* LBA的最低8位 */ - xWriteCH376Data( (UINT8)( (UINT16)iLbaStart >> 8 ) ); - xWriteCH376Data( (UINT8)( iLbaStart >> 16 ) ); - xWriteCH376Data( (UINT8)( iLbaStart >> 24 ) ); /* LBA的最高8位 */ - xWriteCH376Data( iSectorCount ); /* 扇区数 */ - xEndCH376Cmd( ); - for ( mBlockCount = iSectorCount * DEF_SECTOR_SIZE / CH376_DAT_BLOCK_LEN; mBlockCount != 0; -- mBlockCount ) { /* 数据块计数 */ - s = Wait376Interrupt( ); /* 等待中断并获取状态 */ - if ( s == USB_INT_DISK_READ ) { /* USB存储器读数据块,请求数据读出 */ - s = CH376ReadBlock( buf ); /* 从当前主机端点的接收缓冲区读取数据块,返回长度 */ - xWriteCH376Cmd( CMD0H_DISK_RD_GO ); /* 继续执行USB存储器的读操作 */ - 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 ); /* U盘被移除 */ - CH376DiskReqSense( ); /* 检查USB存储器错误 */ - } - return( s ); /* 操作失败 */ + 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 ) /* 将缓冲区中的多个扇区的数据块写入U盘,不支持SD卡 */ -/* iLbaStart 是写入的线起始性扇区号, iSectorCount 是写入的扇区数 */ +UINT8 CH376DiskWriteSec( PUINT8 buf, UINT32 iLbaStart, UINT8 iSectorCount ) { UINT8 s, err; UINT16 mBlockCount; - for ( err = 0; err != 3; ++ err ) { /* 出错重试 */ - xWriteCH376Cmd( CMD5H_DISK_WRITE ); /* 向USB存储器写扇区 */ - xWriteCH376Data( (UINT8)iLbaStart ); /* LBA的最低8位 */ + 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 ) ); /* LBA的最高8位 */ - xWriteCH376Data( iSectorCount ); /* 扇区数 */ + 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 ) { /* USB存储器写数据块,请求数据写入 */ - CH376WriteHostBlock( buf, CH376_DAT_BLOCK_LEN ); /* 向USB主机端点的发送缓冲区写入数据块 */ - xWriteCH376Cmd( CMD0H_DISK_WR_GO ); /* 继续执行USB存储器的写操作 */ + 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; /* 返回错误状态 */ + else break; } if ( mBlockCount == 0 ) { - s = Wait376Interrupt( ); /* 等待中断并获取状态 */ - if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); /* 操作成功 */ + s = Wait376Interrupt( ); + if ( s == USB_INT_SUCCESS ) return( USB_INT_SUCCESS ); } - if ( s == USB_INT_DISCONNECT ) return( s ); /* U盘被移除 */ - CH376DiskReqSense( ); /* 检查USB存储器错误 */ + if ( s == USB_INT_DISCONNECT ) return( s ); + CH376DiskReqSense( ); } - return( s ); /* 操作失败 */ + return( s ); } -UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇区为单位从当前位置读取数据块,不支持SD卡 */ +UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) { UINT8 s; UINT8 cnt; @@ -705,14 +694,14 @@ UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇区 #endif if ( s != USB_INT_SUCCESS ) return( s ); xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); - xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.SectorRead) */ - cnt = xReadCH376Data( ); /* CH376_CMD_DATA.SectorRead.mSectorCount */ + xReadCH376Data( ); + cnt = xReadCH376Data( ); xReadCH376Data( ); xReadCH376Data( ); xReadCH376Data( ); - StaSec = CH376Read32bitDat( ); /* CH376_CMD_DATA.SectorRead.mStartSector,从CH376芯片读取32位的数据并结束命令 */ + StaSec = CH376Read32bitDat( ); if ( cnt == 0 ) break; - s = CH376DiskReadSec( buf, StaSec, cnt ); /* 从U盘读取多个扇区的数据块到缓冲区 */ + s = CH376DiskReadSec( buf, StaSec, cnt ); if ( s != USB_INT_SUCCESS ) return( s ); buf += cnt * DEF_SECTOR_SIZE; if ( RealCount ) *RealCount += cnt; @@ -721,7 +710,7 @@ UINT8 CH376SecRead( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇区 return( s ); } -UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇区为单位在当前位置写入数据块,不支持SD卡 */ +UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) { UINT8 s; UINT8 cnt; @@ -734,14 +723,14 @@ UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇 s = Wait376Interrupt( ); if ( s != USB_INT_SUCCESS ) return( s ); xWriteCH376Cmd( CMD01_RD_USB_DATA0 ); - xReadCH376Data( ); /* 长度总是sizeof(CH376_CMD_DATA.SectorWrite) */ - cnt = xReadCH376Data( ); /* CH376_CMD_DATA.SectorWrite.mSectorCount */ + xReadCH376Data( ); + cnt = xReadCH376Data( ); xReadCH376Data( ); xReadCH376Data( ); xReadCH376Data( ); - StaSec = CH376Read32bitDat( ); /* CH376_CMD_DATA.SectorWrite.mStartSector,从CH376芯片读取32位的数据并结束命令 */ + StaSec = CH376Read32bitDat( ); if ( cnt == 0 ) break; - s = CH376DiskWriteSec( buf, StaSec, cnt ); /* 将缓冲区中的多个扇区的数据块写入U盘 */ + s = CH376DiskWriteSec( buf, StaSec, cnt ); if ( s != USB_INT_SUCCESS ) return( s ); buf += cnt * DEF_SECTOR_SIZE; if ( RealCount ) *RealCount += cnt; @@ -754,7 +743,7 @@ UINT8 CH376SecWrite( PUINT8 buf, UINT8 ReqCount, PUINT8 RealCount ) /* 以扇 #ifdef EN_LONG_NAME -UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount ) /* 长文件名专用的字节写子程序 */ +UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount ) { UINT8 s; #ifndef DEF_IC_V43_U @@ -769,26 +758,25 @@ UINT8 CH376LongNameWrite( PUINT8 buf, UINT16 ReqCount ) /* 长文件名专用 while ( 1 ) { s = Wait376Interrupt( ); if ( s == USB_INT_DISK_WRITE ) { - if ( buf ) buf += CH376WriteReqBlock( buf ); /* 向内部指定缓冲区写入请求的数据块,返回长度 */ + if ( buf ) buf += CH376WriteReqBlock( buf ); else { - xWriteCH376Cmd( CMD01_WR_REQ_DATA ); /* 向内部指定缓冲区写入请求的数据块 */ - s = xReadCH376Data( ); /* 长度 */ - while ( s -- ) xWriteCH376Data( 0 ); /* 填充0 */ + xWriteCH376Cmd( CMD01_WR_REQ_DATA ); + s = xReadCH376Data( ); + while ( s -- ) xWriteCH376Data( 0 ); } xWriteCH376Cmd( CMD0H_BYTE_WR_GO ); xEndCH376Cmd( ); } -/* else if ( s == USB_INT_SUCCESS ) return( s );*/ /* 结束 */ else { #ifndef DEF_IC_V43_U if ( c == DEF_DISK_OPEN_ROOT ) CH376WriteVar8( VAR_DISK_STATUS, c ); #endif - return( s ); /* 错误 */ + return( s ); } } } -UINT8 CH376CheckNameSum( PUINT8 DirName ) /* 计算长文件名的短文件名检验和,输入为无小数点分隔符的固定11字节格式 */ +UINT8 CH376CheckNameSum( PUINT8 DirName ) { UINT8 NameLen; UINT8 CheckSum; @@ -797,181 +785,175 @@ UINT8 CH376CheckNameSum( PUINT8 DirName ) /* 计算长文件名的短文件名 return( CheckSum ); } -UINT8 CH376LocateInUpDir( PUINT8 PathName ) /* 在上级目录(文件夹)中移动文件指针到当前文件目录信息所在的扇区 */ -/* 另外,顺便将当前文件目录信息所在的扇区的前一个扇区的LBA地址写入CH376内部VAR_FAT_DIR_LBA变量(为了方便收集长文件名时向前搜索,否则要多移动一次) */ -/* 使用了全局缓冲区GlobalBuf的前12个字节 */ +UINT8 CH376LocateInUpDir( PUINT8 PathName ) { UINT8 s; xWriteCH376Cmd( CMD14_READ_VAR32 ); - xWriteCH376Data( VAR_FAT_DIR_LBA ); /* 当前文件目录信息所在的扇区LBA地址 */ - for ( s = 4; s != 8; s ++ ) GlobalBuf[ s ] = xReadCH376Data( ); /* 临时保存于全局缓冲区中,节约RAM */ + 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( "/" ); /* 根目录下的文件,则打开根目录 */ + s = CH376SeparatePath( PathName ); + if ( s ) s = CH376FileOpenDir( PathName, s ); + else s = CH376FileOpen( "/" ); if ( s != ERR_OPEN_DIR ) return( s ); - *(PUINT32)(&GlobalBuf[0]) = 0; /* 目录扇区偏移扇区数,保存在全局缓冲区中,节约RAM */ - while ( 1 ) { /* 不断移动文件指针,直到与当前文件目录信息所在的扇区LBA地址匹配 */ - s = CH376SecLocate( *(PUINT32)(&GlobalBuf[0]) ); /* 以扇区为单位在上级目录中移动文件指针 */ + *(PUINT32)(&GlobalBuf[0]) = 0; + while ( 1 ) { + s = CH376SecLocate( *(PUINT32)(&GlobalBuf[0]) ); if ( s != USB_INT_SUCCESS ) return( s ); - CH376ReadBlock( &GlobalBuf[8] ); /* 从内存缓冲区读取CH376_CMD_DATA.SectorLocate.mSectorLba数据块,返回长度总是sizeof(CH376_CMD_DATA.SectorLocate) */ - if ( *(PUINT32)(&GlobalBuf[8]) == *(PUINT32)(&GlobalBuf[4]) ) return( USB_INT_SUCCESS ); /* 已到当前文件目录信息扇区 */ + CH376ReadBlock( &GlobalBuf[8] ); + if ( *(PUINT32)(&GlobalBuf[8]) == *(PUINT32)(&GlobalBuf[4]) ) return( USB_INT_SUCCESS ); xWriteCH376Cmd( CMD50_WRITE_VAR32 ); - xWriteCH376Data( VAR_FAT_DIR_LBA ); /* 得到前一个扇区,设置为新的文件目录信息扇区LBA地址 */ + xWriteCH376Data( VAR_FAT_DIR_LBA ); for ( s = 8; s != 12; s ++ ) xWriteCH376Data( GlobalBuf[ s ] ); xEndCH376Cmd( ); ++ *(PUINT32)(&GlobalBuf[0]); } } -UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName ) /* 由短文件名或者目录(文件夹)名获得相应的长文件名 */ -/* 需要输入短文件名的完整路径PathName,需要提供缓冲区接收长文件名LongName(以UNICODE小端编码,以双0结束) */ -/* 使用了全局缓冲区GlobalBuf的前34个字节,sizeof(GlobalBuf)>=sizeof(FAT_DIR_INFO)+2 */ +UINT8 CH376GetLongName( PUINT8 PathName, PUINT8 LongName ) { UINT8 s; - UINT16 NameCount; /* 长文件名字节计数 */ - s = CH376FileOpenPath( PathName ); /* 打开多级目录下的文件或者目录 */ + UINT16 NameCount; + s = CH376FileOpenPath( PathName ); if ( s != USB_INT_SUCCESS && s != ERR_OPEN_DIR ) return( s ); - s = CH376DirInfoRead( ); /* 读取当前文件的目录信息FAT_DIR_INFO,将相关数据调到内存中 */ + s = CH376DirInfoRead( ); if ( s != USB_INT_SUCCESS ) return( s ); - CH376ReadBlock( GlobalBuf ); /* 从内存缓冲区读取FAT_DIR_INFO数据块,返回长度总是sizeof(FAT_DIR_INFO) */ - CH376EndDirInfo( ); /* 获取完FAT_DIR_INFO结构 */ - GlobalBuf[32] = CH376CheckNameSum( GlobalBuf ); /* 计算长文件名的短文件名检验和,保存在全局缓冲区中,节约RAM */ - GlobalBuf[33] = CH376ReadVar8( VAR_FILE_DIR_INDEX ); /* 当前文件目录信息在扇区内的索引号,保存在全局缓冲区中,节约RAM */ + 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 ( GlobalBuf[33] == 0 ) { + s = CH376LocateInUpDir( PathName ); if ( s != USB_INT_SUCCESS ) break; - if ( CH376ReadVar32( VAR_CURRENT_OFFSET ) == 0 ) { /* 当前已经处于目录扇区的开始,无法获取长文件名 */ + if ( CH376ReadVar32( VAR_CURRENT_OFFSET ) == 0 ) { s = ERR_LONG_NAME_ERR; break; } - GlobalBuf[33] = DEF_SECTOR_SIZE / sizeof( FAT_DIR_INFO ); /* 指向前一个扇区的最后一个文件目录信息 */ + GlobalBuf[33] = DEF_SECTOR_SIZE / sizeof( FAT_DIR_INFO ); } - GlobalBuf[33] --; /* 从后向前搜索文件目录信息 */ - s = CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, GlobalBuf[33] ); /* 读取指定的目录信息FAT_DIR_INFO,将相关数据调到内存中 */ + GlobalBuf[33] --; + s = CH376SendCmdDatWaitInt( CMD1H_DIR_INFO_READ, GlobalBuf[33] ); if ( s != USB_INT_SUCCESS ) break; - CH376ReadBlock( GlobalBuf ); /* 从内存缓冲区读取FAT_DIR_INFO数据块,返回长度总是sizeof(FAT_DIR_INFO) */ - CH376EndDirInfo( ); /* 获取完FAT_DIR_INFO结构 */ - if ( ( GlobalBuf[11] & ATTR_LONG_NAME_MASK ) != ATTR_LONG_NAME || GlobalBuf[13] != GlobalBuf[32] ) { /* 类型错误或者校验和错误 */ + CH376ReadBlock( GlobalBuf ); + CH376EndDirInfo( ); + if ( ( GlobalBuf[11] & ATTR_LONG_NAME_MASK ) != ATTR_LONG_NAME || GlobalBuf[13] != GlobalBuf[32] ) { s = ERR_LONG_NAME_ERR; - break; /* 没有直接返回是因为如果是打开了根目录那么必须要关闭后才能返回 */ + break; } - for ( s = 1; s < sizeof( FAT_DIR_INFO ); s += 2 ) { /* 收集长文件名,长文件名的字符在磁盘上UNICODE用小端方式存放 */ - if ( s == 1 + 5 * 2 ) s = 14; /* 从长文件名的第一组1-5个字符跳到第二组6-11个字符 */ - else if ( s == 14 + 6 * 2 ) s = 28; /* 从长文件名的第二组6-11个字符跳到第三组12-13个字符 */ + 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 ) { /* 长文件名缓冲区溢出 */ + 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; /* 成功完成长文件名收集完成 */ + if ( GlobalBuf[0] & 0x40 ) { + if ( s >= sizeof( FAT_DIR_INFO ) ) *(PUINT16)( &LongName[ NameCount ] ) = 0x0000; + s = USB_INT_SUCCESS; break; } } CH376GetLongNameE: - CH376FileClose( FALSE ); /* 对于根目录则必须要关闭 */ + CH376FileClose( FALSE ); return( s ); } -UINT8 CH376CreateLongName( PUINT8 PathName, PUINT8 LongName ) /* 新建具有长文件名的文件,关闭文件后返回,LongName输入路径必须在RAM中 */ -/* 需要输入短文件名的完整路径PathName(请事先参考FAT规范由长文件名自行产生),需要输入以UNICODE小端编码的以双0结束的长文件名LongName */ -/* 使用了全局缓冲区GlobalBuf的前64个字节,sizeof(GlobalBuf)>=sizeof(FAT_DIR_INFO)*2 */ +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; /* 长文件名占用文件目录结构的个数 */ + 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; /* 加上0结束符后的长度 */ + 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; /* 把剩余数据填为0xFF */ + if ( i < LONG_NAME_PER_DIR ) { + while ( i++ < LONG_NAME_PER_DIR ) LongName[count++] = 0xFF; } } - s = CH376FileOpenPath( PathName ); /* 打开多级目录下的文件 */ - if ( s == USB_INT_SUCCESS ) { /* 短文件名存在则返回错误 */ + s = CH376FileOpenPath( PathName ); + if ( s == USB_INT_SUCCESS ) { s = ERR_NAME_EXIST; goto CH376CreateLongNameE; } if ( s != ERR_MISS_FILE ) return( s ); - s = CH376FileCreatePath( PathName ); /* 新建多级目录下的文件 */ + 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 ); /* 在上级目录中移动文件指针到当前文件目录信息的位置 */ + 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 ); /* 以字节为单位读取数据,获得当前文件的目录信息FAT_DIR_INFO */ + 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 ); /* 以字节为单位读取数据,获得下一个文件目录信息FAT_DIR_INFO */ + 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 ( count == 0 ) break; + if ( GlobalBuf[0] && GlobalBuf[0] != 0xE5 ) { + s = CH376ByteLocate( NewFileLoc ); if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; - GlobalBuf[ 0 ] = 0xE5; /* 文件删除标志 */ + 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) ); /* 写入一个文件目录结构,用于删除之前新建的文件,实际上稍后会将之转移到目录的最末位置 */ + s = CH376LongNameWrite( GlobalBuf, sizeof(FAT_DIR_INFO) ); if ( s != USB_INT_SUCCESS ) goto CH376CreateLongNameE; - do { /* 向后搜索空闲的文件目录结构 */ - s = CH376ByteRead( GlobalBuf, sizeof(FAT_DIR_INFO), &count ); /* 以字节为单位读取数据,获得下一个文件目录信息FAT_DIR_INFO */ + 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); /* 倒回到刚才搜索到的空闲的文件目录结构的起始位置 */ + } 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 ) { /* FAT12/FAT16的根目录,容量是固定的,无法增加文件目录结构 */ - s = ERR_FDT_OVER; /* FAT12/FAT16根目录下的文件数应该少于512个,需要磁盘整理 */ + 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; /* 一簇不够则增加一簇,这种情况只会发生于每簇为512字节的情况下 */ - s = CH376LongNameWrite( NULL, count ); /* 以字节为单位向当前位置写入全0数据块,清空新增加的文件目录簇 */ + 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 ); /* 在上级目录中移动文件指针到当前文件目录信息的位置 */ + 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[13] = CH376CheckNameSum( &GlobalBuf[ sizeof(FAT_DIR_INFO) ] ); GlobalBuf[26] = 0x00; GlobalBuf[27] = 0x00; - for ( s = 0; DirBlockCnt != 0; ) { /* 长文件名占用的文件目录结构计数 */ - GlobalBuf[0] = s ? DirBlockCnt : DirBlockCnt | 0x40; /* 首次要置长文件名入口标志 */ + 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 ) { /* 输出长文件名,长文件名的字符在磁盘上UNICODE用小端方式存放 */ - if ( s == 1 + 5 * 2 ) s = 14; /* 从长文件名的第一组1-5个字符跳到第二组6-11个字符 */ - else if ( s == 14 + 6 * 2 ) s = 28; /* 从长文件名的第二组6-11个字符跳到第三组12-13个字符 */ + 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) ); /* 以字节为单位写入一个文件目录结构,长文件名 */ + 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) ); /* 以字节为单位写入一个文件目录结构,这是转移来的之前新建的文件的目录信息 */ + s = CH376LongNameWrite( &GlobalBuf[ sizeof(FAT_DIR_INFO) ], sizeof(FAT_DIR_INFO) ); CH376CreateLongNameE: - CH376FileClose( FALSE ); /* 对于根目录则必须要关闭 */ + CH376FileClose( FALSE ); return( s ); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h index f87a8169a..23f6b7838 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.h @@ -40,79 +40,85 @@ #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 ); +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 ) ) +#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 ) +#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 ); +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 ); -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 ); +#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 ); +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 ); -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 ); -UINT8 CH376DiskCapacity( PUINT32 DiskCap ); -UINT8 CH376DiskQuery( PUINT32 DiskFre ); -UINT8 CH376SecLocate( UINT32 offset ); -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 ); +#ifdef EN_DIR_CREATE +UINT8 CH376DirCreatePath( PUINT8 PathName ); #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 ); +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 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig index df719b23e..e0e603faf 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig @@ -547,6 +547,10 @@ config NSH_DISABLE_XD bool "Disable xd" default DEFAULT_SMALL +config NSH_DISABLE_CH376 + bool "Disable the ch376 demo." + default n + config NSH_DISABLE_CH438 bool "Disable the ch438 demo." default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h index a54df4a9c..0df886d26 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h @@ -1450,6 +1450,10 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, FAR void *arg); #endif +#if defined(CONFIG_BSP_USING_CH376) && !defined(CONFIG_NSH_DISABLE_CH376) + int cmd_Ch376(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index 65507a192..7bac913da 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -38,6 +38,19 @@ extern int FrameworkInit(void); +/**************************************************************************** + * Name: cmd_Ch376 + ****************************************************************************/ +#if defined(CONFIG_BSP_USING_CH376) && !defined(CONFIG_NSH_DISABLE_CH376) +extern void CH376Demo(void); +int cmd_Ch376(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + CH376Demo(); + return OK; +} +#endif + /**************************************************************************** * Name: cmd_Ch438 ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c index 5dbd550c6..c0132baf6 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c @@ -596,6 +596,10 @@ static const struct cmdmap_s g_cmdmap[] = { "xd", cmd_xd, 3, 3, " " }, #endif +#if defined(CONFIG_BSP_USING_CH376) && !defined(CONFIG_NSH_DISABLE_CH376) + { "ch376", cmd_Ch376, 1, 1, "[ch376 demo cmd.]" }, +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) { "ch438", cmd_Ch438, 1, 1, "[ch438 demo cmd.]" }, #endif From b073c38035c9c40026fd0d9b778c28dac4aeadea Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Wed, 12 Oct 2022 12:40:33 +0800 Subject: [PATCH 07/18] add ch376 usb and sd card demo on xidatong-riscv64 --- .../Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig | 5 +++++ .../aiit_board/xidatong-riscv64/src/ch376_demo.c | 2 ++ .../aiit_board/xidatong-riscv64/src/k210_ch376.c | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig index 90cfa7ee5..336704c35 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig @@ -24,6 +24,11 @@ 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_CH438 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c index d4302842a..f8d439e52 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/ch376_demo.c @@ -31,11 +31,13 @@ void CH376Demo(void) 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 ++ ) { diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c index 9478b2668..e1223e086 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch376.c @@ -107,7 +107,7 @@ UINT8 mInitCH376Host(void) if ( res != 0x9A ) return( ERR_USB_UNKNOWN ); xWriteCH376Cmd(CMD11_SET_USB_MODE); /* SET USB MODE */ - xWriteCH376Data(0x06); + xWriteCH376Data(CONFIG_CH376_WORK_MODE); up_udelay(20); res = xReadCH376Data(); xEndCH376Cmd(); From 256857b6c5e3948bc2a727790ff4bdaf47dbef46 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 14 Oct 2022 16:57:21 +0800 Subject: [PATCH 08/18] move gpio define to board.h on xidatong-riscv64 --- .../connection/wifi/esp8285_wifi/Kconfig | 2 +- .../xidatong-riscv64/include/board.h | 67 ++++++++++++++++--- .../xidatong-riscv64/src/k210_bringup.c | 4 +- .../xidatong-riscv64/src/k210_ch438.h | 34 +--------- .../xidatong-riscv64/src/k210_gpio.c | 10 +-- .../xidatong-riscv64/src/k210_leds.c | 2 +- 6 files changed, 63 insertions(+), 56 deletions(-) diff --git a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig index 4b3b5b8d9..f44e5d47a 100644 --- a/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig +++ b/APP_Framework/Framework/connection/wifi/esp8285_wifi/Kconfig @@ -5,6 +5,6 @@ config ADAPTER_WIFI_ESP8285 if ADD_NUTTX_FETURES config ADAPTER_ESP8285_DRIVER string "ESP8285 device uart driver path" - default "/dev/ttyS2" + default "/dev/ttyS1" endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index 5677e9855..1a8415a8d 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -39,12 +39,10 @@ * Pre-processor Definitions ****************************************************************************/ -#define BOARD_LED_PAD 14 /* Connected to red led */ + /* Map pad 14 to gpiohs io 0 */ - #define BOARD_LED_IO_FUNC K210_IO_FUNC_GPIOHS0 -#define BOARD_LED_IO 0 #define LED_STARTED 0 /* N/C */ #define LED_HEAPALLOCATE 1 /* N/C */ @@ -79,26 +77,75 @@ extern "C" #define EXTERN extern #endif +/*************************** GPIO define ***************************/ +/* Connected to red led */ +#define BOARD_LED_PAD 14 -#define GPIO_CAN_RXD 18 -#define GPIO_CAN_TXD 19 - +/* UART IO */ +#define GPIO_WIFI_RXD 7 +#define GPIO_WIFI_TXD 6 #define GPIO_EC200T_RXD 21 #define GPIO_EC200T_TXD 20 +#define GPIO_CH376T_RXD 22 +#define GPIO_CH376T_TXD 23 -#define GPIO_CH376T_RXD 22 -#define GPIO_CH376T_TXD 23 +/* ch438 IO */ +#define CH438_ALE_PIN 24 +#define CH438_NWR_PIN 25 +#define CH438_NRD_PIN 26 +#define CH438_D0_PIN 27 +#define CH438_D1_PIN 28 +#define CH438_D2_PIN 29 +#define CH438_D3_PIN 30 +#define CH438_D4_PIN 31 +#define CH438_D5_PIN 32 +#define CH438_D6_PIN 33 +#define CH438_D7_PIN 34 +#define CH438_INT_PIN 35 + +/* other mode io */ +#define GPIO_E220_M0 44 +#define GPIO_E220_M1 45 +#define GPIO_E18_MODE 46 +#define GPIO_WIFI_EN 8 + +/************************** end GPIO define **************************/ +/*************************** FPIOA define ***************************/ +#define BOARD_LED_IO 0 + +/* 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 +/* ch438 FPIOA */ +#define FPIOA_CH438_ALE 11 +#define FPIOA_CH438_NWR 12 +#define FPIOA_CH438_NRD 13 +#define FPIOA_CH438_D0 14 +#define FPIOA_CH438_D1 15 +#define FPIOA_CH438_D2 16 +#define FPIOA_CH438_D3 17 +#define FPIOA_CH438_D4 18 +#define FPIOA_CH438_D5 29 +#define FPIOA_CH438_D6 20 +#define FPIOA_CH438_D7 31 +#define FPIOA_CH438_INT 22 + +/* other mode FPIOA */ +#define FPIOA_E220_M0 1 +#define FPIOA_E220_M1 2 +#define FPIOA_E18_MODE 3 +#define FPIOA_WIFI_EN 4 + +/************************** end FPIOA define **************************/ + + /**************************************************************************** * Public Function Prototypes ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c index 227696b1e..3ad5aea69 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c @@ -90,8 +90,8 @@ int k210_bringup(void) #ifdef CONFIG_K210_16550_UART1 sysctl_clock_enable(SYSCTL_CLOCK_UART1); sysctl_reset(SYSCTL_RESET_UART1); - fpioa_set_function(GPIO_CAN_RXD, FPOA_USART1_RX); - fpioa_set_function(GPIO_CAN_TXD, FPOA_USART1_TX); + fpioa_set_function(GPIO_WIFI_RXD, FPOA_USART1_RX); + fpioa_set_function(GPIO_WIFI_TXD, FPOA_USART1_TX); #endif #ifdef CONFIG_K210_16550_UART2 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h index f952320e8..510e5757b 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_ch438.h @@ -53,6 +53,7 @@ #include #include +#include #include #include "riscv_internal.h" @@ -289,39 +290,6 @@ #define Fpclk 1843200 /* Define the internal clock frequency*/ - -/* Define CH438 PIN NUM */ -#define CH438_ALE_PIN 24 -#define CH438_NWR_PIN 25 -#define CH438_NRD_PIN 26 - -#define CH438_D0_PIN 27 -#define CH438_D1_PIN 28 -#define CH438_D2_PIN 29 -#define CH438_D3_PIN 30 -#define CH438_D4_PIN 31 -#define CH438_D5_PIN 32 -#define CH438_D6_PIN 33 -#define CH438_D7_PIN 34 - -#define CH438_INT_PIN 35 - -/* Define ch438 FPIOA NUMBER */ -#define FPIOA_CH438_ALE 11 -#define FPIOA_CH438_NWR 12 -#define FPIOA_CH438_NRD 13 - -#define FPIOA_CH438_D0 14 -#define FPIOA_CH438_D1 15 -#define FPIOA_CH438_D2 16 -#define FPIOA_CH438_D3 17 -#define FPIOA_CH438_D4 18 -#define FPIOA_CH438_D5 29 -#define FPIOA_CH438_D6 20 -#define FPIOA_CH438_D7 31 - -#define FPIOA_CH438_INT 22 - /* ch438 debug */ #ifdef CONFIG_DEBUG_CH438_ERROR # define ch438err _err diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c index a54b3714d..ab1b880a7 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_gpio.c @@ -34,7 +34,7 @@ #include #include - +#include #include #include "k210_fpioa.h" @@ -48,15 +48,7 @@ /* Pin 1 and 2 are used for this example as GPIO outputs. */ -#define GPIO_E220_M0 44 -#define GPIO_E220_M1 45 -#define GPIO_E18_MODE 46 -#define GPIO_WIFI_EN 8 -#define FPIOA_E220_M0 1 -#define FPIOA_E220_M1 2 -#define FPIOA_E18_MODE 3 -#define FPIOA_WIFI_EN 4 /**************************************************************************** * Private Types diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c index 709d74107..76d1fa14a 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c @@ -25,7 +25,7 @@ #include #include - +#include #include #include "k210_fpioa.h" From ba84afb1799b3f4cb736ab3649dfa845eb30096b Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 14 Oct 2022 18:08:41 +0800 Subject: [PATCH 09/18] add w5500 for xidatong-riscv64 --- .../aiit_board/xidatong-riscv64/Kconfig | 4 + .../xidatong-riscv64/include/board.h | 16 + .../aiit_board/xidatong-riscv64/src/Makefile | 3 + .../xidatong-riscv64/src/k210_bringup.c | 5 - .../xidatong-riscv64/src/k210_leds.c | 1 - .../aiit_board/xidatong-riscv64/src/w5500.c | 683 ++++++++++++++++++ .../aiit_board/xidatong-riscv64/src/w5500.h | 299 ++++++++ 7 files changed, 1005 insertions(+), 6 deletions(-) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.c create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.h diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig index 336704c35..78bb7ffd2 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig @@ -31,6 +31,10 @@ config CH376_WORK_MODE endif # BSP_USING_CH376 +menuconfig BSP_USING_ENET + bool "Using ENET device" + default n + menuconfig BSP_USING_CH438 bool "Using CH438 device" default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index 1a8415a8d..b3b197955 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -103,6 +103,14 @@ extern "C" #define CH438_D7_PIN 34 #define CH438_INT_PIN 35 +/* 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 + /* other mode io */ #define GPIO_E220_M0 44 #define GPIO_E220_M1 45 @@ -137,6 +145,14 @@ extern "C" #define FPIOA_CH438_D7 31 #define FPIOA_CH438_INT 22 +/* w5500 FPIOA */ +#define FPIOA_ENET_NRST 5 +#define FPIOA_ENET_NINT 6 +#define FPIOA_ENET_SCLK 7 +#define FPIOA_ENET_MISO 8 +#define FPIOA_ENET_MOSI 9 +#define FPIOA_ENET_NCS 10 + /* other mode FPIOA */ #define FPIOA_E220_M0 1 #define FPIOA_E220_M1 2 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile index 90a9d8f65..bf7a0eb95 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile @@ -50,4 +50,7 @@ ifeq ($(CONFIG_BSP_USING_CH376),y) CSRCS += k210_ch376.c ch376_demo.c endif +ifeq ($(CONFIG_BSP_USING_ENET),y) +CSRCS += w5500.c +endif include $(TOPDIR)/boards/Board.mk diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c index 3ad5aea69..1fed3801b 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_bringup.c @@ -108,10 +108,5 @@ int k210_bringup(void) fpioa_set_function(GPIO_CH376T_TXD, FPOA_USART3_TX); #endif -#ifdef CONFIG_BSP_USING_ENET - k210_sysctl_init(); - board_enet_initialize(); -#endif - return ret; } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c index 76d1fa14a..5d255a6f4 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_leds.c @@ -24,7 +24,6 @@ #include -#include #include #include diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.c new file mode 100644 index 000000000..720152814 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.c @@ -0,0 +1,683 @@ +/* +* 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 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 "w5500.h" +#include "k210_gpio_common.h" + +/**************************************************************************** + * Private Data + ****************************************************************************/ +w5500_param_t w5500_param; + +/**************************************************************************** + * 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_load_param +*Description: load param to w5500_param +*Input: src: source param +*Output: None +*Return value: None +*******************************************************************************/ +void w5500_load_param(w5500_param_t *src) +{ + w5500_param_t *dest = &w5500_param; + memcpy(dest->ip_addr, src->ip_addr, sizeof(src->ip_addr)); + memcpy(dest->ip_mask, src->ip_mask, sizeof(src->ip_mask)); + memcpy(dest->gw_addr, src->gw_addr, sizeof(src->gw_addr)); + memcpy(dest->mac_addr, src->mac_addr, sizeof(src->mac_addr)); + memcpy(dest->sock.dst_ip, src->sock.dst_ip, sizeof(src->sock.dst_ip)); + dest->sock.local_port = src->sock.local_port; + dest->sock.dst_port = src->sock.dst_port; + dest->sock.mode = src->sock.mode; +} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.h new file mode 100644 index 000000000..ca2e41599 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.h @@ -0,0 +1,299 @@ +/* +* 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 w5500.h +* @brief w5500 driver +* @version 1.0 +* @author AIIT XUOS Lab +* @date 2022-9-15 +*/ + +#ifndef _W5500_H_ +#define _W5500_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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); + +int w5500_net_test(void); + +#endif From f573bc391c768dff5ce0345509ba7c47d9a9201f Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 17 Oct 2022 11:28:16 +0800 Subject: [PATCH 10/18] add w5500 for xidatong-riscv64 --- .../aiit_board/xidatong-riscv64/src/Makefile | 2 +- .../src/{w5500.c => k210_w5500.c} | 176 ++++++++++++++++-- .../src/{w5500.h => k210_w5500.h} | 27 ++- 3 files changed, 185 insertions(+), 20 deletions(-) rename Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/{w5500.c => k210_w5500.c} (78%) rename Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/{w5500.h => k210_w5500.h} (87%) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile index bf7a0eb95..b3bd1fa1f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile @@ -51,6 +51,6 @@ CSRCS += k210_ch376.c ch376_demo.c endif ifeq ($(CONFIG_BSP_USING_ENET),y) -CSRCS += w5500.c +CSRCS += k210_w5500.c endif include $(TOPDIR)/boards/Board.mk diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c similarity index 78% rename from Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.c rename to Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c index 720152814..12cb92c6f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c @@ -11,7 +11,7 @@ */ /** -* @file w5500.c +* @file k210_w5500.c * @brief w5500 driver based on simulated SPI * @version 1.0 * @author AIIT XUOS Lab @@ -19,7 +19,7 @@ */ #include "nuttx/arch.h" -#include "w5500.h" +#include "k210_w5500.h" #include "k210_gpio_common.h" /**************************************************************************** @@ -27,6 +27,18 @@ ****************************************************************************/ w5500_param_t w5500_param; +static uint8_t rx_buf[30]; +static uint8_t tx_buf[30]; + +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 @@ -663,21 +675,155 @@ void w5500_irq_process(void) } /******************************************************************************* -*Function name: w5500_load_param -*Description: load param to w5500_param -*Input: src: source param +*Function name: w5500_intialization +*Description: W5500 initial configuration +*Input: None *Output: None *Return value: None *******************************************************************************/ -void w5500_load_param(w5500_param_t *src) +void w5500_intialization(void) { - w5500_param_t *dest = &w5500_param; - memcpy(dest->ip_addr, src->ip_addr, sizeof(src->ip_addr)); - memcpy(dest->ip_mask, src->ip_mask, sizeof(src->ip_mask)); - memcpy(dest->gw_addr, src->gw_addr, sizeof(src->gw_addr)); - memcpy(dest->mac_addr, src->mac_addr, sizeof(src->mac_addr)); - memcpy(dest->sock.dst_ip, src->sock.dst_ip, sizeof(src->sock.dst_ip)); - dest->sock.local_port = src->sock.local_port; - dest->sock.dst_port = src->sock.dst_port; - dest->sock.mode = src->sock.mode; + 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: None +*******************************************************************************/ +void 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); +} + +/**************************************************************************** + * Name: SPI_Configuration + * Description: spi pin mode configure + * input: None + * output: None + * return:none + ****************************************************************************/ +void SPI_Configuration(void) +{ + /* 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) +{ + uint32_t cnt = 0; + SPI_Configuration(); + w5500_load_param(); + w5500_reset(); + w5500_intialization(); + while(1) + { + w5500_socket_config(); + w5500_irq_process(); + + if((w5500_param.sock.state & SOCK_STAT_RECV) == SOCK_STAT_RECV) + { + w5500_param.sock.state &= ~SOCK_STAT_RECV; + Process_Socket_Data(0); + } + + else if(cnt >= 10) + { + 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); + break; + } + cnt = 0; + } + up_mdelay(1000); + cnt++; + } + } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h similarity index 87% rename from Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.h rename to Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h index ca2e41599..0e8ad87f1 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/w5500.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h @@ -11,15 +11,15 @@ */ /** -* @file w5500.h +* @file k210_w5500.h * @brief w5500 driver * @version 1.0 * @author AIIT XUOS Lab * @date 2022-9-15 */ -#ifndef _W5500_H_ -#define _W5500_H_ +#ifndef _K210_W5500_H_ +#define _K210_W5500_H_ #include #include @@ -294,6 +294,25 @@ typedef unsigned char socket_t; #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); -int w5500_net_test(void); +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); +void Process_Socket_Data(socket_t sock); +void SPI_Configuration(void); #endif From b7a3657c831f3c3a826882e5a8d3dc254183903c Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 17 Oct 2022 17:22:28 +0800 Subject: [PATCH 11/18] add w5500 cmd to nuttx shell --- .../xidatong-riscv64/include/board.h | 12 ++-- .../xidatong-riscv64/src/k210_w5500.c | 69 +++++++++++-------- .../xidatong-riscv64/src/k210_w5500.h | 3 +- .../app_match_nuttx/apps/nshlib/Kconfig | 4 ++ .../app_match_nuttx/apps/nshlib/nsh.h | 4 ++ .../apps/nshlib/nsh_Applicationscmd.c | 13 ++++ .../app_match_nuttx/apps/nshlib/nsh_command.c | 4 ++ 7 files changed, 73 insertions(+), 36 deletions(-) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index b3b197955..32d32f02f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -146,12 +146,12 @@ extern "C" #define FPIOA_CH438_INT 22 /* w5500 FPIOA */ -#define FPIOA_ENET_NRST 5 -#define FPIOA_ENET_NINT 6 -#define FPIOA_ENET_SCLK 7 -#define FPIOA_ENET_MISO 8 -#define FPIOA_ENET_MOSI 9 -#define FPIOA_ENET_NCS 10 +#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 /* other mode FPIOA */ #define FPIOA_E220_M0 1 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c index 12cb92c6f..755404f91 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.c @@ -27,8 +27,8 @@ ****************************************************************************/ w5500_param_t w5500_param; -static uint8_t rx_buf[30]; -static uint8_t tx_buf[30]; +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}; @@ -283,7 +283,7 @@ uint16_t w5500_read_sock_bytes(socket_t sock, uint8_t *dat) uint8_t val; recv_size = w5500_read_sock_short(sock, W5500_SN_RX_RSR_REG); - //no receive data + /* no receive data */ if(recv_size == 0) { return 0; @@ -297,7 +297,7 @@ uint16_t w5500_read_sock_bytes(socket_t sock, uint8_t *dat) recv_addr = w5500_read_sock_short(sock, W5500_SN_RX_RD_REG); write_addr = recv_addr; - //calculate physical address + /* calculate physical address */ recv_addr &= (SOCK_RECV_SIZE - 1); NCS_L(); spi_write_short(recv_addr); @@ -340,7 +340,7 @@ uint16_t w5500_read_sock_bytes(socket_t sock, uint8_t *dat) write_addr += recv_size; w5500_write_sock_short(sock, W5500_SN_RX_RD_REG, write_addr); - //start receive + /* start receive */ w5500_write_sock_byte(sock, W5500_SN_CR_REG, SN_CR_RECV); return recv_size; } @@ -357,7 +357,7 @@ 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 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); @@ -422,7 +422,7 @@ void w5500_reset(void) RST_L(); RST_H(); - //wait connect ok + /* wait connect ok */ while((dat & LINK) == 0) { up_mdelay(500); @@ -442,7 +442,7 @@ void w5500_config_init(void) { uint8_t i = 0; - //software reset, set 1 and auto clear 0 + /* software reset, set 1 and auto clear 0 */ w5500_write_byte(W5500_MR_REG, MR_RST); up_mdelay(100); @@ -451,17 +451,17 @@ void w5500_config_init(void) 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 + /* 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) + /* 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) + /* retry time with 8, when exceed it, produce overtime interrupt, set W5500_SN_IR_REG(TIMEOUT) */ w5500_write_byte(W5500_RCR_REG, 8); } @@ -476,7 +476,7 @@ 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 + /* 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); @@ -488,13 +488,13 @@ uint8_t w5500_detect_gateway(void) return FALSE; } - //set socket connection mode + /* 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 + /* read socket0 interrupt register */ val = w5500_read_sock_byte(0, W5500_SN_IR_REG); if(val != 0) @@ -510,7 +510,7 @@ uint8_t w5500_detect_gateway(void) } else if(w5500_read_sock_byte(0, W5500_SN_DHAR_REG) != 0xff) { - //close socket + /* close socket */ w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE); return TRUE; } @@ -527,7 +527,7 @@ uint8_t w5500_detect_gateway(void) *******************************************************************************/ void w5500_socket_init(socket_t sock) { - //max partition bytes = 30 + /* max partition bytes = 30 */ w5500_write_sock_short(0, W5500_SN_MSSR_REG, 30); switch(sock) @@ -632,7 +632,7 @@ void w5500_irq_process(void) ir_flag = w5500_read_byte(W5500_SIR_REG); do { - //handle socket0 event + /* handle socket0 event */ if((ir_flag & S0_INT) == S0_INT) { sn_flag = w5500_read_sock_byte(0, W5500_SN_IR_REG); @@ -640,13 +640,13 @@ void w5500_irq_process(void) if(sn_flag & IR_CON) { - //socket connection finished + /* socket connection finished */ w5500_param.sock.flag |= SOCK_FLAG_CONN; } if(sn_flag & IR_DISCON) { - //disconnect state + /* disconnect state */ w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE); w5500_socket_init(0); w5500_param.sock.flag = 0; @@ -654,7 +654,7 @@ void w5500_irq_process(void) if(sn_flag & IR_SEND_OK) { - //send one package ok + /* send one package ok */ w5500_param.sock.state |= SOCK_STAT_SEND; } @@ -665,7 +665,7 @@ void w5500_irq_process(void) if(sn_flag & IR_TIMEOUT) { - //close socket, connection failed + /* close socket, connection failed */ w5500_write_sock_byte(0, W5500_SN_CR_REG, SN_CR_CLOSE); w5500_param.sock.flag = 0; } @@ -753,14 +753,17 @@ void w5500_socket_config(void) *Description: W5500 receives and sends the received data *Input: sock: port number *Output: None -*Return value: None +*Return value: receive data length *******************************************************************************/ -void Process_Socket_Data(socket_t sock) +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; + } /**************************************************************************** @@ -772,7 +775,7 @@ void Process_Socket_Data(socket_t sock) ****************************************************************************/ void SPI_Configuration(void) { - /* simluate SPI bus */ + /* 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); @@ -795,7 +798,8 @@ void SPI_Configuration(void) void w5500_test(void) { - uint32_t cnt = 0; + uint8_t cnt = 0; + uint8_t length = 0; SPI_Configuration(); w5500_load_param(); w5500_reset(); @@ -805,24 +809,31 @@ void w5500_test(void) 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; - Process_Socket_Data(0); + length = Process_Socket_Data(0); + printf("w5500 receive: "); + for(int i = 0; i < length; i++) + { + printf("%x ", rx_buf[i]); + } + printf("\n"); } - else if(cnt >= 10) + /* 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); - break; } cnt = 0; } - up_mdelay(1000); + up_mdelay(100); cnt++; } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h index 0e8ad87f1..86e238b03 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_w5500.h @@ -312,7 +312,8 @@ void w5500_irq_process(void); void w5500_intialization(void); void w5500_load_param(void); void w5500_socket_config(void); -void Process_Socket_Data(socket_t sock); +uint16_t Process_Socket_Data(socket_t sock); void SPI_Configuration(void); +void w5500_test(void); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig index e0e603faf..eb17d6b8a 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig @@ -551,6 +551,10 @@ config NSH_DISABLE_CH376 bool "Disable the ch376 demo." default n +config NSH_DISABLE_W5500 + bool "Disable the w5500 demo." + default n + config NSH_DISABLE_CH438 bool "Disable the ch438 demo." default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h index 0df886d26..fbb8043c5 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h @@ -1454,6 +1454,10 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, int cmd_Ch376(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif +#if defined(CONFIG_BSP_USING_ENET) && !defined(CONFIG_NSH_DISABLE_W5500) + int cmd_w5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index 7bac913da..9b7dfa14b 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -51,6 +51,19 @@ int cmd_Ch376(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif +/**************************************************************************** + * Name: cmd_w5500 + ****************************************************************************/ +#if defined(CONFIG_BSP_USING_ENET) && !defined(CONFIG_NSH_DISABLE_W5500) +extern void w5500_test(void); +int cmd_w5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + w5500_test(); + return OK; +} +#endif + /**************************************************************************** * Name: cmd_Ch438 ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c index c0132baf6..c8d5eee23 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c @@ -600,6 +600,10 @@ static const struct cmdmap_s g_cmdmap[] = { "ch376", cmd_Ch376, 1, 1, "[ch376 demo cmd.]" }, #endif +#if defined(CONFIG_BSP_USING_ENET) && !defined(CONFIG_NSH_DISABLE_W5500) + { "w5500", cmd_w5500, 1, 1, "[w5500 demo cmd.]" }, +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) { "ch438", cmd_Ch438, 1, 1, "[ch438 demo cmd.]" }, #endif From deb247165aaedda2bfdd84fb67502d74a01e2ab0 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Mon, 17 Oct 2022 18:16:28 +0800 Subject: [PATCH 12/18] add ch376 and w5500 defconfig --- .../configs/ch376nsh/defconfig | 63 +++++++++++++++++++ .../configs/w5500nsh/defconfig | 61 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/ch376nsh/defconfig create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/w5500nsh/defconfig diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/ch376nsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/ch376nsh/defconfig new file mode 100644 index 000000000..b9aefbaa3 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/ch376nsh/defconfig @@ -0,0 +1,63 @@ +# +# 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_BSP_USING_CH376=y +CONFIG_CH376_USB_FUNCTION=y +CONFIG_CH376_WORK_MODE=0x06 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/w5500nsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/w5500nsh/defconfig new file mode 100644 index 000000000..6075ce1b8 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/w5500nsh/defconfig @@ -0,0 +1,61 @@ +# +# 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_BSP_USING_ENET=y From a4f183c62a7abd724d37f9f8d538dc13668bf083 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 20 Oct 2022 16:35:05 +0800 Subject: [PATCH 13/18] resolve Conflicts --- .../app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index 23157bfeb..bf665058e 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -352,7 +352,7 @@ int cmd_recvzigbee(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif -#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) extern int AdapterWifiTest(int argc, char *argv[]); int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { From df32ed24ed411d55e659418e665c7e6c4759346c Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Thu, 20 Oct 2022 16:45:14 +0800 Subject: [PATCH 14/18] change nsh_Applicationscmd.c --- .../app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index 254255532..1f9bfe2ff 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -389,7 +389,7 @@ int cmd_recvzigbee(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif -#if defined(CONFIG_ADAPTER_ESP07S_WIFI) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) +#if (defined(CONFIG_ADAPTER_ESP07S_WIFI) || defined(CONFIG_ADAPTER_ESP8285_WIFI)) && !defined(CONFIG_NSH_DISABLE_ADAPTER_WIFI_TEST) extern int AdapterWifiTestWithParam(int argc, char *argv[]); int cmd_AdapterWifiTest(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) { From c815bb3b6e8a4b322f8cd690a5f220aff5262dbe Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Fri, 21 Oct 2022 18:13:41 +0800 Subject: [PATCH 15/18] support gpio on k210 on nuttx --- .../nuttx/arch/risc-v/src/k210/k210_gpio.c | 152 ++++++++++------- .../nuttx/arch/risc-v/src/k210/k210_gpio.h | 157 +++++++++++++----- 2 files changed, 206 insertions(+), 103 deletions(-) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c index b79966c01..eb3c0e93e 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.c @@ -39,82 +39,110 @@ #include "k210_memorymap.h" #include "k210_gpio.h" #include "k210_fpioa.h" +#include "k210_sysctl.h" + +#define GPIO_MAX_PINNO 8 /**************************************************************************** - * Pre-processor Definitions + * Private Function declaration ****************************************************************************/ - -#define GPIO_INPUT_VAL_OFFSET 0x00 -#define GPIO_INPUT_EN_OFFSET 0x04 -#define GPIO_OUTPUT_EN_OFFSET 0x08 -#define GPIO_OUTPUT_VAL_OFFSET 0x0c -#define GPIO_PULLUP_EN_OFFSET 0x10 -#define GPIO_DRIVE_OFFSET 0x14 - -#define GPIO_INPUT (K210_GPIO_BASE + GPIO_INPUT_VAL_OFFSET) -#define GPIO_INPUT_EN (K210_GPIO_BASE + GPIO_INPUT_EN_OFFSET) -#define GPIO_OUTPUT (K210_GPIO_BASE + GPIO_OUTPUT_VAL_OFFSET) -#define GPIO_OUTPUT_EN (K210_GPIO_BASE + GPIO_OUTPUT_EN_OFFSET) +static void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value); +static void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value); +static void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value); +static uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset); +static uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset); /**************************************************************************** - * Public Functions + * Private Data ****************************************************************************/ -void k210_gpio_set_direction(uint32_t io, gpio_drive_mode_t mode) +volatile gpio_t *const gpio = (volatile gpio_t *)K210_GPIO_BASE; + +/**************************************************************************** + * Private Function definition + ****************************************************************************/ +static void set_bit(volatile uint32_t *bits, uint32_t mask, uint32_t value) { - DEBUGASSERT(io < K210_GPIO_MAX_PINNO); - int io_number = k210_fpioa_get_io_by_function(K210_IO_FUNC_GPIO0 + io); - DEBUGASSERT(io_number >= 0); - - fpioa_pull_t pull = FPIOA_PULL_NONE; - uint32_t dir = 0; - - switch (mode) - { - case GPIO_DM_INPUT: - pull = FPIOA_PULL_NONE; - dir = 0; - break; - case GPIO_DM_INPUT_PULL_DOWN: - pull = FPIOA_PULL_DOWN; - dir = 0; - break; - case GPIO_DM_INPUT_PULL_UP: - pull = FPIOA_PULL_UP; - dir = 0; - break; - case GPIO_DM_OUTPUT: - pull = FPIOA_PULL_DOWN; - dir = 1; - break; - default: - DEBUGASSERT(!"GPIO drive mode is not supported."); - break; - } - - fpioa_set_io_pull(io_number, pull); - uint32_t outbit = dir << io; - uint32_t inbit = (!dir) << io; - modifyreg32(GPIO_OUTPUT_EN, inbit, outbit); - modifyreg32(GPIO_INPUT_EN, outbit, inbit); + uint32_t org = (*bits) & ~mask; + *bits = org | (value & mask); } -void k210_gpio_set_value(uint32_t io, bool val) +static void set_bit_offset(volatile uint32_t *bits, uint32_t mask, size_t offset, uint32_t value) { - uint32_t setbit = val << io; - uint32_t clrbit = (!val) << io; - modifyreg32(GPIO_OUTPUT, clrbit, setbit); + set_bit(bits, mask << offset, value << offset); } -bool k210_gpio_get_value(uint32_t io) +static void set_gpio_bit(volatile uint32_t *bits, size_t offset, uint32_t value) { - uint32_t reg = getreg32(GPIO_INPUT); + set_bit_offset(bits, 1, offset, value); +} - if (reg & (1 << io)) +static uint32_t get_bit(volatile uint32_t *bits, uint32_t mask, size_t offset) +{ + return ((*bits) & (mask << offset)) >> offset; +} + +static uint32_t get_gpio_bit(volatile uint32_t *bits, size_t offset) +{ + return get_bit(bits, 1, offset); +} + + +/**************************************************************************** + * Public Function definition + ****************************************************************************/ +int gpio_init(void) +{ + return sysctl_clock_enable(SYSCTL_CLOCK_GPIO); +} + +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + int io_number = fpioa_get_io_by_function(K210_IO_FUNC_GPIO0 + pin); + DEBUGASSERT(io_number >= 0); + + fpioa_pull_t pull; + uint32_t dir; + + switch(mode) { - return true; - } - else - { - return false; + case GPIO_DM_INPUT: + pull = FPIOA_PULL_NONE; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_DOWN: + pull = FPIOA_PULL_DOWN; + dir = 0; + break; + case GPIO_DM_INPUT_PULL_UP: + pull = FPIOA_PULL_UP; + dir = 0; + break; + case GPIO_DM_OUTPUT: + pull = FPIOA_PULL_DOWN; + dir = 1; + break; + default: + break; } + + fpioa_set_io_pull(io_number, pull); + set_gpio_bit(gpio->direction.u32, pin, dir); +} + +gpio_pin_value_t gpio_get_pin(uint8_t pin) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + return get_gpio_bit(reg, pin); +} + +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value) +{ + DEBUGASSERT(pin < GPIO_MAX_PINNO); + uint32_t dir = get_gpio_bit(gpio->direction.u32, pin); + volatile uint32_t *reg = dir ? gpio->data_output.u32 : gpio->data_input.u32; + DEBUGASSERT(dir == 1); + set_gpio_bit(reg, pin, value); } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h index 13d98e04d..1ac4a2ef6 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/risc-v/src/k210/k210_gpio.h @@ -38,52 +38,127 @@ #include #include "k210_gpio_common.h" +typedef struct _gpio_bits +{ + uint32_t b0 : 1; + uint32_t b1 : 1; + uint32_t b2 : 1; + uint32_t b3 : 1; + uint32_t b4 : 1; + uint32_t b5 : 1; + uint32_t b6 : 1; + uint32_t b7 : 1; + uint32_t b8 : 1; + uint32_t b9 : 1; + uint32_t b10 : 1; + uint32_t b11 : 1; + uint32_t b12 : 1; + uint32_t b13 : 1; + uint32_t b14 : 1; + uint32_t b15 : 1; + uint32_t b16 : 1; + uint32_t b17 : 1; + uint32_t b18 : 1; + uint32_t b19 : 1; + uint32_t b20 : 1; + uint32_t b21 : 1; + uint32_t b22 : 1; + uint32_t b23 : 1; + uint32_t b24 : 1; + uint32_t b25 : 1; + uint32_t b26 : 1; + uint32_t b27 : 1; + uint32_t b28 : 1; + uint32_t b29 : 1; + uint32_t b30 : 1; + uint32_t b31 : 1; +} __attribute__((packed, aligned(4))) gpio_bits_t; + +/* Structure of templates for accessing GPIO registers */ +typedef union _gpio_access_tp +{ + /* 32x1 bit mode */ + uint32_t u32[1]; + /* 16x2 bit mode */ + uint16_t u16[2]; + /* 8x4 bit mode */ + uint8_t u8[4]; + /* 1 bit mode */ + gpio_bits_t bits; +} __attribute__((packed, aligned(4))) gpio_access_tp_t; + +/* The GPIO address map */ +typedef struct _gpio +{ + /* Offset 0x00: Data (output) registers */ + gpio_access_tp_t data_output; + /* Offset 0x04: Data direction registers */ + gpio_access_tp_t direction; + /* Offset 0x08: Data source registers */ + gpio_access_tp_t source; + /* Offset 0x10 - 0x2f: Unused registers, 9x4 bytes */ + uint32_t unused_0[9]; + /* Offset 0x30: Interrupt enable/disable registers */ + gpio_access_tp_t interrupt_enable; + /* Offset 0x34: Interrupt mask registers */ + gpio_access_tp_t interrupt_mask; + /* Offset 0x38: Interrupt level registers */ + gpio_access_tp_t interrupt_level; + /* Offset 0x3c: Interrupt polarity registers */ + gpio_access_tp_t interrupt_polarity; + /* Offset 0x40: Interrupt status registers */ + gpio_access_tp_t interrupt_status; + /* Offset 0x44: Raw interrupt status registers */ + gpio_access_tp_t interrupt_status_raw; + /* Offset 0x48: Interrupt debounce registers */ + gpio_access_tp_t interrupt_debounce; + /* Offset 0x4c: Registers for clearing interrupts */ + gpio_access_tp_t interrupt_clear; + /* Offset 0x50: External port (data input) registers */ + gpio_access_tp_t data_input; + /* Offset 0x54 - 0x5f: Unused registers, 3x4 bytes */ + uint32_t unused_1[3]; + /* Offset 0x60: Sync level registers */ + gpio_access_tp_t sync_level; + /* Offset 0x64: ID code */ + gpio_access_tp_t id_code; + /* Offset 0x68: Interrupt both edge type */ + gpio_access_tp_t interrupt_bothedge; +} __attribute__((packed, aligned(4))) gpio_t; + +/* Bus GPIO object instance */ +extern volatile gpio_t *const gpio; + /**************************************************************************** * Public Functions Prototypes ****************************************************************************/ +/** + * @brief Gpio initialize + * @return - 0:Success,Other:Fail + */ +int gpio_init(void); -/**************************************************************************** - * Name: k210_gpio_set_direction - * - * Description: - * Set gpiohs direction - * - * Input Parameters: - * io - IO number - * dir - true for output, false for input - * - ****************************************************************************/ +/** + * @brief Set Gpio drive mode + * @param[in] pin Gpio pin + * @param[in] mode Gpio pin drive mode + */ +void gpio_set_drive_mode(uint8_t pin, gpio_drive_mode_t mode); -void k210_gpio_set_direction(uint32_t io, gpio_drive_mode_t mode); +/** + * @brief Get Gpio pin value + * @param[in] pin Gpio pin + * @return Pin value + * GPIO_PV_Low Gpio pin low + * GPIO_PV_High Gpio pin high + */ +gpio_pin_value_t gpio_get_pin(uint8_t pin); -/**************************************************************************** - * Name: k210_gpio_set_value - * - * Description: - * Set gpiohs direction - * - * Input Parameters: - * io - IO number - * dir - true for high level, false for low level - * - ****************************************************************************/ - -void k210_gpio_set_value(uint32_t io, bool val); - -/**************************************************************************** - * Name: k210_gpio_get_value - * - * Description: - * Get gpiohs level - * - * Input Parameters: - * io - IO number - * - * Returned Value: - * true for high level, false for low level - * - ****************************************************************************/ - -bool k210_gpio_get_value(uint32_t io); +/** + * @brief Set Gpio pin value + * @param[in] pin Gpio pin + * @param[in] value Gpio pin value + */ +void gpio_set_pin(uint8_t pin, gpio_pin_value_t value); #endif /* __ARCH_RISCV_SRC_K210_K210_GPIO_H */ From 6794cb03a83dcd87d1ddf2ed51dac3300dcefb50 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 25 Oct 2022 16:27:25 +0800 Subject: [PATCH 16/18] support touch screen for xidatong-riscv64 on nuttx --- .../aiit_board/xidatong-riscv64/Kconfig | 6 +- .../xidatong-riscv64/include/board.h | 8 + .../aiit_board/xidatong-riscv64/src/Makefile | 5 + .../xidatong-riscv64/src/k210_touch.c | 409 ++++++++++++++++++ .../xidatong-riscv64/src/k210_touch.h | 88 ++++ 5 files changed, 515 insertions(+), 1 deletion(-) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig index 78bb7ffd2..a4a4dac80 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/Kconfig @@ -6,7 +6,7 @@ if ARCH_BOARD_XIDATONG_RISCV64 menuconfig BSP_USING_CH376 - bool "Using ch376 device" + bool "Using CH376 device" default n select K210_16550_UART select K210_16550_UART3 @@ -35,6 +35,10 @@ menuconfig BSP_USING_ENET bool "Using ENET device" default n +menuconfig BSP_USING_TOUCH + bool "Using touch device" + default n + menuconfig BSP_USING_CH438 bool "Using CH438 device" default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h index 32d32f02f..5757d2b3f 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/include/board.h @@ -111,6 +111,10 @@ extern "C" #define BSP_ENET_NRST 13 #define BSP_ENET_NINT 14 +/* I2C */ +#define BSP_IIC_SDA 15 +#define BSP_IIC_SCL 17 + /* other mode io */ #define GPIO_E220_M0 44 #define GPIO_E220_M1 45 @@ -153,6 +157,10 @@ extern "C" #define FPIOA_ENET_MOSI 23 #define FPIOA_ENET_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 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile index b3bd1fa1f..04afe7e33 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/Makefile @@ -53,4 +53,9 @@ 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 diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c new file mode 100644 index 000000000..8d79cc121 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c @@ -0,0 +1,409 @@ +/* +* 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" + +/**************************************************************************** + * Name: IIC_Init + * Description: i2c pin mode configure + * input: None + * output: None + * return:none + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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. +********************************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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 + ****************************************************************************/ +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>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 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: GT911_test + * Description: gt911 test code + * input: None + * output: None + * return: Returns true for touch, false for no touch + ***********************************************************************************/ +void GT911_test(void) +{ + uint16_t res; + POINT point = {0, 0}; + IIC_Init(); + res = GT911_ReadFirmwareVersion(); + printf("FirmwareVersion:%2x\n",res); + while(1) + { + if(GT911_Scan(&point)) + { + printf("Now touch point:(%d,%d)\n",point.X,point.X); + } + } +} \ No newline at end of file diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h new file mode 100644 index 000000000..26ad5ed32 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.h @@ -0,0 +1,88 @@ +/* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; +}POINT; + +void IIC_Init(void); +void SDA_IN(void); +void SDA_OUT(void); +uint8_t READ_SDA(void); +void IIC_SCL(uint8_t val); +void IIC_SDA(uint8_t val); +void IIC_Start(void); +void IIC_Stop(void); +uint8_t IIC_Wait_Ack(void); +void IIC_Ack(void); +void IIC_NAck(void); +void IIC_Send_Byte(uint8_t txd); +uint8_t IIC_Read_Byte(uint8_t ack); +bool GT911_Scan(POINT* point); +void GT911_test(void); + +#endif From 490d372b4724e62f302d9434811a66511ea0d583 Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 25 Oct 2022 17:41:08 +0800 Subject: [PATCH 17/18] add touchnsh/defconfig --- .../configs/touchnsh/defconfig | 63 +++++++++++++++++++ .../app_match_nuttx/apps/nshlib/Kconfig | 4 ++ .../app_match_nuttx/apps/nshlib/nsh.h | 4 ++ .../apps/nshlib/nsh_Applicationscmd.c | 13 ++++ .../app_match_nuttx/apps/nshlib/nsh_command.c | 4 ++ 5 files changed, 88 insertions(+) create mode 100644 Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig new file mode 100644 index 000000000..67f5f8c4a --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/configs/touchnsh/defconfig @@ -0,0 +1,63 @@ +# +# 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_16550_UART=y +CONFIG_K210_16550_UART3=y +CONFIG_BSP_USING_TOUCH=y diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig index eb17d6b8a..fcffc9750 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/Kconfig @@ -555,6 +555,10 @@ config NSH_DISABLE_W5500 bool "Disable the w5500 demo." default n +config NSH_DISABLE_TOUCH + bool "Disable the gt911 touch screen demo." + default n + config NSH_DISABLE_CH438 bool "Disable the ch438 demo." default n diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h index a7ddcb302..918ba31a7 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh.h @@ -1458,6 +1458,10 @@ int nsh_foreach_var(FAR struct nsh_vtbl_s *vtbl, nsh_foreach_var_t cb, int cmd_w5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif +#if defined(CONFIG_BSP_USING_TOUCH) && !defined(CONFIG_NSH_DISABLE_TOUCH) + int cmd_Touch(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) int cmd_Ch438(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c index 1f9bfe2ff..820d3360d 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_Applicationscmd.c @@ -64,6 +64,19 @@ int cmd_w5500(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) } #endif +/**************************************************************************** + * Name: cmd_Touch + ****************************************************************************/ +#if defined(CONFIG_BSP_USING_TOUCH) && !defined(CONFIG_NSH_DISABLE_TOUCH) +extern void GT911_test(void); +int cmd_Touch(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + nsh_output(vtbl, "Hello, world!\n"); + GT911_test(); + return OK; +} +#endif + /**************************************************************************** * Name: cmd_Ch438 ****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c index 4f2486cd5..1b03f5cc9 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/apps/nshlib/nsh_command.c @@ -604,6 +604,10 @@ static const struct cmdmap_s g_cmdmap[] = { "w5500", cmd_w5500, 1, 1, "[w5500 demo cmd.]" }, #endif +#if defined(CONFIG_BSP_USING_TOUCH) && !defined(CONFIG_NSH_DISABLE_TOUCH) + { "touch", cmd_Touch, 1, 1, "[gt911 touch screen demo cmd.]" }, +#endif + #if defined(CONFIG_BSP_USING_CH438) && !defined(CONFIG_NSH_DISABLE_CH438) { "ch438", cmd_Ch438, 1, 1, "[ch438 demo cmd.]" }, #endif From a04a4288a767606205e57106e44585eb63a2b45c Mon Sep 17 00:00:00 2001 From: wgzAIIT <820906721@qq.com> Date: Tue, 25 Oct 2022 18:21:32 +0800 Subject: [PATCH 18/18] add printf point.x and point.y in test case --- .../aiit_board/xidatong-riscv64/src/k210_touch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c index 8d79cc121..4649cf1d4 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/xidatong-riscv64/src/k210_touch.c @@ -403,7 +403,7 @@ void GT911_test(void) { if(GT911_Scan(&point)) { - printf("Now touch point:(%d,%d)\n",point.X,point.X); + printf("Now touch point:(%d,%d)\n",point.X,point.Y); } } } \ No newline at end of file