diff --git a/APP_Framework/Applications/Makefile b/APP_Framework/Applications/Makefile index 118c80ac5..6780a2b27 100644 --- a/APP_Framework/Applications/Makefile +++ b/APP_Framework/Applications/Makefile @@ -35,5 +35,9 @@ ifeq ($(CONFIG_ADD_XIZI_FETURES),y) SRC_DIR += control_app endif + ifeq ($(CONFIG_APP_USING_WEBNET),y) + SRC_DIR += webnet + endif + include $(KERNEL_ROOT)/compiler.mk endif \ No newline at end of file diff --git a/APP_Framework/Applications/webnet/Kconfig b/APP_Framework/Applications/webnet/Kconfig index 812518e11..692261c4e 100644 --- a/APP_Framework/Applications/webnet/Kconfig +++ b/APP_Framework/Applications/webnet/Kconfig @@ -1,5 +1,5 @@ menuconfig APP_USING_WEBNET - bool "WebNet: A lightweight, customizable, embeddable Web Server for RT-Thread" + bool "WebNet: A lightweight, customizable, embeddable Web Server for XiUOS" default n if APP_USING_WEBNET @@ -25,31 +25,31 @@ if APP_USING_WEBNET config WEBNET_USING_LOG bool "LOG: Enable output log support" - default n + default y config WEBNET_USING_AUTH bool "AUTH: Enable basic HTTP authentication support" - default n + default y config WEBNET_USING_CGI bool "CGI: Enable Common Gateway Interface support" - default n + default y config WEBNET_USING_ASP bool "ASP: Enable Active Server Pages support" - default n + default y config WEBNET_USING_SSI bool "SSI: Enable Server Side Includes support" - default n + default y config WEBNET_USING_INDEX bool "INDEX: Enable list all the file in the directory support" - default n + default y config WEBNET_USING_ALIAS bool "ALIAS: Enable alias support" - default n + default y config WEBNET_USING_DAV bool "DAV: Enable Web-based Distributed Authoring and Versioning support" @@ -57,7 +57,7 @@ if APP_USING_WEBNET config WEBNET_USING_UPLOAD bool "UPLOAD: Enable upload file support" - default n + default y config WEBNET_USING_GZIP bool "GZIP: Enable compressed file support by GZIP" @@ -65,11 +65,10 @@ if APP_USING_WEBNET config WEBNET_CACHE_LEVEL int "CACHE: Configure cache level(0:disable 1:use Last-Modified 2:use Cache-Control)" - default 0 + default 2 range 0 2 - if WEBNET_CACHE_LEVEL = 2 - + if WEBNET_CACHE_LEVEL = 2 config WEBNET_CACHE_MAX_AGE int "Cache-Control time in seconds" default 1800 @@ -80,7 +79,7 @@ if APP_USING_WEBNET config WEBNET_USING_SAMPLES bool "Enable webnet samples" - default n + default y select WEBNET_USING_ASP select WEBNET_USING_AUTH select WEBNET_USING_CGI diff --git a/APP_Framework/Framework/transform_layer/rtthread/transform.c b/APP_Framework/Framework/transform_layer/rtthread/transform.c index 42872041a..c17005e00 100644 --- a/APP_Framework/Framework/transform_layer/rtthread/transform.c +++ b/APP_Framework/Framework/transform_layer/rtthread/transform.c @@ -237,3 +237,10 @@ void PrivTaskexitCritical() { rt_exit_critical(); } + +/*********************tick**********************/ +#ifdef APP_USING_WEBNET +int PriGetTick(){ + return rt_tick_get()/RT_TICK_PER_SECOND; +} +#endif \ No newline at end of file diff --git a/APP_Framework/Framework/transform_layer/rtthread/transform.h b/APP_Framework/Framework/transform_layer/rtthread/transform.h index e24bf0552..80a13a7d3 100644 --- a/APP_Framework/Framework/transform_layer/rtthread/transform.h +++ b/APP_Framework/Framework/transform_layer/rtthread/transform.h @@ -239,6 +239,10 @@ void PrivTaskenterCritical(); void PrivTaskexitCritical(); +/*********************tick**********************/ +#ifdef APP_USING_WEBNET +int PriGetTick(); +#endif #ifdef __cplusplus } diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.c b/APP_Framework/Framework/transform_layer/xizi/transform.c index f2d53d155..7e6128020 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.c +++ b/APP_Framework/Framework/transform_layer/xizi/transform.c @@ -204,3 +204,24 @@ void PrivFree(void *pointer) UserFree(pointer); } + +/*********************massage queue***********************/ +mqd_t PrivMqueueSend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio) +{ + return mq_send(mqdes, msg_ptr, msg_len, msg_prio); +} + +mqd_t PrivMqueueCreate(const char *name, int oflag, mode_t mode, struct mq_attr *attr) +{ + return mq_open(name, oflag, mode, attr); +} + +int PrivMqueueReceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio) +{ + return mq_receive(mqdes, msg_ptr, msg_len, msg_prio); +} + +/*********************tick**********************/ +int PriGetTick(){ + return CurrentTicksGain() / TICK_PER_SECOND; +} \ No newline at end of file diff --git a/APP_Framework/Framework/transform_layer/xizi/transform.h b/APP_Framework/Framework/transform_layer/xizi/transform.h index 7514d9297..651192052 100644 --- a/APP_Framework/Framework/transform_layer/xizi/transform.h +++ b/APP_Framework/Framework/transform_layer/xizi/transform.h @@ -29,6 +29,16 @@ #include #include #include +#include + +#ifdef APP_USING_WEBNET +#include "sys_arch.h" +#include +#include "lwip/sys.h" +#include +#include +#include +#endif #ifdef __cplusplus extern "C" { @@ -93,6 +103,14 @@ extern "C" { #define SERIAL_RB_BUFSZ 128 #endif +#ifdef APP_USING_WEBNET + +#define bool _Bool +#define FALSE 0 +#define TRUE 1 + +#endif + struct PinDevIrq { int irq_mode;//< RISING/FALLING/HIGH/LOW @@ -295,6 +313,16 @@ void *PrivRealloc(void *pointer, size_t size); void *PrivCalloc(size_t count, size_t size); void PrivFree(void *pointer); +/*********************massage queue***********************/ + +mqd_t PrivMqueueSend(mqd_t mqdes, const char *msg_ptr, size_t msg_len, unsigned msg_prio); +mqd_t PrivMqueueCreate(const char *name, int oflag, mode_t mode,struct mq_attr *attr); +int PrivMqueueReceive(mqd_t mqdes, char *msg_ptr, size_t msg_len, unsigned *msg_prio); + + +/*********************tick**********************/ +int PriGetTick(); + #ifdef __cplusplus } diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h index efe995dc7..917b3fa66 100644 --- a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/include/pthread.h @@ -69,6 +69,19 @@ typedef int pid_t; #define SCHED_RR 2 #define SCHED_IDLE 5 +/*from rt added by zy*/ +#define DEFAULT_STACK_SIZE 4096 +#define DEFAULT_PRIORITY KTASK_PRIORITY_MAX / 2 +#define PTHREAD_CREATE_JOINABLE 0x00 +#define PTHREAD_INHERIT_SCHED 1 + +/* function in pthread.c */ +/*support webnet*/ +int pthread_attr_init(pthread_attr_t *attr); +int pthread_attr_setschedparam(pthread_attr_t *attr, + struct sched_param const *param); +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size); + /* function in pthread.c */ int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void)); int pthread_create(pthread_t *thread, const pthread_attr_t *attr, diff --git a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/pthread.c b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/pthread.c index 3b8b170fd..ab254d93f 100644 --- a/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/pthread.c +++ b/APP_Framework/Framework/transform_layer/xizi/user_api/posix_support/pthread.c @@ -21,6 +21,45 @@ #include #include #include "include/pthread.h" +#include +const pthread_attr_t pthread_default_attr = +{ + 0, /* stack base */ + 0, + DEFAULT_STACK_SIZE, /* stack size */ + 0, + PTHREAD_INHERIT_SCHED, /* Inherit parent prio/policy */ + SCHED_FIFO, /* scheduler policy */ + { + DEFAULT_PRIORITY, /* scheduler priority */ + }, + 4096, + PTHREAD_CREATE_JOINABLE, /* detach state */ +}; + + +int pthread_attr_init(pthread_attr_t *attr) +{ + assert(attr != NULL); + *attr = pthread_default_attr; + return 0; +} + +int pthread_attr_setschedparam(pthread_attr_t *attr, + struct sched_param const *param) +{ + assert(attr != NULL); + assert(param != NULL); + attr->schedparam.sched_priority = param->sched_priority; + return 0; +} + +int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stack_size) +{ + assert(attr != NULL); + attr->stacksize = stack_size; + return 0; +} int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/Kconfig index 2f9dcfc49..bf3959038 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/Kconfig @@ -11,4 +11,27 @@ config HC32F4A0_BOARD ---help--- Select if you are using the HC32F4A0 base board with the HC32F4A0. +config HC32_ROMFS + bool "Automount baked-in ROMFS image" + default n + depends on FS_ROMFS + ---help--- + Select HC32_ROMFS_IMAGEFILE, HC32_ROMFS_DEV_MINOR, HC32_ROMFS_MOUNTPOINT + +config HC32_ROMFS_DEV_MINOR + int "Minor for the block device backing the data" + depends on HC32_ROMFS + default 64 + +config HC32_ROMFS_MOUNTPOINT + string "Mountpoint of the custom romfs image" + depends on HC32_ROMFS + default "/rom" + +config HC32_ROMFS_IMAGEFILE + string "ROMFS image file to include into build" + depends on HC32_ROMFS + default "../../../../../rom.img" + + endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/include/board.h index 2d25e1e8d..343719cad 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/include/board.h @@ -57,38 +57,42 @@ /* for lowputc device output */ /* UART RX/TX Port/Pin definition */ -#define LP_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */ -#define LP_RX_PIN (GPIO_PIN_06) -#define LP_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX) +#define DBG_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */ +#define DBG_RX_PIN (GPIO_PIN_06) +#define DBG_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX) -#define LP_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */ -#define LP_TX_PIN (GPIO_PIN_06) -#define LP_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX) +#define DBG_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */ +#define DBG_TX_PIN (GPIO_PIN_06) +#define DBG_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX) /* UART unit definition */ -#define LP_UNIT (M4_USART6) -#define LP_FUNCTION_CLK_GATE (PWC_FCG3_USART6) +#define DBG_UNIT (M4_USART6) +#define DBG_BAUDRATE (115200UL) +#define DBG_FUNCTION_CLK_GATE (PWC_FCG3_USART6) /* UART unit interrupt definition */ -#define LP_UNIT_ERR_INT_SRC (INT_USART6_EI) -#define LP_UNIT_ERR_INT_IRQn (Int015_IRQn + HC32_IRQ_FIRST) +#define DBG_UNIT_ERR_INT_SRC (INT_USART6_EI) +#define DBG_UNIT_ERR_INT_IRQn (Int010_IRQn) -#define LP_UNIT_RX_INT_SRC (INT_USART6_RI) -#define LP_UNIT_RX_INT_IRQn (Int103_IRQn + HC32_IRQ_FIRST) +#define DBG_UNIT_RX_INT_SRC (INT_USART6_RI) +#define DBG_UNIT_RX_INT_IRQn (Int011_IRQn) -#define LP_UNIT_TX_INT_SRC (INT_USART6_TI) -#define LP_UNIT_TX_INT_IRQn (Int102_IRQn + HC32_IRQ_FIRST) +#define DBG_RXTO_INT_SRC (INT_USART6_RTO) +#define DBG_RXTO_INT_IRQn (Int012_IRQn) -#define LP_UNIT_TCI_INT_SRC (INT_USART6_TCI) -#define LP_UNIT_TCI_INT_IRQn (Int099_IRQn + HC32_IRQ_FIRST) +#define DBG_UNIT_TX_INT_SRC (INT_USART6_TI) +#define DBG_UNIT_TX_INT_IRQn (Int013_IRQn) + +#define DBG_UNIT_TCI_INT_SRC (INT_USART6_TCI) +#define DBG_UNIT_TCI_INT_IRQn (Int014_IRQn) /* printf device s*/ -#define BSP_PRINTF_DEVICE LP_UNIT -#define BSP_PRINTF_BAUDRATE (115200) +#define BSP_PRINTF_DEVICE DBG_UNIT +#define BSP_PRINTF_BAUDRATE DBG_BAUDRATE -#define BSP_PRINTF_PORT LP_TX_PORT +#define BSP_PRINTF_PORT DBG_TX_PORT -#define BSP_PRINTF_PIN LP_TX_PIN -#define BSP_PRINTF_PORT_FUNC LP_TX_GPIO_FUNC +#define BSP_PRINTF_PIN DBG_TX_PIN +#define BSP_PRINTF_PORT_FUNC DBG_TX_GPIO_FUNC #endif /* __BOARDS_ARM_HC32_HC32F4A0_INCLUDE_BOARD_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/Makefile b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/Makefile index 16096091d..42dd1dd06 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/Makefile +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/Makefile @@ -41,7 +41,7 @@ USER_LIBGCC = "${shell "$(CC)" $(ARCHCPUFLAGS) -print-libgcc-file-name}" # Source files -CSRCS = stm32_userspace.c +CSRCS = hc32_userspace.c COBJS = $(CSRCS:.c=$(OBJEXT)) OBJS = $(COBJS) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/hc32_userspace.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/hc32_userspace.c index 966de7345..0fe0f7753 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/hc32_userspace.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/kernel/hc32_userspace.c @@ -52,7 +52,7 @@ # error "CONFIG_NUTTX_USERSPACE not defined" #endif -#if CONFIG_NUTTX_USERSPACE != 0x20060000 +#if CONFIG_NUTTX_USERSPACE != 0x20062000 # error "CONFIG_NUTTX_USERSPACE must be 0x20060000 to match memory.ld" #endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/gnu-elf.ld b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/gnu-elf.ld index 1b588c8c6..d951eff23 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/gnu-elf.ld +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/gnu-elf.ld @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/stm32/aiit-arm32-board/scripts/gnu-elf.ld + * boards/arm/hc32/hc32f4a0/scripts/gnu-elf.ld * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/kernel-space.ld b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/kernel-space.ld index 82221aada..000ce6b07 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/kernel-space.ld +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/kernel-space.ld @@ -1,5 +1,5 @@ /**************************************************************************** - * boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld + * boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/memory.ld b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/memory.ld index 2afc1f9ef..c65f11e4b 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/memory.ld +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/memory.ld @@ -32,7 +32,7 @@ * For MPU support, the kernel-mode NuttX section is assumed to be 128Kb of * FLASH and 4Kb of SRAM. That is an excessive amount for the kernel which * should fit into 64KB and, of course, can be optimized as needed (See - * also boards/arm/stm32/aiit-arm32-board/scripts/kernel-space.ld). Allowing the + * also boards/arm/hc32/hc32f4a0/scripts/kernel-space.ld). Allowing the * additional does permit addition debug instrumentation to be added to the * kernel space without overflowing the partition. * @@ -73,13 +73,13 @@ MEMORY { /* 2Mb FLASH */ - kflash (rx) : ORIGIN = 0x00000000, LENGTH = 2M - uflash (rx) : ORIGIN = 0x00200000, LENGTH = 128K - xflash (rx) : ORIGIN = 0x00220000, LENGTH = 768K + kflash (rx) : ORIGIN = 0x00000000, LENGTH = 64K + uflash (rx) : ORIGIN = 0x00010000, LENGTH = 1M + xflash (rx) : ORIGIN = 0x00110000, LENGTH = 128K /* 512Kb of contiguous SRAM */ - ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 512K - usram (rwx) : ORIGIN = 0x20060000, LENGTH = 4K - xsram (rwx) : ORIGIN = 0x20062000, LENGTH = 4K + ksram (rwx) : ORIGIN = 0x1FFE0000, LENGTH = 64K + usram (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 448K + xsram (rwx) : ORIGIN = 0x20070000, LENGTH = 4K } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/user-space.ld b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/user-space.ld index ee800d72d..c71b0297c 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/user-space.ld +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/scripts/user-space.ld @@ -48,16 +48,16 @@ SECTIONS _sinit = ABSOLUTE(.); *(.init_array .init_array.*) _einit = ABSOLUTE(.); - } > kflash + } > uflash .ARM.extab : { *(.ARM.extab*) - } > kflash + } > uflash __exidx_start = ABSOLUTE(.); .ARM.exidx : { *(.ARM.exidx*) - } > kflash + } > uflash __exidx_end = ABSOLUTE(.); @@ -70,7 +70,7 @@ SECTIONS CONSTRUCTORS . = ALIGN(4); _edata = ABSOLUTE(.); - } > ksram AT > kflash + } > usram AT > uflash .bss : { _sbss = ABSOLUTE(.); @@ -79,7 +79,7 @@ SECTIONS *(COMMON) . = ALIGN(4); _ebss = ABSOLUTE(.); - } > ksram + } > usram /* Stabs debugging sections */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/Make.defs b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/Make.defs index aaf7da6ee..37a78f333 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/Make.defs +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/Make.defs @@ -26,6 +26,10 @@ ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += endif +ifeq ($(CONFIG_STM32_ROMFS),y) +CSRCS += hc32_romfs_initialize.c +endif + DEPPATH += --dep-path board VPATH += :board CFLAGS += $(shell $(INCDIR) "$(CC)" $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)board$(DELIM)board) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_boot.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_boot.c index 274d03360..e75aed9f1 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_boot.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_boot.c @@ -38,6 +38,7 @@ ****************************************************************************/ extern int hc32_bringup(void); +extern int hc32_spidev_initialized; /**************************************************************************** * Name: hc32_boardinitialize @@ -52,57 +53,57 @@ extern int hc32_bringup(void); void hc32_boardinitialize(void) { -//#ifdef CONFIG_SCHED_CRITMONITOR -// /* Enable ITM and DWT resources, if not left enabled by debugger. */ -// -// modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA); -// -// /* Make sure the high speed cycle counter is running. It will be started -// * automatically only if a debugger is connected. -// */ -// -// putreg32(0xc5acce55, ITM_LAR); -// modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK); -//#endif -// -//#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3) -// /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak -// * function hc32_spidev_initialize() has been brought into the link. -// */ -// -// if (hc32_spidev_initialize) -// { -// hc32_spidev_initialize(); -// } -//#endif -// -//#ifdef CONFIG_HC32_OTGFS -// /* Initialize USB if the 1) OTG FS controller is in the configuration and -// * 2) disabled, and 3) the weak function hc32_usbinitialize() has been -// * brought into the build. Presumably either CONFIG_USBDEV or -// * CONFIG_USBHOST is also selected. -// */ -// -// if (hc32_usbinitialize) -// { -// hc32_usbinitialize(); -// } -//#endif -// -//#ifdef HAVE_NETMONITOR -// /* Configure board resources to support networking. */ -// -// if (hc32_netinitialize) -// { -// hc32_netinitialize(); -// } -//#endif -// -//#ifdef CONFIG_ARCH_LEDS -// /* Configure on-board LEDs if LED support has been selected. */ -// -// board_autoled_initialize(); -//#endif +#ifdef CONFIG_SCHED_CRITMONITOR + /* Enable ITM and DWT resources, if not left enabled by debugger. */ + + modifyreg32(NVIC_DEMCR, 0, NVIC_DEMCR_TRCENA); + + /* Make sure the high speed cycle counter is running. It will be started + * automatically only if a debugger is connected. + */ + + putreg32(0xc5acce55, ITM_LAR); + modifyreg32(DWT_CTRL, 0, DWT_CTRL_CYCCNTENA_MASK); +#endif + +#if defined(CONFIG_HC32_SPI1) || defined(CONFIG_HC32_SPI2) || defined(CONFIG_HC32_SPI3) + /* Configure SPI chip selects if 1) SPI is not disabled, and 2) the weak + * function hc32_spidev_initialize() has been brought into the link. + */ + + if (hc32_spidev_initialized) + { + hc32_spidev_initialize(); + } +#endif + +#ifdef CONFIG_HC32_OTGFS + /* Initialize USB if the 1) OTG FS controller is in the configuration and + * 2) disabled, and 3) the weak function hc32_usbinitialize() has been + * brought into the build. Presumably either CONFIG_USBDEV or + * CONFIG_USBHOST is also selected. + */ + + if (hc32_usbinitialize) + { + hc32_usbinitialize(); + } +#endif + +#ifdef HAVE_NETMONITOR + /* Configure board resources to support networking. */ + + if (hc32_netinitialize) + { + hc32_netinitialize(); + } +#endif + +#ifdef CONFIG_ARCH_LEDS + /* Configure on-board LEDs if LED support has been selected. */ + + board_autoled_initialize(); +#endif } /**************************************************************************** diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_bringup.c index dd768fd85..9ea9d7fde 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_bringup.c @@ -31,6 +31,8 @@ #include +#include + /**************************************************************************** * Name: hc32_bringup * @@ -48,6 +50,27 @@ int hc32_bringup(void) { int ret = 0; + +#ifdef CONFIG_FS_PROCFS + /* Mount the procfs file system */ + + ret = nx_mount(NULL, HC32_PROCFS_MOUNTPOINT, "procfs", 0, NULL); + if (ret < 0) + { + serr("ERROR: Failed to mount procfs at %s: %d\n", + HC32_PROCFS_MOUNTPOINT, ret); + } +#endif + +#ifdef CONFIG_HC32_ROMFS + ret = hc32_romfs_initialize(); + if (ret < 0) + { + serr("ERROR: Failed to mount romfs at %s: %d\n", + CONFIG_HC32_ROMFS_MOUNTPOINT, ret); + } +#endif + printf("start %s\n", __func__); return ret; } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_romfs.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_romfs.h new file mode 100755 index 000000000..b8297d570 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_romfs.h @@ -0,0 +1,76 @@ +/**************************************************************************** + * boards/arm/hc32/hc32f4a0/src/hc32_romfs.h + * + * Copyright (C) 2017 Tomasz Wozniak. All rights reserved. + * Author: Tomasz Wozniak + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#ifndef __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H +#define __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#ifdef CONFIG_HC32_ROMFS + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ROMFS_SECTOR_SIZE 64 + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Name: stm32_romfs_initialize + * + * Description: + * Registers built-in ROMFS image as block device and mounts it. + * + * Returned Value: + * Zero (OK) on success, a negated errno value on error. + * + * Assumptions/Limitations: + * Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain + * ROMFS volume data, as included in the assembly snippet above (l. 84). + * + ****************************************************************************/ + +int hc32_romfs_initialize(void); + +#endif /* CONFIG_STM32_ROMFS */ + +#endif /* __BOARDS_ARM_HC32_HC32F4A0_SRC_HC32_ROMFS_H */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_romfs_initialize.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_romfs_initialize.c new file mode 100755 index 000000000..4723ce40b --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/hc32f4a0/src/hc32_romfs_initialize.c @@ -0,0 +1,158 @@ +/**************************************************************************** + * boards/arm/hc32/hc32f4a0/src/hc32_romfs_initialize.c + * This file provides contents of an optional ROMFS volume, mounted at boot. + * + * Copyright (C) 2017 Tomasz Wozniak. All rights reserved. + * Author: Tomasz Wozniak + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include "hc32_romfs.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#ifndef CONFIG_HC32_ROMFS +# error "CONFIG_HC32_ROMFS must be defined" +#else + +#ifndef CONFIG_HC32_ROMFS_IMAGEFILE +# error "CONFIG_HC32_ROMFS_IMAGEFILE must be defined" +#endif + +#ifndef CONFIG_HC32_ROMFS_DEV_MINOR +# error "CONFIG_HC32_ROMFS_DEV_MINOR must be defined" +#endif + +#ifndef CONFIG_HC32_ROMFS_MOUNTPOINT +# error "CONFIG_HC32_ROMFS_MOUNTPOINT must be defined" +#endif + +#define NSECTORS(size) (((size) + ROMFS_SECTOR_SIZE - 1)/ROMFS_SECTOR_SIZE) + +#define STR2(m) #m +#define STR(m) STR2(m) + +#define MKMOUNT_DEVNAME(m) "/dev/ram" STR(m) +#define MOUNT_DEVNAME MKMOUNT_DEVNAME(CONFIG_HC32_ROMFS_DEV_MINOR) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +__asm__ ( + ".section .rodata\n" + ".balign 16\n" + ".globl romfs_data_begin\n" +"romfs_data_begin:\n" + ".incbin " STR(CONFIG_HC32_ROMFS_IMAGEFILE) "\n"\ + \ + ".balign " STR(ROMFS_SECTOR_SIZE) "\n" + ".globl romfs_data_end\n" +"romfs_data_end:\n" + ".globl romfs_data_size\n" +"romfs_data_size:\n" + ".word romfs_data_end - romfs_data_begin\n" + ".previous\n"); + +extern const char romfs_data_begin; +extern const char romfs_data_end; +extern const int romfs_data_size; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: hc32_romfs_initialize + * + * Description: + * Registers the aboveincluded binary file as block device. + * Then mounts the block device as ROMFS filesystems. + * + * Returned Value: + * Zero (OK) on success, a negated errno value on error. + * + * Assumptions/Limitations: + * Memory addresses [&romfs_data_begin .. &romfs_data_begin) should contain + * ROMFS volume data, as included in the assembly snippet above (l. 84). + * + ****************************************************************************/ + +int hc32_romfs_initialize(void) +{ + uintptr_t romfs_data_len; + int ret; + + /* Create a ROM disk for the /etc filesystem */ + + romfs_data_len = (uintptr_t)&romfs_data_end - (uintptr_t)&romfs_data_begin; + + ret = romdisk_register(CONFIG_HC32_ROMFS_DEV_MINOR, &romfs_data_begin, + NSECTORS(romfs_data_len), ROMFS_SECTOR_SIZE); + if (ret < 0) + { + ferr("ERROR: romdisk_register failed: %d\n", -ret); + return ret; + } + + /* Mount the file system */ + + finfo("Mounting ROMFS filesystem at target=%s with source=%s\n", + CONFIG_HC32_ROMFS_MOUNTPOINT, MOUNT_DEVNAME); + + ret = nx_mount(MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT, + "romfs", MS_RDONLY, NULL); + if (ret < 0) + { + ferr("ERROR: nx_mount(%s,%s,romfs) failed: %d\n", + MOUNT_DEVNAME, CONFIG_HC32_ROMFS_MOUNTPOINT, ret); + return ret; + } + + return OK; +} + +#endif /* CONFIG_HC32_ROMFS */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Kconfig b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Kconfig index d70f8ea1c..c1c3ebc02 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Kconfig +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Kconfig @@ -172,3 +172,26 @@ config HC32_UART8 endmenu # HC32 U[S]ART Selection +config HC32_SPI1 + bool "SPI1" + default n + select SPI + select HC32_SPI + +config HC32_SPI2 + bool "SPI2" + default n + depends on HC32_HAVE_SPI2 + select SPI + select HC32_SPI + + +config HC32_SPI + bool + +config HC32_I2C + bool + +config HC32_CAN + bool + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Make.defs b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Make.defs index 9c2eba33a..b85737cb1 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Make.defs +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/Make.defs @@ -44,7 +44,6 @@ CMN_ASRCS += arm_lazyexception.S else CMN_ASRCS += arm_exception.S endif -CMN_CSRCS += arm_vectors.c ifeq ($(CONFIG_ARCH_RAMVECTORS),y) CMN_CSRCS += arm_ramvec_initialize.c arm_ramvec_attach.c @@ -77,12 +76,19 @@ ifeq ($(CONFIG_SCHED_THREAD_LOCAL),y) CMN_CSRCS += arm_tls.c endif +CMN_CSRCS += hc32_vectors.c + CHIP_CSRCS = hc32_allocateheap.c hc32_gpio.c CHIP_CSRCS += hc32_irq.c hc32_idle.c hc32_mpuinit.c CHIP_CSRCS += hc32_rcc.c hc32_start.c hc32_serial.c CHIP_CSRCS += hc32_pm.c hc32_timerisr.c hc32_lowputc.c +CHIP_CSRCS += hc32_console.c CHIP_CSRCS += hc32f4a0_clk.c hc32f4a0_efm.c hc32f4a0_gpio.c CHIP_CSRCS += hc32f4a0_interrupts.c hc32f4a0_usart.c hc32f4a0_utility.c CHIP_CSRCS += hc32f4a0_sram.c hc32f4a0_pwc.c +CHIP_CSRCS += hc32f4a0_spi.c + +CHIP_CSRCS += hc32_spiflash.c hc32_spi.c + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/ddl_config.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/ddl_config.h index 6706dd9af..692f850d7 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/ddl_config.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/ddl_config.h @@ -89,7 +89,7 @@ extern "C" #define DDL_RTC_ENABLE (DDL_OFF) #define DDL_SDIOC_ENABLE (DDL_OFF) #define DDL_SMC_ENABLE (DDL_OFF) -#define DDL_SPI_ENABLE (DDL_OFF) +#define DDL_SPI_ENABLE (DDL_ON) #define DDL_SRAM_ENABLE (DDL_ON) #define DDL_SWDT_ENABLE (DDL_OFF) #define DDL_TMR0_ENABLE (DDL_OFF) @@ -134,7 +134,7 @@ extern "C" #define BSP_OV5640_ENABLE (BSP_OFF) #define BSP_S29GL064N90TFI03_ENABLE (BSP_OFF) #define BSP_TCA9539_ENABLE (BSP_OFF) -#define BSP_W25QXX_ENABLE (BSP_ON) +#define BSP_W25QXX_ENABLE (BSP_OFF) #define BSP_WM8731_ENABLE (BSP_OFF) /** diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_allocateheap.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_allocateheap.c index e3036f8cb..140ac310c 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_allocateheap.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_allocateheap.c @@ -83,20 +83,20 @@ /* The HC32 F4A0 have no CCM SRAM */ -# if defined(CONFIG_HC32_HC32F4A0) +# if defined(CONFIG_HC32_HC32F4A0) # undef CONFIG_HC32_CCMEXCLUDE # define CONFIG_HC32_CCMEXCLUDE 1 # endif /* Set the end of system SRAM */ -#define SRAM1_END 0x20073880 +#define SRAM1_END 0x1FFF0000 /* Set the range of CCM SRAM as well (although we may not use it) */ -#define SRAM2_START 0x1FE00000 -#define SRAM2_END 0x20073880 +#define SRAM2_START 0x1FFF0000 +#define SRAM2_END 0x20070000 /* There are 4 possible SRAM configurations: diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_common.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_common.h index e9539542a..ac617b632 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_common.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_common.h @@ -37,6 +37,15 @@ extern "C" #define HC32F4A0 1 #define USE_DDL_DRIVER 1 +#ifdef CONFIG_FS_PROCFS +# ifdef CONFIG_NSH_PROC_MOUNTPOINT +# define HC32_PROCFS_MOUNTPOINT CONFIG_NSH_PROC_MOUNTPOINT +# else +# define HC32_PROCFS_MOUNTPOINT "/proc" +# endif +#endif + + #define getreg32(a) (*(volatile uint32_t *)(a)) #define putreg32(v,a) (*(volatile uint32_t *)(a) = (v)) #define getreg16(a) (*(volatile uint16_t *)(a)) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_console.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_console.c new file mode 100755 index 000000000..e6fd16e9a --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_console.c @@ -0,0 +1,46 @@ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "chip.h" +#include "hc32_uart.h" +#include "hc32_spi.h" + +void hc32_test_console(void) +{ + char *dev_str = "/dev/console"; + char *test_chr = "test"; + int fd = 0, ret; + + fd = open(dev_str, 0x6); + hc32_print("%s: open <%s> ret = %d\n", __func__, dev_str, fd); + ret = write(fd, test_chr, strlen(test_chr)); + hc32_print("%s: open %d ret %d\n", __func__, fd, ret); + close(fd); +} + +void hc32_console_handle(char *buf) +{ + if(strncmp(buf, "console", 7) == 0) + { + hc32_test_console(); + } + else if(strncmp(buf, "spi", 7) == 0) + { + hc32_print("start flash test ...\n"); + hc32_spiflash_test(); + } +} + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_console.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_console.h new file mode 100755 index 000000000..e908105a4 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_console.h @@ -0,0 +1,43 @@ +#ifndef __HC32_CONSOLE_H_ +#define __HC32_CONSOLE_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef CONFIG_SERIAL_TERMIOS +# include +#endif + +#include +#include "chip.h" +#include "hc32_uart.h" +#include "hc32_rcc.h" +#include "hc32_gpio.h" +#include "arm_internal.h" +#include "hc32f4a0.h" +#include "hc32f4a0_usart.h" +#include "hc32f4a0_gpio.h" +#include "hc32f4a0_interrupts.h" +#include "hc32f4a0_sram.h" +#include "hc32f4a0_pwc.h" +#include "hc32f4a0_efm.h" + +void hc32_console_handle(char *buf); + +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_gpio.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_gpio.c index 42f6f2d12..3835a2b14 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_gpio.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_gpio.c @@ -119,7 +119,7 @@ void hc32_gpioinit(void) ****************************************************************************/ /**************************************************************************** - * Name: hc32_configgpio (for the HC32F10xxx family) + * Name: hc32_configgpio (for the HC32F4A0) ****************************************************************************/ int hc32_configgpio(uint32_t cfgset) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_idle.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_idle.c index d112c65c9..fb8deaacd 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_idle.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_idle.c @@ -152,6 +152,12 @@ static void up_idlepm(void) void up_idle(void) { + +#if defined (CONFIG_HC32F4A0_BOARD) + extern void hc32_uart_handle(void); + hc32_uart_handle(); +#endif + #if defined(CONFIG_SUPPRESS_INTERRUPTS) || defined(CONFIG_SUPPRESS_TIMER_INTS) /* If the system is idle and there are no timer interrupts, then process * "fake" timer interrupts. Hopefully, something will wake up. diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_irq.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_irq.c index 8f471147f..91d6a86c7 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_irq.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_irq.c @@ -40,6 +40,7 @@ #endif #include "arm_internal.h" #include "hc32f4a0.h" +#include "hc32f4a0_interrupts.h" /**************************************************************************** * Pre-processor Definitions @@ -162,57 +163,1119 @@ static void hc32_dumpnvic(const char *msg, int irq) * ****************************************************************************/ + +static int hc32_svc(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES + _err("PANIC!!! SVC received\n"); + PANIC(); +#endif + SVC_Handler(); + return 0; +} + +static int hc32_hardfault(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES + _err("PANIC!!! HardFault received\n"); + PANIC(); +#endif + HardFault_Handler(); + return 0; +} + #ifdef CONFIG_DEBUG_FEATURES static int hc32_nmi(int irq, FAR void *context, FAR void *arg) { up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES _err("PANIC!!! NMI received\n"); PANIC(); +#endif + NMI_Handler(); + return 0; +} + +#ifdef CONFIG_ARM_MPU + +static int hc32_memfault(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES + _err("PANIC!!! MemFault received\n"); + PANIC(); +#endif + MemManage_Handler(); return 0; } static int hc32_busfault(int irq, FAR void *context, FAR void *arg) { up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES _err("PANIC!!! Bus fault received: %08" PRIx32 "\n", getreg32(NVIC_CFAULTS)); PANIC(); +#endif + BusFault_Handler(); return 0; } static int hc32_usagefault(int irq, FAR void *context, FAR void *arg) { up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES _err("PANIC!!! Usage fault received: %08" PRIx32 "\n", getreg32(NVIC_CFAULTS)); PANIC(); +#endif + UsageFault_Handler(); return 0; } static int hc32_pendsv(int irq, FAR void *context, FAR void *arg) { up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES _err("PANIC!!! PendSV received\n"); PANIC(); +#endif + PendSV_Handler(); return 0; } static int hc32_dbgmonitor(int irq, FAR void *context, FAR void *arg) { up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES _err("PANIC!!! Debug Monitor received\n"); PANIC(); +#endif + DebugMon_Handler(); return 0; } static int hc32_reserved(int irq, FAR void *context, FAR void *arg) { up_irq_save(); +#ifdef CONFIG_DEBUG_FEATURES _err("PANIC!!! Reserved interrupt\n"); PANIC(); +#endif return 0; } #endif +#endif +static int hc32_irq000(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ000_Handler(); + return 0; +} + +static int hc32_irq001(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ001_Handler(); + return 0; +} + +static int hc32_irq002(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ002_Handler(); + return 0; +} + +static int hc32_irq003(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ003_Handler(); + return 0; +} + +static int hc32_irq004(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ004_Handler(); + return 0; +} + +static int hc32_irq005(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ005_Handler(); + return 0; +} + +static int hc32_irq006(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ006_Handler(); + return 0; +} + +static int hc32_irq007(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ007_Handler(); + return 0; +} + +static int hc32_irq008(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ008_Handler(); + return 0; +} + +static int hc32_irq009(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ009_Handler(); + return 0; +} + +static int hc32_irq010(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ010_Handler(); + return 0; +} + +static int hc32_irq011(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ011_Handler(); + return 0; +} + +static int hc32_irq012(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ012_Handler(); + return 0; +} + +static int hc32_irq013(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ013_Handler(); + return 0; +} + +static int hc32_irq014(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ014_Handler(); + return 0; +} + +static int hc32_irq015(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ015_Handler(); + return 0; +} + +static int hc32_irq016(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ016_Handler(); + return 0; +} + +static int hc32_irq017(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ017_Handler(); + return 0; +} + +static int hc32_irq018(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ018_Handler(); + return 0; +} + +static int hc32_irq019(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ019_Handler(); + return 0; +} + +static int hc32_irq020(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ020_Handler(); + return 0; +} + +static int hc32_irq021(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ021_Handler(); + return 0; +} + +static int hc32_irq022(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ022_Handler(); + return 0; +} + +static int hc32_irq023(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ023_Handler(); + return 0; +} + +static int hc32_irq024(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ024_Handler(); + return 0; +} + +static int hc32_irq025(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ025_Handler(); + return 0; +} + +static int hc32_irq026(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ026_Handler(); + return 0; +} + +static int hc32_irq027(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ027_Handler(); + return 0; +} + +static int hc32_irq028(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ028_Handler(); + return 0; +} + +static int hc32_irq029(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ029_Handler(); + return 0; +} + +static int hc32_irq030(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ030_Handler(); + return 0; +} + +static int hc32_irq031(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ031_Handler(); + return 0; +} + +static int hc32_irq032(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ032_Handler(); + return 0; +} + +static int hc32_irq033(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ033_Handler(); + return 0; +} + +static int hc32_irq034(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ034_Handler(); + return 0; +} + +static int hc32_irq035(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ035_Handler(); + return 0; +} + +static int hc32_irq036(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ036_Handler(); + return 0; +} + +static int hc32_irq037(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ037_Handler(); + return 0; +} + +static int hc32_irq038(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ038_Handler(); + return 0; +} + +static int hc32_irq039(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ039_Handler(); + return 0; +} + +static int hc32_irq040(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ040_Handler(); + return 0; +} + +static int hc32_irq041(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ041_Handler(); + return 0; +} + +static int hc32_irq042(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ042_Handler(); + return 0; +} + +static int hc32_irq043(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ043_Handler(); + return 0; +} + +static int hc32_irq044(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ044_Handler(); + return 0; +} + +static int hc32_irq045(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ045_Handler(); + return 0; +} + +static int hc32_irq046(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ046_Handler(); + return 0; +} + +static int hc32_irq047(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ047_Handler(); + return 0; +} + +static int hc32_irq048(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ048_Handler(); + return 0; +} + +static int hc32_irq049(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ049_Handler(); + return 0; +} + +static int hc32_irq050(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ050_Handler(); + return 0; +} + +static int hc32_irq051(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ051_Handler(); + return 0; +} + +static int hc32_irq052(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ052_Handler(); + return 0; +} + +static int hc32_irq053(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ053_Handler(); + return 0; +} + +static int hc32_irq054(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ054_Handler(); + return 0; +} + +static int hc32_irq055(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ055_Handler(); + return 0; +} + +static int hc32_irq056(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ056_Handler(); + return 0; +} + +static int hc32_irq057(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ057_Handler(); + return 0; +} + +static int hc32_irq058(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ058_Handler(); + return 0; +} + +static int hc32_irq059(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ059_Handler(); + return 0; +} + +static int hc32_irq060(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ060_Handler(); + return 0; +} + +static int hc32_irq061(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ061_Handler(); + return 0; +} + +static int hc32_irq062(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ062_Handler(); + return 0; +} + +static int hc32_irq063(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ063_Handler(); + return 0; +} + +static int hc32_irq064(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ064_Handler(); + return 0; +} + +static int hc32_irq065(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ065_Handler(); + return 0; +} + +static int hc32_irq066(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ066_Handler(); + return 0; +} + +static int hc32_irq067(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ067_Handler(); + return 0; +} + +static int hc32_irq068(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ068_Handler(); + return 0; +} + +static int hc32_irq069(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ069_Handler(); + return 0; +} + +static int hc32_irq070(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ070_Handler(); + return 0; +} + +static int hc32_irq071(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ071_Handler(); + return 0; +} + +static int hc32_irq072(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ072_Handler(); + return 0; +} + +static int hc32_irq073(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ073_Handler(); + return 0; +} + +static int hc32_irq074(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ074_Handler(); + return 0; +} + +static int hc32_irq075(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ075_Handler(); + return 0; +} + +static int hc32_irq076(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ076_Handler(); + return 0; +} + +static int hc32_irq077(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ077_Handler(); + return 0; +} + +static int hc32_irq078(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ078_Handler(); + return 0; +} + +static int hc32_irq079(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ079_Handler(); + return 0; +} + +static int hc32_irq080(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ080_Handler(); + return 0; +} + +static int hc32_irq081(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ081_Handler(); + return 0; +} + +static int hc32_irq082(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ082_Handler(); + return 0; +} + +static int hc32_irq083(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ083_Handler(); + return 0; +} + +static int hc32_irq084(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ084_Handler(); + return 0; +} + +static int hc32_irq085(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ085_Handler(); + return 0; +} + +static int hc32_irq086(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ086_Handler(); + return 0; +} + +static int hc32_irq087(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ087_Handler(); + return 0; +} + +static int hc32_irq088(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ088_Handler(); + return 0; +} + +static int hc32_irq089(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ089_Handler(); + return 0; +} + +static int hc32_irq090(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ090_Handler(); + return 0; +} + +static int hc32_irq091(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ091_Handler(); + return 0; +} + +static int hc32_irq092(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ092_Handler(); + return 0; +} + +static int hc32_irq093(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ093_Handler(); + return 0; +} + +static int hc32_irq094(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ094_Handler(); + return 0; +} + +static int hc32_irq095(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ095_Handler(); + return 0; +} + +static int hc32_irq096(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ096_Handler(); + return 0; +} + +static int hc32_irq097(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ097_Handler(); + return 0; +} + +static int hc32_irq098(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ098_Handler(); + return 0; +} + +static int hc32_irq099(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ099_Handler(); + return 0; +} + +static int hc32_irq100(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ100_Handler(); + return 0; +} + +static int hc32_irq101(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ101_Handler(); + return 0; +} + +static int hc32_irq102(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ102_Handler(); + return 0; +} + +static int hc32_irq103(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ103_Handler(); + return 0; +} + +static int hc32_irq104(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ104_Handler(); + return 0; +} + +static int hc32_irq105(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ105_Handler(); + return 0; +} + +static int hc32_irq106(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ106_Handler(); + return 0; +} + +static int hc32_irq107(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ107_Handler(); + return 0; +} + +static int hc32_irq108(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ108_Handler(); + return 0; +} + +static int hc32_irq109(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ109_Handler(); + return 0; +} + +static int hc32_irq110(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ110_Handler(); + return 0; +} + +static int hc32_irq111(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ111_Handler(); + return 0; +} + +static int hc32_irq112(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ112_Handler(); + return 0; +} + +static int hc32_irq113(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ113_Handler(); + return 0; +} + +static int hc32_irq114(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ114_Handler(); + return 0; +} + +static int hc32_irq115(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ115_Handler(); + return 0; +} + +static int hc32_irq116(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ116_Handler(); + return 0; +} + +static int hc32_irq117(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ117_Handler(); + return 0; +} + +static int hc32_irq118(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ118_Handler(); + return 0; +} + +static int hc32_irq119(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ119_Handler(); + return 0; +} + +static int hc32_irq120(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ120_Handler(); + return 0; +} + +static int hc32_irq121(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ121_Handler(); + return 0; +} + +static int hc32_irq122(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ122_Handler(); + return 0; +} + +static int hc32_irq123(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ123_Handler(); + return 0; +} + +static int hc32_irq124(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ124_Handler(); + return 0; +} + +static int hc32_irq125(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ125_Handler(); + return 0; +} + +static int hc32_irq126(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ126_Handler(); + return 0; +} + +static int hc32_irq127(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ127_Handler(); + return 0; +} + +static int hc32_irq128(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ128_Handler(); + return 0; +} + +static int hc32_irq129(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ129_Handler(); + return 0; +} + +static int hc32_irq130(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ130_Handler(); + return 0; +} + +static int hc32_irq131(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ131_Handler(); + return 0; +} + +static int hc32_irq132(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ132_Handler(); + return 0; +} + +static int hc32_irq133(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ133_Handler(); + return 0; +} + +static int hc32_irq134(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ134_Handler(); + return 0; +} + +static int hc32_irq135(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ135_Handler(); + return 0; +} + +static int hc32_irq136(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ136_Handler(); + return 0; +} + +static int hc32_irq137(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ137_Handler(); + return 0; +} + +static int hc32_irq138(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ138_Handler(); + return 0; +} + +static int hc32_irq139(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ139_Handler(); + return 0; +} + +static int hc32_irq140(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ140_Handler(); + return 0; +} + +static int hc32_irq141(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ141_Handler(); + return 0; +} + +static int hc32_irq142(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ142_Handler(); + return 0; +} + +static int hc32_irq143(int irq, FAR void *context, FAR void *arg) +{ + up_irq_save(); + IRQ143_Handler(); + return 0; +} + /**************************************************************************** * Name: hc32_prioritize_syscall @@ -297,6 +1360,169 @@ static int hc32_irqinfo(int irq, uintptr_t *regaddr, uint32_t *bit, * Public Functions ****************************************************************************/ +void hc32_attach_irqs(void) +{ + irq_attach(HC32_IRQ_FIRST + Int000_IRQn, hc32_irq000, NULL); + irq_attach(HC32_IRQ_FIRST + Int001_IRQn, hc32_irq001, NULL); + irq_attach(HC32_IRQ_FIRST + Int002_IRQn, hc32_irq002, NULL); + irq_attach(HC32_IRQ_FIRST + Int003_IRQn, hc32_irq003, NULL); + irq_attach(HC32_IRQ_FIRST + Int004_IRQn, hc32_irq004, NULL); + irq_attach(HC32_IRQ_FIRST + Int005_IRQn, hc32_irq005, NULL); + irq_attach(HC32_IRQ_FIRST + Int006_IRQn, hc32_irq006, NULL); + irq_attach(HC32_IRQ_FIRST + Int007_IRQn, hc32_irq007, NULL); + irq_attach(HC32_IRQ_FIRST + Int008_IRQn, hc32_irq008, NULL); + irq_attach(HC32_IRQ_FIRST + Int009_IRQn, hc32_irq009, NULL); + + irq_attach(HC32_IRQ_FIRST + Int010_IRQn, hc32_irq010, NULL); + irq_attach(HC32_IRQ_FIRST + Int011_IRQn, hc32_irq011, NULL); + irq_attach(HC32_IRQ_FIRST + Int012_IRQn, hc32_irq012, NULL); + irq_attach(HC32_IRQ_FIRST + Int013_IRQn, hc32_irq013, NULL); + irq_attach(HC32_IRQ_FIRST + Int014_IRQn, hc32_irq014, NULL); + irq_attach(HC32_IRQ_FIRST + Int015_IRQn, hc32_irq015, NULL); + irq_attach(HC32_IRQ_FIRST + Int016_IRQn, hc32_irq016, NULL); + irq_attach(HC32_IRQ_FIRST + Int017_IRQn, hc32_irq017, NULL); + irq_attach(HC32_IRQ_FIRST + Int018_IRQn, hc32_irq018, NULL); + irq_attach(HC32_IRQ_FIRST + Int019_IRQn, hc32_irq019, NULL); + + irq_attach(HC32_IRQ_FIRST + Int020_IRQn, hc32_irq020, NULL); + irq_attach(HC32_IRQ_FIRST + Int021_IRQn, hc32_irq021, NULL); + irq_attach(HC32_IRQ_FIRST + Int022_IRQn, hc32_irq022, NULL); + irq_attach(HC32_IRQ_FIRST + Int023_IRQn, hc32_irq023, NULL); + irq_attach(HC32_IRQ_FIRST + Int024_IRQn, hc32_irq024, NULL); + irq_attach(HC32_IRQ_FIRST + Int025_IRQn, hc32_irq025, NULL); + irq_attach(HC32_IRQ_FIRST + Int026_IRQn, hc32_irq026, NULL); + irq_attach(HC32_IRQ_FIRST + Int027_IRQn, hc32_irq027, NULL); + irq_attach(HC32_IRQ_FIRST + Int028_IRQn, hc32_irq028, NULL); + irq_attach(HC32_IRQ_FIRST + Int029_IRQn, hc32_irq029, NULL); + + irq_attach(HC32_IRQ_FIRST + Int030_IRQn, hc32_irq030, NULL); + irq_attach(HC32_IRQ_FIRST + Int031_IRQn, hc32_irq031, NULL); + irq_attach(HC32_IRQ_FIRST + Int032_IRQn, hc32_irq032, NULL); + irq_attach(HC32_IRQ_FIRST + Int033_IRQn, hc32_irq033, NULL); + irq_attach(HC32_IRQ_FIRST + Int034_IRQn, hc32_irq034, NULL); + irq_attach(HC32_IRQ_FIRST + Int035_IRQn, hc32_irq035, NULL); + irq_attach(HC32_IRQ_FIRST + Int036_IRQn, hc32_irq036, NULL); + irq_attach(HC32_IRQ_FIRST + Int037_IRQn, hc32_irq037, NULL); + irq_attach(HC32_IRQ_FIRST + Int038_IRQn, hc32_irq038, NULL); + irq_attach(HC32_IRQ_FIRST + Int039_IRQn, hc32_irq039, NULL); + + irq_attach(HC32_IRQ_FIRST + Int040_IRQn, hc32_irq040, NULL); + irq_attach(HC32_IRQ_FIRST + Int041_IRQn, hc32_irq041, NULL); + irq_attach(HC32_IRQ_FIRST + Int042_IRQn, hc32_irq042, NULL); + irq_attach(HC32_IRQ_FIRST + Int043_IRQn, hc32_irq043, NULL); + irq_attach(HC32_IRQ_FIRST + Int044_IRQn, hc32_irq044, NULL); + irq_attach(HC32_IRQ_FIRST + Int045_IRQn, hc32_irq045, NULL); + irq_attach(HC32_IRQ_FIRST + Int046_IRQn, hc32_irq046, NULL); + irq_attach(HC32_IRQ_FIRST + Int047_IRQn, hc32_irq047, NULL); + irq_attach(HC32_IRQ_FIRST + Int048_IRQn, hc32_irq048, NULL); + irq_attach(HC32_IRQ_FIRST + Int049_IRQn, hc32_irq049, NULL); + + irq_attach(HC32_IRQ_FIRST + Int050_IRQn, hc32_irq050, NULL); + irq_attach(HC32_IRQ_FIRST + Int051_IRQn, hc32_irq051, NULL); + irq_attach(HC32_IRQ_FIRST + Int052_IRQn, hc32_irq052, NULL); + irq_attach(HC32_IRQ_FIRST + Int053_IRQn, hc32_irq053, NULL); + irq_attach(HC32_IRQ_FIRST + Int054_IRQn, hc32_irq054, NULL); + irq_attach(HC32_IRQ_FIRST + Int055_IRQn, hc32_irq055, NULL); + irq_attach(HC32_IRQ_FIRST + Int056_IRQn, hc32_irq056, NULL); + irq_attach(HC32_IRQ_FIRST + Int057_IRQn, hc32_irq057, NULL); + irq_attach(HC32_IRQ_FIRST + Int058_IRQn, hc32_irq058, NULL); + irq_attach(HC32_IRQ_FIRST + Int059_IRQn, hc32_irq059, NULL); + + irq_attach(HC32_IRQ_FIRST + Int060_IRQn, hc32_irq060, NULL); + irq_attach(HC32_IRQ_FIRST + Int061_IRQn, hc32_irq061, NULL); + irq_attach(HC32_IRQ_FIRST + Int062_IRQn, hc32_irq062, NULL); + irq_attach(HC32_IRQ_FIRST + Int063_IRQn, hc32_irq063, NULL); + irq_attach(HC32_IRQ_FIRST + Int064_IRQn, hc32_irq064, NULL); + irq_attach(HC32_IRQ_FIRST + Int065_IRQn, hc32_irq065, NULL); + irq_attach(HC32_IRQ_FIRST + Int066_IRQn, hc32_irq066, NULL); + irq_attach(HC32_IRQ_FIRST + Int067_IRQn, hc32_irq067, NULL); + irq_attach(HC32_IRQ_FIRST + Int068_IRQn, hc32_irq068, NULL); + irq_attach(HC32_IRQ_FIRST + Int069_IRQn, hc32_irq069, NULL); + + irq_attach(HC32_IRQ_FIRST + Int070_IRQn, hc32_irq070, NULL); + irq_attach(HC32_IRQ_FIRST + Int071_IRQn, hc32_irq071, NULL); + irq_attach(HC32_IRQ_FIRST + Int072_IRQn, hc32_irq072, NULL); + irq_attach(HC32_IRQ_FIRST + Int073_IRQn, hc32_irq073, NULL); + irq_attach(HC32_IRQ_FIRST + Int074_IRQn, hc32_irq074, NULL); + irq_attach(HC32_IRQ_FIRST + Int075_IRQn, hc32_irq075, NULL); + irq_attach(HC32_IRQ_FIRST + Int076_IRQn, hc32_irq076, NULL); + irq_attach(HC32_IRQ_FIRST + Int077_IRQn, hc32_irq077, NULL); + irq_attach(HC32_IRQ_FIRST + Int078_IRQn, hc32_irq078, NULL); + irq_attach(HC32_IRQ_FIRST + Int079_IRQn, hc32_irq079, NULL); + + irq_attach(HC32_IRQ_FIRST + Int080_IRQn, hc32_irq080, NULL); + irq_attach(HC32_IRQ_FIRST + Int081_IRQn, hc32_irq081, NULL); + irq_attach(HC32_IRQ_FIRST + Int082_IRQn, hc32_irq082, NULL); + irq_attach(HC32_IRQ_FIRST + Int083_IRQn, hc32_irq083, NULL); + irq_attach(HC32_IRQ_FIRST + Int084_IRQn, hc32_irq084, NULL); + irq_attach(HC32_IRQ_FIRST + Int085_IRQn, hc32_irq085, NULL); + irq_attach(HC32_IRQ_FIRST + Int086_IRQn, hc32_irq086, NULL); + irq_attach(HC32_IRQ_FIRST + Int087_IRQn, hc32_irq087, NULL); + irq_attach(HC32_IRQ_FIRST + Int088_IRQn, hc32_irq088, NULL); + irq_attach(HC32_IRQ_FIRST + Int089_IRQn, hc32_irq089, NULL); + + irq_attach(HC32_IRQ_FIRST + Int090_IRQn, hc32_irq090, NULL); + irq_attach(HC32_IRQ_FIRST + Int091_IRQn, hc32_irq091, NULL); + irq_attach(HC32_IRQ_FIRST + Int092_IRQn, hc32_irq092, NULL); + irq_attach(HC32_IRQ_FIRST + Int093_IRQn, hc32_irq093, NULL); + irq_attach(HC32_IRQ_FIRST + Int094_IRQn, hc32_irq094, NULL); + irq_attach(HC32_IRQ_FIRST + Int095_IRQn, hc32_irq095, NULL); + irq_attach(HC32_IRQ_FIRST + Int096_IRQn, hc32_irq096, NULL); + irq_attach(HC32_IRQ_FIRST + Int097_IRQn, hc32_irq097, NULL); + irq_attach(HC32_IRQ_FIRST + Int098_IRQn, hc32_irq098, NULL); + irq_attach(HC32_IRQ_FIRST + Int099_IRQn, hc32_irq099, NULL); + + irq_attach(HC32_IRQ_FIRST + Int100_IRQn, hc32_irq100, NULL); + irq_attach(HC32_IRQ_FIRST + Int101_IRQn, hc32_irq101, NULL); + irq_attach(HC32_IRQ_FIRST + Int102_IRQn, hc32_irq102, NULL); + irq_attach(HC32_IRQ_FIRST + Int103_IRQn, hc32_irq103, NULL); + irq_attach(HC32_IRQ_FIRST + Int104_IRQn, hc32_irq104, NULL); + irq_attach(HC32_IRQ_FIRST + Int105_IRQn, hc32_irq105, NULL); + irq_attach(HC32_IRQ_FIRST + Int106_IRQn, hc32_irq106, NULL); + irq_attach(HC32_IRQ_FIRST + Int107_IRQn, hc32_irq107, NULL); + irq_attach(HC32_IRQ_FIRST + Int108_IRQn, hc32_irq108, NULL); + irq_attach(HC32_IRQ_FIRST + Int109_IRQn, hc32_irq109, NULL); + + irq_attach(HC32_IRQ_FIRST + Int110_IRQn, hc32_irq110, NULL); + irq_attach(HC32_IRQ_FIRST + Int111_IRQn, hc32_irq111, NULL); + irq_attach(HC32_IRQ_FIRST + Int112_IRQn, hc32_irq112, NULL); + irq_attach(HC32_IRQ_FIRST + Int113_IRQn, hc32_irq113, NULL); + irq_attach(HC32_IRQ_FIRST + Int114_IRQn, hc32_irq114, NULL); + irq_attach(HC32_IRQ_FIRST + Int115_IRQn, hc32_irq115, NULL); + irq_attach(HC32_IRQ_FIRST + Int116_IRQn, hc32_irq116, NULL); + irq_attach(HC32_IRQ_FIRST + Int117_IRQn, hc32_irq117, NULL); + irq_attach(HC32_IRQ_FIRST + Int118_IRQn, hc32_irq118, NULL); + irq_attach(HC32_IRQ_FIRST + Int119_IRQn, hc32_irq119, NULL); + + irq_attach(HC32_IRQ_FIRST + Int120_IRQn, hc32_irq120, NULL); + irq_attach(HC32_IRQ_FIRST + Int121_IRQn, hc32_irq121, NULL); + irq_attach(HC32_IRQ_FIRST + Int122_IRQn, hc32_irq122, NULL); + irq_attach(HC32_IRQ_FIRST + Int123_IRQn, hc32_irq123, NULL); + irq_attach(HC32_IRQ_FIRST + Int124_IRQn, hc32_irq124, NULL); + irq_attach(HC32_IRQ_FIRST + Int125_IRQn, hc32_irq125, NULL); + irq_attach(HC32_IRQ_FIRST + Int126_IRQn, hc32_irq126, NULL); + irq_attach(HC32_IRQ_FIRST + Int127_IRQn, hc32_irq127, NULL); + irq_attach(HC32_IRQ_FIRST + Int128_IRQn, hc32_irq128, NULL); + irq_attach(HC32_IRQ_FIRST + Int129_IRQn, hc32_irq129, NULL); + + irq_attach(HC32_IRQ_FIRST + Int130_IRQn, hc32_irq130, NULL); + irq_attach(HC32_IRQ_FIRST + Int131_IRQn, hc32_irq131, NULL); + irq_attach(HC32_IRQ_FIRST + Int132_IRQn, hc32_irq132, NULL); + irq_attach(HC32_IRQ_FIRST + Int133_IRQn, hc32_irq133, NULL); + irq_attach(HC32_IRQ_FIRST + Int134_IRQn, hc32_irq134, NULL); + irq_attach(HC32_IRQ_FIRST + Int135_IRQn, hc32_irq135, NULL); + irq_attach(HC32_IRQ_FIRST + Int136_IRQn, hc32_irq136, NULL); + irq_attach(HC32_IRQ_FIRST + Int137_IRQn, hc32_irq137, NULL); + irq_attach(HC32_IRQ_FIRST + Int138_IRQn, hc32_irq138, NULL); + irq_attach(HC32_IRQ_FIRST + Int139_IRQn, hc32_irq139, NULL); + + irq_attach(HC32_IRQ_FIRST + Int140_IRQn, hc32_irq140, NULL); + irq_attach(HC32_IRQ_FIRST + Int141_IRQn, hc32_irq141, NULL); + irq_attach(HC32_IRQ_FIRST + Int142_IRQn, hc32_irq142, NULL); + irq_attach(HC32_IRQ_FIRST + Int143_IRQn, hc32_irq143, NULL); +} + + /**************************************************************************** * Name: up_irqinitialize ****************************************************************************/ @@ -315,7 +1541,7 @@ void up_irqinitialize(void) } /* The standard location for the vector table is at the beginning of FLASH - * at address 0x0800:0000. If we are using the STMicro DFU bootloader, + * at address 0x0000:0000. If we are using the HC32 bootloader, * then the vector table will be offset to a different location in FLASH * and we will need to set the NVIC vector location to this alternative * location. @@ -371,8 +1597,8 @@ void up_irqinitialize(void) * under certain conditions. */ - irq_attach(HC32_IRQ_SVCALL, arm_svcall, NULL); - irq_attach(HC32_IRQ_HARDFAULT, arm_hardfault, NULL); + irq_attach(HC32_IRQ_SVCALL, hc32_svc, NULL); + irq_attach(HC32_IRQ_HARDFAULT, hc32_hardfault, NULL); /* Set the priority of the SVCall interrupt */ @@ -388,7 +1614,7 @@ void up_irqinitialize(void) */ #ifdef CONFIG_ARM_MPU - irq_attach(HC32_IRQ_MEMFAULT, arm_memfault, NULL); + irq_attach(HC32_IRQ_MEMFAULT, hc32_memfault, NULL); up_enable_irq(HC32_IRQ_MEMFAULT); #endif @@ -403,7 +1629,7 @@ void up_irqinitialize(void) #ifdef CONFIG_DEBUG_FEATURES irq_attach(HC32_IRQ_NMI, hc32_nmi, NULL); #ifndef CONFIG_ARM_MPU - irq_attach(HC32_IRQ_MEMFAULT, arm_memfault, NULL); + irq_attach(HC32_IRQ_MEMFAULT, hc32_memfault, NULL); #endif irq_attach(HC32_IRQ_BUSFAULT, hc32_busfault, NULL); irq_attach(HC32_IRQ_USAGEFAULT, hc32_usagefault, NULL); @@ -412,6 +1638,8 @@ void up_irqinitialize(void) irq_attach(HC32_IRQ_RESERVED, hc32_reserved, NULL); #endif + hc32_attach_irqs(); + hc32_dumpnvic("initial", NR_IRQS); #ifndef CONFIG_SUPPRESS_INTERRUPTS @@ -446,7 +1674,8 @@ void up_disable_irq(int irq) if (irq >= HC32_IRQ_FIRST) { - putreg32(bit, regaddr); + uint32_t act_irq = irq - HC32_IRQ_FIRST; + NVIC_DisableIRQ(act_irq); } else { @@ -481,7 +1710,10 @@ void up_enable_irq(int irq) if (irq >= HC32_IRQ_FIRST) { - putreg32(bit, regaddr); + uint32_t act_irq = irq - HC32_IRQ_FIRST; + NVIC_ClearPendingIRQ(act_irq); + NVIC_SetPriority(act_irq, DDL_IRQ_PRIORITY_00); + NVIC_EnableIRQ(act_irq); } else { diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_lowputc.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_lowputc.c index 7554b27a9..0ac9edcf5 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_lowputc.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_lowputc.c @@ -37,34 +37,12 @@ #include "hc32_lowputc.h" #include "hc32f4a0_usart.h" #include "hc32_ddl.h" +#include "hc32_uart.h" /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ -/* UART multiple processor ID definition */ -#define UART_MASTER_STATION_ID (0x20U) -#define UART_SLAVE_STATION_ID (0x21U) - -/* Ring buffer size */ -#define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize)) - -/* Multi-processor silence mode */ -#define LP_UART_NORMAL_MODE (0U) -#define LP_UART_SILENCE_MODE (1U) - -/** - * @brief Ring buffer structure definition - */ -typedef struct -{ - uint16_t u16Capacity; - __IO uint16_t u16UsedSize; - uint16_t u16InIdx; - uint16_t u16OutIdx; - uint8_t au8Buf[50]; -} stc_ring_buffer_t; - /**************************************************************************** * Private Types ****************************************************************************/ @@ -81,212 +59,10 @@ typedef struct * Private Data ****************************************************************************/ -static uint8_t m_u8UartSilenceMode = LP_UART_NORMAL_MODE; - -static stc_ring_buffer_t m_stcRingBuf = { - .u16InIdx = 0U, - .u16OutIdx = 0U, - .u16UsedSize = 0U, - .u16Capacity = sizeof (m_stcRingBuf.au8Buf), -}; - /**************************************************************************** * Private Functions ****************************************************************************/ -/** - * @brief Set silence mode. - * @param [in] u8Mode Silence mode - * This parameter can be one of the following values: - * @arg LP_UART_SILENCE_MODE: UART silence mode - * @arg LP_UART_NORMAL_MODE: UART normal mode - * @retval None - */ -static void UsartSetSilenceMode(uint8_t u8Mode) -{ - m_u8UartSilenceMode = u8Mode; -} - -/** - * @brief Get silence mode. - * @param [in] None - * @retval Returned value can be one of the following values: - * @arg LP_UART_SILENCE_MODE: UART silence mode - * @arg LP_UART_NORMAL_MODE: UART normal mode - */ -static uint8_t UsartGetSilenceMode(void) -{ - return m_u8UartSilenceMode; -} - -/** - * @brief Instal IRQ handler. - * @param [in] pstcConfig Pointer to struct @ref stc_irq_signin_config_t - * @param [in] u32Priority Interrupt priority - * @retval None - */ -static void InstalIrqHandler(const stc_irq_signin_config_t *pstcConfig, - uint32_t u32Priority) -{ - if (NULL != pstcConfig) - { - (void)INTC_IrqSignIn(pstcConfig); - NVIC_ClearPendingIRQ(pstcConfig->enIRQn); - NVIC_SetPriority(pstcConfig->enIRQn, u32Priority); - NVIC_EnableIRQ(pstcConfig->enIRQn); - } -} - - -/** - * @brief Write ring buffer. - * @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure - * @param [in] pu8Data Pointer to data buffer to read - * @retval An en_result_t enumeration value: - * - Ok: Write success. - * - ErrorNotReady: Buffer is empty. - */ -static en_result_t RingBufRead(stc_ring_buffer_t *pstcBuffer, uint8_t *pu8Data) -{ - en_result_t enRet = Ok; - - if (pstcBuffer->u16UsedSize == 0U) - { - enRet = ErrorNotReady; - } - else - { - *pu8Data = pstcBuffer->au8Buf[pstcBuffer->u16OutIdx++]; - pstcBuffer->u16OutIdx %= pstcBuffer->u16Capacity; - pstcBuffer->u16UsedSize--; - } - - return enRet; -} - -/** - * @brief UART TX Empty IRQ callback. - * @param None - * @retval None - */ -static void USART_TxEmpty_IrqCallback(void) -{ - uint8_t u8Data = 0U; - en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_TXE); - en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_TXE); - - if ((Set == enFlag) && (Enable == enState)) - { - USART_SendId(LP_UNIT, UART_SLAVE_STATION_ID); - - while (Reset == USART_GetStatus(LP_UNIT, USART_FLAG_TC)) /* Wait Tx data register empty */ - { - } - - if (Ok == RingBufRead(&m_stcRingBuf, &u8Data)) - { - USART_SendData(LP_UNIT, (uint16_t)u8Data); - } - - if (IS_RING_BUFFER_EMPTY(&m_stcRingBuf)) - { - USART_FuncCmd(LP_UNIT, USART_INT_TXE, Disable); - USART_FuncCmd(LP_UNIT, USART_INT_TC, Enable); - } - } -} - -/** - * @brief UART TX Complete IRQ callback. - * @param None - * @retval None - */ -static void USART_TxComplete_IrqCallback(void) -{ - en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_TC); - en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_TC); - - if ((Set == enFlag) && (Enable == enState)) - { - /* Disable TX function */ - USART_FuncCmd(LP_UNIT, (USART_TX | USART_RX | USART_INT_TC), Disable); - - /* Enable RX function */ - USART_FuncCmd(LP_UNIT, (USART_RX | USART_INT_RX), Enable); - } -} - -/** - * @brief Write ring buffer. - * @param [in] pstcBuffer Pointer to a @ref stc_ring_buffer_t structure - * @param [in] u8Data Data to write - * @retval An en_result_t enumeration value: - * - Ok: Write success. - * - ErrorBufferFull: Buffer is full. - */ -static en_result_t write_ring_buf(stc_ring_buffer_t *pstcBuffer, uint8_t u8Data) -{ - en_result_t enRet = Ok; - - if (pstcBuffer->u16UsedSize >= pstcBuffer->u16Capacity) - { - enRet = ErrorBufferFull; - } - else - { - pstcBuffer->au8Buf[pstcBuffer->u16InIdx++] = u8Data; - pstcBuffer->u16InIdx %= pstcBuffer->u16Capacity; - pstcBuffer->u16UsedSize++; - } - - return enRet; -} - -/** - * @brief UART RX IRQ callback. - * @param None - * @retval None - */ -static void USART_Rx_IrqCallback(void) -{ - uint8_t u8RxData; - en_flag_status_t enFlag = USART_GetStatus(LP_UNIT, USART_FLAG_RXNE); - en_functional_state_t enState = USART_GetFuncState(LP_UNIT, USART_INT_RX); - - if ((Set == enFlag) && (Enable == enState)) - { - u8RxData = (uint8_t)USART_RecData(LP_UNIT); - - if ((Reset == USART_GetStatus(LP_UNIT, USART_FLAG_MPB)) && - (LP_UART_NORMAL_MODE == UsartGetSilenceMode())) - { - write_ring_buf(&m_stcRingBuf, u8RxData); - } - else - { - if (UART_MASTER_STATION_ID != u8RxData) - { - USART_SilenceCmd(LP_UNIT, Enable); - UsartSetSilenceMode(LP_UART_SILENCE_MODE); - } - else - { - UsartSetSilenceMode(LP_UART_NORMAL_MODE); - } - } - } -} - -/** - * @brief UART RX Error IRQ callback. - * @param None - * @retval None - */ -static void USART_RxErr_IrqCallback(void) -{ - USART_ClearStatus(LP_UNIT, (USART_CLEAR_FLAG_FE | USART_CLEAR_FLAG_PE | USART_CLEAR_FLAG_ORE)); -} - void hc32_unlock(void) { /* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */ @@ -342,30 +118,19 @@ void hc32_print_portinit(void) void arm_lowputc(char ch) { - while(Set != USART_GetStatus(LP_UNIT, USART_FLAG_TXE)); - USART_SendData(LP_UNIT, ch); + while(Set != USART_GetStatus(DBG_UNIT, USART_FLAG_TXE)); + USART_SendData(DBG_UNIT, ch); } - -/**************************************************************************** - * Name: hc32_lowsetup - * - * Description: - * This performs basic initialization of the USART used for the serial - * console. Its purpose is to get the console output available as soon - * as possible. - * - ****************************************************************************/ - void hc32_lowsetup(void) { - stc_irq_signin_config_t stcIrqSigninCfg; - const stc_usart_multiprocessor_init_t stcUartMultiProcessorInit = { - .u32Baudrate = 115200UL, + const stc_usart_uart_init_t stcUartInit = { + .u32Baudrate = BSP_PRINTF_BAUDRATE, .u32BitDirection = USART_LSB, .u32StopBit = USART_STOPBIT_1BIT, + .u32Parity = USART_PARITY_NONE, .u32DataWidth = USART_DATA_LENGTH_8BIT, - .u32ClkMode = USART_INTERNCLK_NONE_OUTPUT, + .u32ClkMode = USART_INTERNCLK_OUTPUT, .u32PclkDiv = USART_PCLK_DIV64, .u32OversamplingBits = USART_OVERSAMPLING_8BIT, .u32NoiseFilterState = USART_NOISE_FILTER_DISABLE, @@ -380,42 +145,18 @@ void hc32_lowsetup(void) DDL_PrintfInit(BSP_PRINTF_DEVICE, BSP_PRINTF_BAUDRATE, hc32_print_portinit); /* Configure USART RX/TX pin. */ - GPIO_SetFunc(LP_RX_PORT, LP_RX_PIN, LP_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE); - GPIO_SetFunc(LP_TX_PORT, LP_TX_PIN, LP_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE); + GPIO_SetFunc(DBG_RX_PORT, DBG_RX_PIN, DBG_RX_GPIO_FUNC, PIN_SUBFUNC_DISABLE); + GPIO_SetFunc(DBG_TX_PORT, DBG_TX_PIN, DBG_TX_GPIO_FUNC, PIN_SUBFUNC_DISABLE); hc32_lock(); /* Enable peripheral clock */ - PWC_Fcg3PeriphClockCmd(LP_FUNCTION_CLK_GATE, Enable); - - /* Set silence mode */ - UsartSetSilenceMode(LP_UART_SILENCE_MODE); + PWC_Fcg3PeriphClockCmd(DBG_FUNCTION_CLK_GATE, Enable); /* Initialize UART function. */ - (void)USART_MultiProcessorInit(LP_UNIT, &stcUartMultiProcessorInit); - - /* Register error IRQ handler && configure NVIC. */ - stcIrqSigninCfg.enIRQn = LP_UNIT_ERR_INT_IRQn; - stcIrqSigninCfg.enIntSrc = LP_UNIT_ERR_INT_SRC; - stcIrqSigninCfg.pfnCallback = &USART_RxErr_IrqCallback; - InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT); - - /* Register RX IRQ handler && configure NVIC. */ - stcIrqSigninCfg.enIRQn = LP_UNIT_RX_INT_IRQn; - stcIrqSigninCfg.enIntSrc = LP_UNIT_RX_INT_SRC; - stcIrqSigninCfg.pfnCallback = &USART_Rx_IrqCallback; - InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_00); - - /* Register TX IRQ handler && configure NVIC. */ - stcIrqSigninCfg.enIRQn = LP_UNIT_TX_INT_IRQn; - stcIrqSigninCfg.enIntSrc = LP_UNIT_TX_INT_SRC; - stcIrqSigninCfg.pfnCallback = &USART_TxEmpty_IrqCallback; - InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT); - - /* Register TC IRQ handler && configure NVIC. */ - stcIrqSigninCfg.enIRQn = LP_UNIT_TCI_INT_IRQn; - stcIrqSigninCfg.enIntSrc = LP_UNIT_TCI_INT_SRC; - stcIrqSigninCfg.pfnCallback = &USART_TxComplete_IrqCallback; - InstalIrqHandler(&stcIrqSigninCfg, DDL_IRQ_PRIORITY_DEFAULT); + if (Ok != USART_UartInit(DBG_UNIT, &stcUartInit)) + { + for (;;); + } } diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_serial.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_serial.c index 9398d5e27..5c4e9f861 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_serial.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_serial.c @@ -154,10 +154,21 @@ struct up_dev_s #endif const uint32_t irq; /* IRQ associated with this USART */ - const uint32_t apbclock; /* PCLK 1 or 2 frequency */ + const uint32_t clk_gate; const uint32_t usartbase; /* Base address of USART registers */ const uint32_t tx_gpio; /* U[S]ART TX GPIO pin configuration */ + const uint32_t tx_func; const uint32_t rx_gpio; /* U[S]ART RX GPIO pin configuration */ + const uint32_t rx_func; + const uint32_t rx_irq; + const uint32_t tx_irq; + const uint32_t txc_irq; + const uint32_t err_irq; + const uint32_t rxint_src; + const uint32_t txint_src; + const uint32_t txcint_src; + const uint32_t errint_src; + const stc_usart_uart_init_t param; // U[S]ART parameter #ifdef CONFIG_SERIAL_IFLOWCONTROL const uint32_t rts_gpio; /* U[S]ART RTS GPIO pin configuration */ #endif @@ -175,7 +186,6 @@ struct up_dev_s * Private Function Prototypes ****************************************************************************/ -static void up_set_format(struct uart_dev_s *dev); 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); @@ -194,13 +204,6 @@ static void up_txint(struct uart_dev_s *dev, bool enable); static bool up_txready(struct uart_dev_s *dev); -#ifdef CONFIG_PM -static void up_pm_notify(struct pm_callback_s *cb, int dowmin, - enum pm_state_e pmstate); -static int up_pm_prepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate); -#endif - /**************************************************************************** * Private Data ****************************************************************************/ @@ -557,35 +560,46 @@ static struct up_dev_s g_uart5priv = /* UART RX/TX Port/Pin definition */ #define USART_RX_PORT (GPIO_PORT_H) /* PH6: USART6_RX */ #define USART_RX_PIN (GPIO_PIN_06) -#define USART_RX_GPIO_FUNC (GPIO_FUNC_37_USART6_RX) +#define USART_RX_FUNC (GPIO_FUNC_37_USART6_RX) #define USART_TX_PORT (GPIO_PORT_E) /* PE6: USART6_TX */ #define USART_TX_PIN (GPIO_PIN_06) -#define USART_TX_GPIO_FUNC (GPIO_FUNC_36_USART6_TX) +#define USART_TX_FUNC (GPIO_FUNC_36_USART6_TX) /* UART unit definition */ #define USART_UNIT (M4_USART6) -#define USART_FUNCTION_CLK_GATE (PWC_FCG3_USART6) +#define USART_CLK_GATE (PWC_FCG3_USART6) /* UART unit interrupt definition */ #define USART_UNIT_ERR_INT_SRC (INT_USART6_EI) -#define USART_UNIT_ERR_INT_IRQn (Int015_IRQn + HC32_IRQ_FIRST) +#define USART_UNIT_ERR_INT_IRQn (Int011_IRQn + HC32_IRQ_FIRST) #define USART_UNIT_RX_INT_SRC (INT_USART6_RI) -#define USART_UNIT_RX_INT_IRQn (Int010_IRQn + HC32_IRQ_FIRST) +#define USART_UNIT_RX_INT_IRQn (Int012_IRQn + HC32_IRQ_FIRST) #define USART_UNIT_TX_INT_SRC (INT_USART6_TI) -#define USART_UNIT_TX_INT_IRQn (Int102_IRQn + HC32_IRQ_FIRST) +#define USART_UNIT_TX_INT_IRQn (Int013_IRQn + HC32_IRQ_FIRST) #define USART_UNIT_TCI_INT_SRC (INT_USART6_TCI) -#define USART_UNIT_TCI_INT_IRQn (Int099_IRQn + HC32_IRQ_FIRST) +#define USART_UNIT_TCI_INT_IRQn (Int014_IRQn + HC32_IRQ_FIRST) -#define HC32_UART6_BASE 0x40020C00UL// M4_USART6 -#define HC32_IRQ_USART6 (Int010_IRQn + HC32_IRQ_FIRST) #define GPIO_USART6_TX GPIO_PINSET(USART_TX_PORT, USART_TX_PIN) #define GPIO_USART6_RX GPIO_PINSET(USART_RX_PORT, USART_RX_PIN) -#define HC32_PCLK2_FREQUENCY 120000000 + +const stc_usart_uart_init_t usart6config = { + .u32Baudrate = BSP_PRINTF_BAUDRATE, + .u32BitDirection = USART_LSB, + .u32StopBit = USART_STOPBIT_1BIT, + .u32Parity = USART_PARITY_NONE, + .u32DataWidth = USART_DATA_LENGTH_8BIT, + .u32ClkMode = USART_INTERNCLK_OUTPUT, + .u32PclkDiv = USART_PCLK_DIV64, + .u32OversamplingBits = USART_OVERSAMPLING_8BIT, + .u32NoiseFilterState = USART_NOISE_FILTER_DISABLE, + .u32SbDetectPolarity = USART_SB_DETECT_FALLING, +}; + static struct up_dev_s g_usart6priv = { @@ -608,15 +622,35 @@ static struct up_dev_s g_usart6priv = .priv = &g_usart6priv, }, - .irq = HC32_IRQ_USART6, - .parity = CONFIG_UART6_PARITY, - .bits = CONFIG_UART6_BITS, - .stopbits2 = CONFIG_UART6_2STOP, - .baud = CONFIG_UART6_BAUD, - .apbclock = HC32_PCLK2_FREQUENCY, - .usartbase = HC32_UART6_BASE, + .irq = USART_UNIT_RX_INT_IRQn, + .rx_irq = USART_UNIT_RX_INT_IRQn, + .tx_irq = USART_UNIT_TX_INT_IRQn, + .txc_irq = USART_UNIT_TCI_INT_IRQn, + .err_irq = USART_UNIT_ERR_INT_IRQn, + .rxint_src = USART_UNIT_RX_INT_SRC, + .txint_src = USART_UNIT_TX_INT_SRC, + .txcint_src = USART_UNIT_TCI_INT_SRC, + .errint_src = USART_UNIT_ERR_INT_SRC, + + .clk_gate = USART_CLK_GATE, + .usartbase = (uint32_t)USART_UNIT, .tx_gpio = GPIO_USART6_TX, + .tx_func = USART_TX_FUNC, .rx_gpio = GPIO_USART6_RX, + .rx_func = USART_RX_FUNC, + .param = + { + .u32Baudrate = BSP_PRINTF_BAUDRATE, + .u32BitDirection = USART_LSB, + .u32StopBit = USART_STOPBIT_1BIT, + .u32Parity = USART_PARITY_NONE, + .u32DataWidth = USART_DATA_LENGTH_8BIT, + .u32ClkMode = USART_INTERNCLK_OUTPUT, + .u32PclkDiv = USART_PCLK_DIV64, + .u32OversamplingBits = USART_OVERSAMPLING_8BIT, + .u32NoiseFilterState = USART_NOISE_FILTER_DISABLE, + .u32SbDetectPolarity = USART_SB_DETECT_FALLING + }, #if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_USART6_OFLOWCONTROL) .oflow = true, .cts_gpio = GPIO_USART6_CTS, @@ -637,112 +671,7 @@ static struct up_dev_s g_usart6priv = }; #endif -/* This describes the state of the HC32 UART7 port. */ - -#ifdef CONFIG_UART7_SERIALDRIVER -static struct up_dev_s g_uart7priv = -{ - .dev = - { -#if CONSOLE_UART == 7 - .isconsole = true, -#endif - .recv = - { - .size = CONFIG_UART7_RXBUFSIZE, - .buffer = g_uart7rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART7_TXBUFSIZE, - .buffer = g_uart7txbuffer, - }, - - .ops = &g_uart_ops, - .priv = &g_uart7priv, - }, - - .irq = HC32_IRQ_UART7, - .parity = CONFIG_UART7_PARITY, - .bits = CONFIG_UART7_BITS, - .stopbits2 = CONFIG_UART7_2STOP, - .baud = CONFIG_UART7_BAUD, - .apbclock = HC32_PCLK1_FREQUENCY, - .usartbase = HC32_UART7_BASE, - .tx_gpio = GPIO_UART7_TX, - .rx_gpio = GPIO_UART7_RX, -#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART7_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART7_CTS, -#endif -#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART7_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART7_RTS, -#endif - -#ifdef CONFIG_UART7_RS485 - .rs485_dir_gpio = GPIO_UART7_RS485_DIR, -# if (CONFIG_UART7_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, -# else - .rs485_dir_polarity = true, -# endif -#endif -}; -#endif - -/* This describes the state of the HC32 UART8 port. */ - -#ifdef CONFIG_UART8_SERIALDRIVER -static struct up_dev_s g_uart8priv = -{ - .dev = - { -#if CONSOLE_UART == 8 - .isconsole = true, -#endif - .recv = - { - .size = CONFIG_UART8_RXBUFSIZE, - .buffer = g_uart8rxbuffer, - }, - .xmit = - { - .size = CONFIG_UART8_TXBUFSIZE, - .buffer = g_uart8txbuffer, - }, - .ops = &g_uart_ops, - .priv = &g_uart8priv, - }, - - .irq = HC32_IRQ_UART8, - .parity = CONFIG_UART8_PARITY, - .bits = CONFIG_UART8_BITS, - .stopbits2 = CONFIG_UART8_2STOP, - .baud = CONFIG_UART8_BAUD, - .apbclock = HC32_PCLK1_FREQUENCY, - .usartbase = HC32_UART8_BASE, - .tx_gpio = GPIO_UART8_TX, - .rx_gpio = GPIO_UART8_RX, -#if defined(CONFIG_SERIAL_OFLOWCONTROL) && defined(CONFIG_UART8_OFLOWCONTROL) - .oflow = true, - .cts_gpio = GPIO_UART8_CTS, -#endif -#if defined(CONFIG_SERIAL_IFLOWCONTROL) && defined(CONFIG_UART8_IFLOWCONTROL) - .iflow = true, - .rts_gpio = GPIO_UART8_RTS, -#endif - -#ifdef CONFIG_UART8_RS485 - .rs485_dir_gpio = GPIO_UART8_RS485_DIR, -# if (CONFIG_UART8_RS485_DIR_POLARITY == 0) - .rs485_dir_polarity = false, -# else - .rs485_dir_polarity = true, -# endif -#endif -}; -#endif +static struct up_dev_s *g_uart_rx_dev = &g_usart6priv; /* This table lets us iterate over the configured USARTs */ @@ -774,35 +703,114 @@ static struct up_dev_s * const g_uart_devs[HC32_NUSART] = #endif }; -#ifdef CONFIG_PM -static struct pm_callback_s g_serialcb = +static inline uint32_t up_serialin(struct up_dev_s *priv, int offset); + +void hc32_rx_irq_cb(void) { - .notify = up_pm_notify, - .prepare = up_pm_prepare, -}; -#endif + up_interrupt(g_uart_rx_dev->rx_irq, NULL, g_uart_rx_dev); +} + +void hc32_tx_irq_cb(void) +{ + up_interrupt(g_uart_rx_dev->tx_irq, NULL, g_uart_rx_dev); +} + +void hc32_txc_irq_cb(void) +{ + up_interrupt(g_uart_rx_dev->txc_irq, NULL, g_uart_rx_dev); +} + +void hc32_err_irq_cb(void) +{ + up_interrupt(g_uart_rx_dev->err_irq, NULL, g_uart_rx_dev); +} + +void hc32_handle_recv_buf(void) +{ + struct up_dev_s *priv = g_uart_rx_dev; + struct uart_buffer_s *recv = &priv->dev.recv; + char recv_buf[255] = {0}; + int i, j = 0; + static int cnt = 0; + static int last_tail = 0; + + if((recv->head != recv->tail) && (cnt ++ > 30)) + { + last_tail = recv->tail; + for(i = recv->tail; i < recv->head; i ++) + { + recv_buf[j++] = recv->buffer[last_tail++]; + } + hc32_console_handle(recv_buf); + hc32_print("nsh>%s\n", recv_buf); + recv->tail = recv->head; + cnt = 0; + last_tail = 0; + } +} + +void hc32_handle_xmit_buf(void) +{ + struct up_dev_s *priv = g_uart_rx_dev; + int i, j = 0; + char xmit_buf[255] = {0}; + + if(priv->dev.xmit.tail != priv->dev.xmit.head) + { + for(i = priv->dev.xmit.tail; i < priv->dev.xmit.head; i ++) + { + xmit_buf[j++] = priv->dev.xmit.buffer[i++]; + } + hc32_print("nsh>%s", xmit_buf); + } +} + +void hc32_uart_handle(void) +{ + hc32_handle_recv_buf(); +} /**************************************************************************** * Private Functions ****************************************************************************/ -void hc32_print(const char *fmt, ...) +int hc32_print(const char *fmt, ...) { - int i; + int i, ret; va_list ap; char buf[256]; memset(buf, 0, sizeof(buf)); va_start(ap, fmt); - vsnprintf(buf, 255, fmt, ap); + ret = vsnprintf(buf, 255, fmt, ap); va_end(ap); + USART_FuncCmd(USART_UNIT, USART_RX | USART_TX, Enable); - USART_FuncCmd(USART_UNIT, USART_TX, Enable); + arm_lowputc('-'); + arm_lowputc(' '); for (i = 0; i < strlen(buf); i++) { - while(Set != USART_GetStatus(USART_UNIT, USART_FLAG_TXE)); - USART_SendData(USART_UNIT, (uint16_t)*(buf + i)); + arm_lowputc((uint16_t)*(buf + i)); + } + return ret; +} + +/** + * @brief Instal IRQ handler. + * @param [in] pstcConfig Pointer to struct @ref stc_irq_signin_config_t + * @param [in] u32Priority Interrupt priority + * @retval None + */ +static void hc32_enable_irq(const stc_irq_signin_config_t *pstcConfig, + uint32_t u32Priority) +{ + if (NULL != pstcConfig) + { + (void)INTC_IrqSignIn(pstcConfig); + NVIC_ClearPendingIRQ(pstcConfig->enIRQn); + NVIC_SetPriority(pstcConfig->enIRQn, u32Priority); + NVIC_EnableIRQ(pstcConfig->enIRQn); } } @@ -825,6 +833,7 @@ static inline void up_serialout(struct up_dev_s *priv, int offset, putreg32(value, priv->usartbase + offset); } + /**************************************************************************** * Name: up_setusartint ****************************************************************************/ @@ -832,7 +841,6 @@ static inline void up_serialout(struct up_dev_s *priv, int offset, static inline void up_setusartint(struct up_dev_s *priv, uint16_t ie) { uint32_t cr; - M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; /* Save the interrupt mask */ @@ -842,12 +850,12 @@ static inline void up_setusartint(struct up_dev_s *priv, uint16_t ie) * table above) */ - cr = up_serialin(priv, base->_CR1); + cr = up_serialin(priv, offsetof(M4_USART_TypeDef, _CR1)); cr &= ~(USART_CR1_USED_INTS); cr |= (ie & (USART_CR1_USED_INTS)); - up_serialout(priv, base->_CR1, cr); -// -// cr = up_serialin(priv, base->_CR3); + up_serialout(priv, offsetof(M4_USART_TypeDef, _CR1), cr); + +// cr = up_serialin(priv, offsetof(M4_USART_TypeDef, _CR3)); // cr &= ~USART_CR3_EIE; // cr |= (ie & USART_CR3_EIE); // up_serialout(priv, base->_CR3, cr); @@ -861,8 +869,6 @@ static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie) { irqstate_t flags; -// hc32_print("check %s line %d\n", __func__, __LINE__); - flags = enter_critical_section(); up_setusartint(priv, ie); @@ -877,7 +883,6 @@ static void up_restoreusartint(struct up_dev_s *priv, uint16_t ie) static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) { irqstate_t flags; - M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; flags = enter_critical_section(); @@ -903,7 +908,7 @@ static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) * USART_CR3_CTSIE USART_SR_CTS CTS flag (not used) */ - cr1 = up_serialin(priv, base->_CR1); + cr1 = up_serialin(priv, offsetof(M4_USART_TypeDef, _CR1)); *ie = cr1 & (USART_CR1_USED_INTS); } @@ -914,36 +919,44 @@ static void up_disableusartint(struct up_dev_s *priv, uint16_t *ie) leave_critical_section(flags); } -/**************************************************************************** - * Name: up_set_format - * - * Description: - * Set the serial line format and speed. - * - ****************************************************************************/ - -#ifndef CONFIG_SUPPRESS_UART_CONFIG -static void up_set_format(struct uart_dev_s *dev) +static int hc32_enable_serialirq(struct uart_dev_s *dev) { + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + stc_irq_signin_config_t cfg; -} -#endif /* CONFIG_SUPPRESS_UART_CONFIG */ + { + memset(&cfg, 0, sizeof(cfg)); + cfg.enIRQn = priv->rx_irq - HC32_IRQ_FIRST; + cfg.enIntSrc = priv->rxint_src; + cfg.pfnCallback = &hc32_rx_irq_cb; + hc32_enable_irq(&cfg, DDL_IRQ_PRIORITY_DEFAULT); + } -/**************************************************************************** - * Name: up_set_apb_clock - * - * Description: - * Enable or disable APB clock for the USART peripheral - * - * Input Parameters: - * dev - A reference to the UART driver state structure - * on - Enable clock if 'on' is 'true' and disable if 'false' - * - ****************************************************************************/ + { + memset(&cfg, 0, sizeof(cfg)); + cfg.enIRQn = priv->tx_irq - HC32_IRQ_FIRST; + cfg.enIntSrc = priv->txint_src; + cfg.pfnCallback = &hc32_tx_irq_cb; + hc32_enable_irq(&cfg, DDL_IRQ_PRIORITY_DEFAULT); + } -static void up_set_apb_clock(struct uart_dev_s *dev, bool on) -{ + { + memset(&cfg, 0, sizeof(cfg)); + cfg.enIRQn = priv->txc_irq - HC32_IRQ_FIRST; + cfg.enIntSrc = priv->txcint_src; + cfg.pfnCallback = &hc32_txc_irq_cb; + hc32_enable_irq(&cfg, DDL_IRQ_PRIORITY_DEFAULT); + } + { + memset(&cfg, 0, sizeof(cfg)); + cfg.enIRQn = priv->err_irq - HC32_IRQ_FIRST; + cfg.enIntSrc = priv->errint_src; + cfg.pfnCallback = &hc32_err_irq_cb; + hc32_enable_irq(&cfg, DDL_IRQ_PRIORITY_DEFAULT); + } + + return OK; } /**************************************************************************** @@ -954,111 +967,13 @@ static void up_set_apb_clock(struct uart_dev_s *dev, bool on) * 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; - M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; - - hc32_print("%s irq %d\n", __func__, priv->irq); - -#ifndef CONFIG_SUPPRESS_UART_CONFIG - uint32_t regval; - - /* Note: The logic here depends on the fact that that the USART module - * was enabled in hc32_lowsetup(). - */ - - /* Enable USART APB1/2 clock */ - - up_set_apb_clock(dev, true); - - /* Configure pins for USART use */ - - hc32_configgpio(priv->tx_gpio); - hc32_configgpio(priv->rx_gpio); - -#ifdef CONFIG_SERIAL_OFLOWCONTROL - if (priv->cts_gpio != 0) - { - hc32_configgpio(priv->cts_gpio); - } -#endif - -#ifdef CONFIG_SERIAL_IFLOWCONTROL - if (priv->rts_gpio != 0) - { - uint32_t config = priv->rts_gpio; - -#ifdef CONFIG_HC32_FLOWCONTROL_BROKEN - /* Instead of letting hw manage this pin, we will bitbang */ - - config = (config & ~GPIO_MODE_MASK) | GPIO_OUTPUT; -#endif - hc32_configgpio(config); - } -#endif - -#ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) - { - hc32_configgpio(priv->rs485_dir_gpio); - hc32_gpiowrite(priv->rs485_dir_gpio, !priv->rs485_dir_polarity); - } -#endif - - /* Configure CR2 - * Clear STOP, CLKEN, CPOL, CPHA, LBCL, and interrupt enable bits - */ - - regval = up_serialin(priv, base->_CR2); - - regval &= ~(USART_CR2_STOP | USART_CR2_CLKC | USART_CR2_WKUPE | - USART_CR2_SBKL | USART_CR2_LBDL | USART_CR2_LBDIE); - - /* Configure STOP bits */ - - if (priv->stopbits2) - { - regval |= USART_CR2_STOP; - } - - up_serialout(priv, base->_CR2, regval); - - /* Configure CR1 - * Clear TE, REm and all interrupt enable bits - */ - - regval = up_serialin(priv, base->_CR1); - regval &= ~(USART_CR1_TE | USART_CR1_RE | USART_CR1_USED_INTS); - - up_serialout(priv, base->_CR1, regval); - - /* Configure CR3 - * Clear CTSE, RTSE, and all interrupt enable bits - */ - - regval = up_serialin(priv, base->_CR3); - regval &= ~(USART_CR3_CTSE | USART_CR3_RTSE); - - up_serialout(priv, base->_CR3, regval); - - /* Configure the USART line format and speed. */ - - up_set_format(dev); - - /* Enable Rx, Tx, and the USART */ - - regval = up_serialin(priv, base->_CR1); - regval |= (USART_CR1_TE | USART_CR1_RE | USART_CR1_USED_INTS); - - up_serialout(priv, base->_CR1, regval); - -#endif /* CONFIG_SUPPRESS_UART_CONFIG */ /* Set up the cached interrupt enables value */ - priv->ie = 0; + priv->ie = 0; /* Mark device as initialized. */ @@ -1079,11 +994,8 @@ static int up_setup(struct uart_dev_s *dev) static void up_shutdown(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; - M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; uint32_t regval; - hc32_print("check %s line %d\n", __func__, __LINE__); - /* Mark device as uninitialized. */ priv->initialized = false; @@ -1092,15 +1004,11 @@ static void up_shutdown(struct uart_dev_s *dev) up_disableusartint(priv, NULL); - /* Disable USART APB1/2 clock */ - - up_set_apb_clock(dev, false); - /* Disable Rx, Tx, and the UART */ - regval = up_serialin(priv, base->_CR1); + regval = up_serialin(priv, offsetof(M4_USART_TypeDef, _CR1)); regval &= ~( USART_CR1_TE | USART_CR1_RE); - up_serialout(priv, base->_CR1, regval); + up_serialout(priv, offsetof(M4_USART_TypeDef, _CR1), regval); /* Release pins. "If the serial-attached device is powered down, the TX * pin causes back-powering, potentially confusing the device to the point @@ -1154,20 +1062,12 @@ static void up_shutdown(struct uart_dev_s *dev) static int up_attach(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; - int ret; + int ret = 0; - /* Attach and enable the IRQ */ - - ret = irq_attach(priv->irq, up_interrupt, priv); - if (ret == OK) - { - /* Enable the interrupt (RX and TX interrupts are still disabled - * in the USART - */ - - up_enable_irq(priv->irq); - } + hc32_print("%s: attach irq rx %d %d tx %d %d\n", __func__, priv->rx_irq, priv->rxint_src, + priv->tx_irq, priv->txint_src); + ret = hc32_enable_serialirq(dev); return ret; } @@ -1205,20 +1105,11 @@ static void up_detach(struct uart_dev_s *dev) static int up_interrupt(int irq, void *context, void *arg) { struct up_dev_s *priv = (struct up_dev_s *)arg; - M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; int passes; bool handled; - hc32_print("check %s irq %d come\n", __func__, irq); - DEBUGASSERT(priv != NULL); - /* Report serial activity to the power management logic */ - -#if defined(CONFIG_PM) && CONFIG_HC32_PM_SERIAL_ACTIVITY > 0 - pm_activity(PM_IDLE_DOMAIN, CONFIG_HC32_PM_SERIAL_ACTIVITY); -#endif - /* Loop until there are no characters to be transferred or, * until we have been looping for a long time. */ @@ -1230,7 +1121,7 @@ static int up_interrupt(int irq, void *context, void *arg) /* Get the masked USART status word. */ - priv->sr = up_serialin(priv, base->SR); + priv->sr = up_serialin(priv, offsetof(M4_USART_TypeDef, SR)); /* USART interrupts: * @@ -1279,7 +1170,6 @@ static int up_interrupt(int irq, void *context, void *arg) * for RXNEIE: We cannot call uart_recvchards of RX interrupts are * disabled. */ - uart_recvchars(&priv->dev); handled = true; } @@ -1290,15 +1180,7 @@ static int up_interrupt(int irq, void *context, void *arg) else if ((priv->sr & (USART_SR_ORE | USART_SR_RXNE | USART_SR_FE)) != 0) { -#if defined(CONFIG_HC32_HC32F30XX) || defined(CONFIG_HC32_HC32F33XX) || \ - defined(CONFIG_HC32_HC32F37XX) || defined(CONFIG_HC32_HC32G4XXX) - /* These errors are cleared by writing the corresponding bit to the - * interrupt clear register (ICR). - */ - up_serialout(priv, HC32_UART_ICR_OFFSET, - (USART_ICR_NCF | USART_ICR_ORECF | USART_ICR_FECF)); -#else /* If an error occurs, read from DR to clear the error (data has * been lost). If ORE is set along with RXNE then it tells you * that the byte *after* the one in the data register has been @@ -1307,8 +1189,7 @@ static int up_interrupt(int irq, void *context, void *arg) * good byte will be lost. */ - up_serialin(priv, base->DR); //RDR -#endif + up_serialin(priv, offsetof(M4_USART_TypeDef, DR)); //RDR } /* Handle outgoing, transmit bytes */ @@ -1321,6 +1202,7 @@ static int up_interrupt(int irq, void *context, void *arg) uart_xmitchars(&priv->dev); handled = true; } + } return OK; @@ -1343,12 +1225,9 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) #endif #if defined(CONFIG_SERIAL_TERMIOS) || defined(CONFIG_HC32_SERIALBRK_BSDCOMPAT) struct up_dev_s *priv = (struct up_dev_s *)dev->priv; - M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; #endif int ret = OK; - hc32_print("check %s line %d\n", __func__, __LINE__); - switch (cmd) { #ifdef CONFIG_SERIAL_TIOCSERGSTRUCT @@ -1374,7 +1253,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) * half-duplex mode. */ - uint32_t cr = up_serialin(priv, base->_CR3); + uint32_t cr = up_serialin(priv, offsetof(M4_USART_TypeDef, _CR3)); #if defined(CONFIG_HC32_HC32F10XX) if ((arg & SER_SINGLEWIRE_ENABLED) != 0) @@ -1509,9 +1388,7 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) /* Effect the changes immediately - note that we do not implement * TCSADRAIN / TCSAFLUSH */ - - up_set_format(dev); - } + } break; #endif /* CONFIG_SERIAL_TERMIOS */ @@ -1566,8 +1443,8 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) irqstate_t flags; flags = enter_critical_section(); - cr1 = up_serialin(priv, base->_CR1); - up_serialout(priv, base->_CR1, cr1 | USART_CR1_SBK); + cr1 = up_serialin(priv, offsetof(M4_USART_TypeDef, _CR1)); + up_serialout(priv, offsetof(M4_USART_TypeDef, _CR1), cr1 | USART_CR1_SBK); leave_critical_section(flags); } break; @@ -1578,8 +1455,8 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) irqstate_t flags; flags = enter_critical_section(); - cr1 = up_serialin(priv, base->_CR1); - up_serialout(priv, base->_CR1, cr1 & ~USART_CR1_SBK); + cr1 = up_serialin(priv, offsetof(M4_USART_TypeDef, _CR1)); + up_serialout(priv, offsetof(M4_USART_TypeDef, _CR1), cr1 & ~USART_CR1_SBK); leave_critical_section(flags); } break; @@ -1606,10 +1483,19 @@ static int up_ioctl(struct file *filep, int cmd, unsigned long arg) static int up_receive(struct uart_dev_s *dev, unsigned int *status) { + int val; struct up_dev_s *priv = (struct up_dev_s *)dev->priv; M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; - return USART_RecData(base); + val = USART_RecData(base); + + if (status) + { + *status = priv->sr; + priv->sr = 0; + } + + return val; } /**************************************************************************** @@ -1649,24 +1535,33 @@ static void up_rxint(struct uart_dev_s *dev, bool enable) * (or an Rx timeout occurs). */ -#ifndef CONFIG_SUPPRESS_SERIAL_INTS -#ifdef CONFIG_USART_ERRINTS - ie |= (USART_CR1_RIE | USART_CR1_PCE); -#else ie |= USART_CR1_RIE; -#endif -#endif + + up_enable_irq(priv->irq); + + /* Enable TX && RX && RX interrupt function */ + USART_FuncCmd((M4_USART_TypeDef *)priv->usartbase, + (USART_RX | USART_INT_RX | USART_TX | \ + USART_RTO | USART_INT_RTO), Enable); + } else { -// ie &= ~(USART_CR1_RIE | USART_CR1_PCE ); - ie &= ~(USART_CR1_RIE); + ie &= ~(USART_CR1_RIE); + up_disable_irq(priv->irq); + + USART_FuncCmd((M4_USART_TypeDef *)priv->usartbase, + (USART_RX | USART_INT_RX | USART_TX | \ + USART_RTO | USART_INT_RTO), Disable); } /* Then set the new interrupt state */ up_restoreusartint(priv, ie); leave_critical_section(flags); + + hc32_print("%s: opened %d irq %d %s ie %x\n", __func__, dev->open_count, priv->irq, + enable ? "enable" : "disable", ie); } /**************************************************************************** @@ -1676,17 +1571,12 @@ static void up_rxint(struct uart_dev_s *dev, bool enable) * Return true if the receive register is not empty * ****************************************************************************/ - -//#if defined(SERIAL_HAVE_TXDMA_OPS) || defined(SERIAL_HAVE_NODMA_OPS) static bool up_rxavailable(struct uart_dev_s *dev) { - hc32_print("check %s line %d\n", __func__, __LINE__); - struct up_dev_s *priv = (struct up_dev_s *)dev->priv; M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; - return ((up_serialin(priv, base->SR) & USART_SR_RXNE) != 0); + return (Set == USART_GetStatus(base, USART_FLAG_RXNE)); } -//#endif /**************************************************************************** * Name: up_rxflowcontrol @@ -1796,8 +1686,9 @@ static bool up_rxflowcontrol(struct uart_dev_s *dev, static void up_send(struct uart_dev_s *dev, int ch) { - while(Set != USART_GetStatus(USART_UNIT, USART_FLAG_TXE)); - USART_SendData(USART_UNIT, (uint16_t)(ch)); + struct up_dev_s *priv = (struct up_dev_s *)dev->priv; + while(Set != USART_GetStatus((const M4_USART_TypeDef *)priv->usartbase, USART_FLAG_TXE)); + USART_SendData((M4_USART_TypeDef *)priv->usartbase, (uint16_t)(ch)); } /**************************************************************************** @@ -1827,37 +1718,7 @@ static void up_txint(struct uart_dev_s *dev, bool enable) { /* Set to receive an interrupt when the TX data register is empty */ -#ifndef CONFIG_SUPPRESS_SERIAL_INTS - uint16_t ie = priv->ie | USART_CR1_TXEIE; - - /* If RS-485 is supported on this U[S]ART, then also enable the - * transmission complete interrupt. - */ - -# ifdef HAVE_RS485 - if (priv->rs485_dir_gpio != 0) - { - ie |= USART_CR1_TCIE; - } -# endif - -# ifdef CONFIG_HC32_SERIALBRK_BSDCOMPAT - if (priv->ie & USART_CR1_IE_BREAK_INPROGRESS) - { - leave_critical_section(flags); - return; - } -# endif - - up_restoreusartint(priv, ie); - -#else - /* Fake a TX interrupt here by just calling uart_xmitchars() with - * interrupts disabled (note this may recurse). - */ - uart_xmitchars(dev); -#endif } else { @@ -1881,113 +1742,11 @@ static bool up_txready(struct uart_dev_s *dev) { struct up_dev_s *priv = (struct up_dev_s *)dev->priv; M4_USART_TypeDef *base = (M4_USART_TypeDef *)priv->usartbase; - return ((up_serialin(priv, base->SR) & USART_SR_TXE) != 0); + + return((Set == USART_GetStatus(base, USART_FLAG_TXE)) + || (Set == USART_GetStatus(base, USART_FLAG_TC))); } -/**************************************************************************** - * Name: up_pm_notify - * - * Description: - * Notify the driver of new power state. This callback is called after - * all drivers have had the opportunity to prepare for the new power state. - * - * Input Parameters: - * - * cb - Returned to the driver. The driver version of the callback - * structure may include additional, driver-specific state data at - * the end of the structure. - * - * pmstate - Identifies the new PM state - * - * Returned Value: - * None - The driver already agreed to transition to the low power - * consumption state when when it returned OK to the prepare() call. - * - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static void up_pm_notify(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) -{ - switch (pmstate) - { - case(PM_NORMAL): - { - /* Logic for PM_NORMAL goes here */ - } - break; - - case(PM_IDLE): - { - /* Logic for PM_IDLE goes here */ - } - break; - - case(PM_STANDBY): - { - /* Logic for PM_STANDBY goes here */ - } - break; - - case(PM_SLEEP): - { - /* Logic for PM_SLEEP goes here */ - } - break; - - default: - { - /* Should not get here */ - } - break; - } -} -#endif - -/**************************************************************************** - * Name: up_pm_prepare - * - * Description: - * Request the driver to prepare for a new power state. This is a warning - * that the system is about to enter into a new power state. The driver - * should begin whatever operations that may be required to enter power - * state. The driver may abort the state change mode by returning a - * non-zero value from the callback function. - * - * Input Parameters: - * - * cb - Returned to the driver. The driver version of the callback - * structure may include additional, driver-specific state data at - * the end of the structure. - * - * pmstate - Identifies the new PM state - * - * Returned Value: - * Zero - (OK) means the event was successfully processed and that the - * driver is prepared for the PM state change. - * - * Non-zero - means that the driver is not prepared to perform the tasks - * needed achieve this power setting and will cause the state - * change to be aborted. NOTE: The prepare() method will also - * be called when reverting from lower back to higher power - * consumption modes (say because another driver refused a - * lower power state change). Drivers are not permitted to - * return non-zero values when reverting back to higher power - * consumption modes! - * - * - ****************************************************************************/ - -#ifdef CONFIG_PM -static int up_pm_prepare(struct pm_callback_s *cb, int domain, - enum pm_state_e pmstate) -{ - /* Logic to prepare for a reduced power state goes here. */ - - return OK; -} -#endif #endif /* HAVE_SERIALDRIVER */ #endif /* USE_SERIALDRIVER */ @@ -2075,9 +1834,7 @@ void arm_serialinit(void) char devname[16]; unsigned i; unsigned minor = 0; -#ifdef CONFIG_PM int ret; -#endif /* Register to receive power management callbacks */ @@ -2090,15 +1847,17 @@ void arm_serialinit(void) /* Register the console */ #if CONSOLE_UART > 0 - uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); + ret = uart_register("/dev/console", &g_uart_devs[CONSOLE_UART - 1]->dev); #ifndef CONFIG_HC32_SERIAL_DISABLE_REORDERING /* If not disabled, register the console UART to ttyS0 and exclude * it from initializing it further down */ - uart_register("/dev/ttyS0", &g_uart_devs[CONSOLE_UART - 1]->dev); + ret = uart_register("/dev/ttyS0", &g_uart_devs[CONSOLE_UART - 1]->dev); minor = 1; + + hc32_print("register /dev/ttyS0 %d = %d\n", CONSOLE_UART - 1, ret); #endif #endif /* CONSOLE_UART > 0 */ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spi.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spi.c new file mode 100755 index 000000000..11ba985cb --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spi.c @@ -0,0 +1,189 @@ +/** + ******************************************************************************* + * @file arch/arm/src/hc32/hc32_spi.c + * @brief SPI write read flash API for the Device Driver Library. + @verbatim + Change Logs: + Date Author Notes + 2020-06-12 Wangmin First version + 2020-10-13 Wangmin Modify spelling mistake + @endverbatim + ******************************************************************************* + * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by HDSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "hc32_ddl.h" +#include "hc32_spi.h" + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief MCU Peripheral registers write unprotected. + * @param None + * @retval None + * @note Comment/uncomment each API depending on APP requires. + */ +static void Peripheral_WE(void) +{ + /* Unlock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */ + GPIO_Unlock(); + /* Unlock PWC register: FCG0 */ + PWC_FCG0_Unlock(); + /* Unlock PWC, CLK, PVD registers, @ref PWC_REG_Write_Unlock_Code for details */ + PWC_Unlock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1 | PWC_UNLOCK_CODE_2); + /* Unlock SRAM register: WTCR */ + SRAM_WTCR_Unlock(); + /* Unlock SRAM register: CKCR */ + //SRAM_CKCR_Unlock(); + /* Unlock all EFM registers */ + EFM_Unlock(); + /* Unlock EFM register: FWMC */ + //EFM_FWMC_Unlock(); + /* Unlock EFM OTP write protect registers */ + //EFM_OTP_WP_Unlock(); + /* Unlock all MPU registers */ + // MPU_Unlock(); +} + +/** + * @brief MCU Peripheral registers write protected. + * @param None + * @retval None + * @note Comment/uncomment each API depending on APP requires. + */ +static __attribute__((unused)) void Peripheral_WP(void) +{ + /* Lock GPIO register: PSPCR, PCCR, PINAER, PCRxy, PFSRxy */ + GPIO_Lock(); + /* Lock PWC register: FCG0 */ + PWC_FCG0_Lock(); + /* Lock PWC, CLK, PVD registers, @ref PWC_REG_Write_Unlock_Code for details */ + PWC_Lock(PWC_UNLOCK_CODE_0 | PWC_UNLOCK_CODE_1 | PWC_UNLOCK_CODE_2); + /* Lock SRAM register: WTCR */ + SRAM_WTCR_Lock(); + /* Lock SRAM register: CKCR */ + //SRAM_CKCR_Lock(); + /* Lock EFM OTP write protect registers */ + //EFM_OTP_WP_Lock(); + /* Lock EFM register: FWMC */ + //EFM_FWMC_Lock(); + /* Lock all EFM registers */ + EFM_Lock(); + /* Lock all MPU registers */ + // MPU_Lock(); +} + +/** + * @brief Configure SPI peripheral function + * + * @param [in] None + * + * @retval None + */ +static void Spi_Config(void) +{ + stc_spi_init_t stcSpiInit; + stc_spi_delay_t stcSpiDelayCfg; + + /* Clear initialize structure */ + (void)SPI_StructInit(&stcSpiInit); + (void)SPI_DelayStructInit(&stcSpiDelayCfg); + + /* Configure peripheral clock */ + PWC_Fcg1PeriphClockCmd(SPI_UNIT_CLOCK, Enable); + + /* SPI De-initialize */ + SPI_DeInit(SPI_UNIT); + + /* Configuration SPI structure */ + stcSpiInit.u32WireMode = SPI_WIRE_3; + stcSpiInit.u32TransMode = SPI_FULL_DUPLEX; + stcSpiInit.u32MasterSlave = SPI_MASTER; + stcSpiInit.u32SuspMode = SPI_COM_SUSP_FUNC_OFF; + stcSpiInit.u32Modfe = SPI_MODFE_DISABLE; + stcSpiInit.u32Parity = SPI_PARITY_INVALID; + stcSpiInit.u32SpiMode = SPI_MODE_0; + stcSpiInit.u32BaudRatePrescaler = SPI_BR_PCLK1_DIV256; + stcSpiInit.u32DataBits = SPI_DATA_SIZE_8BIT; + stcSpiInit.u32FirstBit = SPI_FIRST_MSB; + (void)SPI_Init(SPI_UNIT, &stcSpiInit); + + stcSpiDelayCfg.u32IntervalDelay = SPI_INTERVAL_TIME_8SCK_2PCLK1; + stcSpiDelayCfg.u32ReleaseDelay = SPI_RELEASE_TIME_8SCK; + stcSpiDelayCfg.u32SetupDelay = SPI_SETUP_TIME_1SCK; + (void)SPI_DelayTimeCfg(SPI_UNIT, &stcSpiDelayCfg); + + SPI_FunctionCmd(SPI_UNIT, Enable); +} + + +int hc32_spi_init(void) +{ + stc_gpio_init_t stcGpioCfg; + + Peripheral_WE(); + + /* Port configurate */ + (void)GPIO_StructInit(&stcGpioCfg); + + /* High driving capacity for output pin. */ + stcGpioCfg.u16PinDir = PIN_DIR_OUT; + stcGpioCfg.u16PinDrv = PIN_DRV_HIGH; + stcGpioCfg.u16PinState = PIN_STATE_SET; + (void)GPIO_Init(SPI_NSS_PORT, SPI_NSS_PIN, &stcGpioCfg); + + (void)GPIO_StructInit(&stcGpioCfg); + stcGpioCfg.u16PinDrv = PIN_DRV_HIGH; + (void)GPIO_Init(SPI_SCK_PORT, SPI_SCK_PIN, &stcGpioCfg); + (void)GPIO_Init(SPI_MOSI_PORT, SPI_MOSI_PIN, &stcGpioCfg); + + /* CMOS input for input pin */ + stcGpioCfg.u16PinDrv = PIN_DRV_LOW; + stcGpioCfg.u16PinIType = PIN_ITYPE_CMOS; + (void)GPIO_Init(SPI_MISO_PORT, SPI_MISO_PIN, &stcGpioCfg); + + /* Configure SPI Port function for master */ + GPIO_SetFunc(SPI_SCK_PORT, SPI_SCK_PIN, SPI_SCK_FUNC, PIN_SUBFUNC_DISABLE); + GPIO_SetFunc(SPI_MOSI_PORT, SPI_MOSI_PIN, SPI_MOSI_FUNC, PIN_SUBFUNC_DISABLE); + GPIO_SetFunc(SPI_MISO_PORT, SPI_MISO_PIN, SPI_MISO_FUNC, PIN_SUBFUNC_DISABLE); + + /* Configure SPI for SPI flash */ + Spi_Config(); + + Peripheral_WP(); + return OK; +} + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spi.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spi.h new file mode 100755 index 000000000..d9a26f4df --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spi.h @@ -0,0 +1,77 @@ +/** + ******************************************************************************* + * @file arch/arm/src/hc32/hc32_spi.h + * @brief SPI write read flash API for the Device Driver Library. + @verbatim + Change Logs: + Date Author Notes + 2020-06-12 Wangmin First version + 2020-10-13 Wangmin Modify spelling mistake + @endverbatim + ******************************************************************************* + * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by HDSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "hc32_ddl.h" + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/* SPI unit and clock definition */ +#define SPI_UNIT (M4_SPI1) +#define SPI_UNIT_CLOCK (PWC_FCG1_SPI1) + +/* SPI port definition for master */ +#define SPI_NSS_PORT (GPIO_PORT_C) +#define SPI_NSS_PIN (GPIO_PIN_07) + +#define SPI_SCK_PORT (GPIO_PORT_C) +#define SPI_SCK_PIN (GPIO_PIN_06) +#define SPI_SCK_FUNC (GPIO_FUNC_40_SPI1_SCK) + +#define SPI_MOSI_PORT (GPIO_PORT_D) +#define SPI_MOSI_PIN (GPIO_PIN_08) +#define SPI_MOSI_FUNC (GPIO_FUNC_41_SPI1_MOSI) + +#define SPI_MISO_PORT (GPIO_PORT_D) +#define SPI_MISO_PIN (GPIO_PIN_09) +#define SPI_MISO_FUNC (GPIO_FUNC_42_SPI1_MISO) + +/* NSS pin control */ +#define SPI_NSS_HIGH() (GPIO_SetPins(SPI_NSS_PORT, SPI_NSS_PIN)) +#define SPI_NSS_LOW() (GPIO_ResetPins(SPI_NSS_PORT, SPI_NSS_PIN)) + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +int hc32_spi_init(void); +void hc32_spiflash_test(void); + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spiflash.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spiflash.c new file mode 100755 index 000000000..503ce4603 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_spiflash.c @@ -0,0 +1,350 @@ +/** + ******************************************************************************* + * @file arch/arm/src/hc32/hc32_spiflash.c + * @brief SPI write read flash API for the Device Driver Library. + @verbatim + Change Logs: + Date Author Notes + 2020-06-12 Wangmin First version + 2020-10-13 Wangmin Modify spelling mistake + @endverbatim + ******************************************************************************* + * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by HDSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "hc32_ddl.h" +#include "hc32_spi.h" +#include "hc32_uart.h" + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ + +/* FLASH parameters */ +#define FLASH_PAGE_SIZE (0x100U) +#define FLASH_SECTOR_SIZE (0x1000U) +#define FLASH_MAX_ADDR (0x800000UL) +#define FLASH_DUMMY_BYTE_VALUE (0xffU) +#define FLASH_BUSY_BIT_MASK (0x01U) + +/* FLASH instruction */ +#define FLASH_INSTR_WRITE_ENABLE (0x06U) +#define FLASH_INSTR_PAGE_PROGRAM (0x02U) +#define FLASH_INSTR_STANDARD_READ (0x03U) +#define FLASH_INSTR_ERASE_4KB_SECTOR (0x20U) +#define FLASH_INSTR_READ_SR1 (0x05U) +#define FLASH_READ_MANUFACTURER_ID (0x90U) + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ + +/** + * @brief SPI flash write byte function + * + * @param [in] u8Data SPI write data to flash + * + * @retval uint8_t SPI receive data from flash + */ +static uint8_t SpiFlash_WriteReadByte(uint8_t u8Data) +{ + uint8_t u8Byte; + + /* Wait tx buffer empty */ + while (Reset == SPI_GetStatus(SPI_UNIT, SPI_FLAG_TX_BUFFER_EMPTY)) + { + } + /* Send data */ + SPI_WriteDataReg(SPI_UNIT, (uint32_t)u8Data); + + /* Wait rx buffer full */ + while (Reset == SPI_GetStatus(SPI_UNIT, SPI_FLAG_RX_BUFFER_FULL)) + { + } + /* Receive data */ + u8Byte = (uint8_t)SPI_ReadDataReg(SPI_UNIT); + + return u8Byte; +} + +/** + * @brief SPI flash write enable function + * + * @param [in] None + * + * @retval None + */ +static void SpiFlash_WriteEnable(void) +{ + SPI_NSS_LOW(); + (void)SpiFlash_WriteReadByte(FLASH_INSTR_WRITE_ENABLE); + SPI_NSS_HIGH(); +} + +/** + * @brief SPI flash wait for write operation end function + * + * @param [in] None + * + * @retval Ok Flash internal operation finish + * @retval ErrorTimeout Flash internal operation timeout + */ +static en_result_t SpiFlash_WaitForWriteEnd(void) +{ + en_result_t enRet = Ok; + uint8_t u8Status; + uint32_t u32Timeout; + stc_clk_freq_t stcClkFreq; + + (void)CLK_GetClockFreq(&stcClkFreq); + u32Timeout = stcClkFreq.sysclkFreq / 1000U; + SPI_NSS_LOW(); + (void)SpiFlash_WriteReadByte(FLASH_INSTR_READ_SR1); + do + { + u8Status = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE); + u32Timeout--; + } while ((u32Timeout != 0UL) && + ((u8Status & FLASH_BUSY_BIT_MASK) == FLASH_BUSY_BIT_MASK)); + + if (FLASH_BUSY_BIT_MASK == u8Status) + { + enRet = ErrorTimeout; + } + SPI_NSS_HIGH(); + + return enRet; +} + +/** + * @brief SPI flash page write program function + * + * @param [in] u32Addr Valid flash address + * @param [in] pData Pointer to send data buffer + * @param [in] len Send data length + * + * @retval Error Page write program failed + * @retval Ok Page write program success + */ +static en_result_t SpiFlash_WritePage(uint32_t u32Addr, const uint8_t pData[], uint16_t len) +{ + en_result_t enRet; + uint16_t u16Index = 0U; + + if ((u32Addr > FLASH_MAX_ADDR) || (NULL == pData) || (len > FLASH_PAGE_SIZE)) + { + enRet = Error; + } + else + { + SpiFlash_WriteEnable(); + /* Send data to flash */ + SPI_NSS_LOW(); + (void)SpiFlash_WriteReadByte(FLASH_INSTR_PAGE_PROGRAM); + (void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U)); + (void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U)); + (void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU)); + while (0U != (len--)) + { + (void)SpiFlash_WriteReadByte(pData[u16Index]); + u16Index++; + } + SPI_NSS_HIGH(); + /* Wait for flash idle */ + enRet = SpiFlash_WaitForWriteEnd(); + } + + return enRet; +} + +/** + * @brief SPI flash read data function + * + * @param [in] u32Addr Valid flash address + * @param [out] pData Pointer to receive data buffer + * + * @param [in] len Read data length + * + * @retval Error Read data program failed + * @retval Ok Read data program success + */ +static en_result_t SpiFlash_ReadData(uint32_t u32Addr, uint8_t pData[], uint16_t len) +{ + en_result_t enRet = Ok; + uint16_t u16Index = 0U; + + if ((u32Addr > FLASH_MAX_ADDR) || (NULL == pData)) + { + enRet = Error; + } + else + { + SpiFlash_WriteEnable(); + /* Send data to flash */ + SPI_NSS_LOW(); + (void)SpiFlash_WriteReadByte(FLASH_INSTR_STANDARD_READ); + (void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U)); + (void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U)); + (void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU)); + while (0U != (len--)) + { + pData[u16Index] = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE); + u16Index++; + } + SPI_NSS_HIGH(); + } + + return enRet; +} + +/** + * @brief SPI flash read ID for test + * + * @param [in] None + * + * @retval uint8_t Flash ID + */ +static uint8_t SpiFlash_ReadID(void) +{ + uint8_t u8IdRead; + SPI_NSS_LOW(); + (void)SpiFlash_WriteReadByte(FLASH_READ_MANUFACTURER_ID); + (void)SpiFlash_WriteReadByte((uint8_t)0x00U); + (void)SpiFlash_WriteReadByte((uint8_t)0x00U); + (void)SpiFlash_WriteReadByte((uint8_t)0x00U); + u8IdRead = SpiFlash_WriteReadByte(FLASH_DUMMY_BYTE_VALUE); + SPI_NSS_HIGH(); + return u8IdRead; +} + +/** + * @brief SPI flash erase 4Kb sector function + * + * @param [in] u32Addr Valid flash address + * + * @retval Error Sector erase failed + * @retval Ok Sector erase success + */ +static en_result_t SpiFlash_Erase4KbSector(uint32_t u32Addr) +{ + en_result_t enRet; + + if (u32Addr >= FLASH_MAX_ADDR) + { + enRet = Error; + } + else + { + SpiFlash_WriteEnable(); + /* Send instruction to flash */ + SPI_NSS_LOW(); + (void)SpiFlash_WriteReadByte(FLASH_INSTR_ERASE_4KB_SECTOR); + (void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF0000UL) >> 16U)); + (void)SpiFlash_WriteReadByte((uint8_t)((u32Addr & 0xFF00U) >> 8U)); + (void)SpiFlash_WriteReadByte((uint8_t)(u32Addr & 0xFFU)); + //SPI_GetStatus(const M4_SPI_TypeDef *SPIx, uint32_t u32Flag) //todo + SPI_NSS_HIGH(); + /* Wait for flash idle */ + enRet = SpiFlash_WaitForWriteEnd(); + } + + return enRet; +} + + +/** + * @brief Main function of spi_master_base project + * @param None + * @retval int32_t return value, if needed + */ + +void hc32_spiflash_test(void) +{ + uint32_t flashAddr = 0UL; + uint16_t bufferLen; + char txBuffer[] = "SPI read and write flash example: Welcome to use HDSC micro chip"; + char rxBuffer[128]; + uint8_t flash_id = 0; + + hc32_spi_init(); + + /* Get tx buffer length */ + bufferLen = (uint16_t)sizeof(txBuffer); + + flash_id = SpiFlash_ReadID(); + hc32_print("SPI Flash id: %#x\n", flash_id); + + (void)memset(rxBuffer, 0L, sizeof(rxBuffer)); + /* Erase sector */ + (void)SpiFlash_Erase4KbSector(flashAddr); + /* Write data to flash */ + (void)SpiFlash_WritePage(flashAddr, (uint8_t*)&txBuffer[0], bufferLen); + /* Read data from flash */ + (void)SpiFlash_ReadData(flashAddr, (uint8_t*)&rxBuffer[0], bufferLen); + + /* Compare txBuffer and rxBuffer */ + if (memcmp(txBuffer, rxBuffer, (uint32_t)bufferLen) != 0) + { + hc32_print("spi failed!!!\n"); + } + else + { + hc32_print("spi ok!!!\n"); + } + + /* Flash address offset */ + flashAddr += FLASH_SECTOR_SIZE; + if (flashAddr >= FLASH_MAX_ADDR) + { + flashAddr = 0U; + } +} + +int hc32_spidev_initialized = 1; + +void hc32_spidev_initialize(void) +{ + hc32_spi_init(); + hc32_spidev_initialized = 0; +} + + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ + diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_uart.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_uart.h index 29d8162b2..8718f437e 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_uart.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_uart.h @@ -27,7 +27,6 @@ #include #include - #include "chip.h" #define CONSOLE_UART 6 @@ -43,9 +42,35 @@ * Pre-processor Definitions ****************************************************************************/ -/* Make sure that we have not enabled more U[S]ARTs than are supported by the - * device. +typedef enum en_uart_state +{ + UART_STATE_IDLE = 0U, /*!< No data */ + UART_STATE_RXEND = 1U, /*!< UART RX End */ +} uart_state_t; + +/** + * @brief Ring buffer structure definition */ +typedef struct +{ + uint16_t u16Capacity; + volatile uint16_t u16UsedSize; + uint16_t u16InIdx; + uint16_t u16OutIdx; + uint8_t au8Buf[50]; +} uart_ring_buffer_t; + + +/* UART multiple processor ID definition */ +#define UART_MASTER_STATION_ID (0x20U) +#define UART_SLAVE_STATION_ID (0x21U) + +/* Ring buffer size */ +#define IS_RING_BUFFER_EMPTY(x) (0U == ((x)->u16UsedSize)) + +/* Multi-processor silence mode */ +#define DBG_UART_NORMAL_MODE (0U) +#define DBG_UART_SILENCE_MODE (1U) /**************************************************************************** * Public Types @@ -80,7 +105,9 @@ extern "C" FAR uart_dev_t *hc32_serial_get_uart(int uart_num); -void hc32_print(const char *fmt, ...); +int hc32_print(const char *fmt, ...); + +void hc32_console_handle(char *buf); #undef EXTERN #if defined(__cplusplus) diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_vectors.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_vectors.c new file mode 100755 index 000000000..d0c264e17 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32_vectors.c @@ -0,0 +1,266 @@ +/**************************************************************************** + * arch/arm/src/armv7-m/arm_vectors.c + * + * Copyright (C) 2012 Michael Smith. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include "chip.h" +#include "arm_internal.h" +#include "hc32f4a0_interrupts.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define IDLE_STACK ((unsigned)&_ebss+CONFIG_IDLETHREAD_STACKSIZE) + +#ifndef ARMV7M_PERIPHERAL_INTERRUPTS +# error ARMV7M_PERIPHERAL_INTERRUPTS must be defined to the number of I/O interrupts to be supported +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/* Chip-specific entrypoint */ + +extern void __start(void); + +/* Common exception entrypoint */ + +extern void exception_common(void); + +/**************************************************************************** + * Public data + ****************************************************************************/ + +/* The v7m vector table consists of an array of function pointers, with the + * first slot (vector zero) used to hold the initial stack pointer. + * + * As all exceptions (interrupts) are routed via exception_common, we just + * need to fill this array with pointers to it. + * + * Note that the [ ... ] designated initializer is a GCC extension. + */ + +#if 0 +unsigned _vectors[] locate_data(".vectors") = +{ + /* Initial stack */ + + IDLE_STACK, + + /* Reset exception handler */ + + (unsigned)&__start, + + /* Vectors 2 - n point directly at the generic handler */ + + [2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common +}; +#else +unsigned _vectors[] locate_data(".vectors") = +{ + /* Initial stack */ + + IDLE_STACK, + + /* Reset exception handler */ + + (unsigned)&__start, + (unsigned)&NMI_Handler, + (unsigned)&HardFault_Handler, + (unsigned)&MemManage_Handler, + (unsigned)&BusFault_Handler, + (unsigned)&UsageFault_Handler, + (unsigned)&exception_common, + (unsigned)&exception_common, + (unsigned)&exception_common, + (unsigned)&exception_common, + (unsigned)&SVC_Handler, /* SVC */ + (unsigned)&DebugMon_Handler, /* DebugMon */ + (unsigned)&exception_common, + (unsigned)&PendSV_Handler, + (unsigned)&SysTick_Handler, /* SysTick */ + (unsigned)&IRQ000_Handler, + (unsigned)&IRQ001_Handler, + (unsigned)&IRQ002_Handler, + (unsigned)&IRQ003_Handler, + (unsigned)&IRQ004_Handler, + (unsigned)&IRQ005_Handler, + (unsigned)&IRQ006_Handler, + (unsigned)&IRQ007_Handler, + (unsigned)&IRQ008_Handler, + (unsigned)&IRQ009_Handler, + (unsigned)&IRQ010_Handler, + (unsigned)&IRQ011_Handler, + (unsigned)&IRQ012_Handler, + (unsigned)&IRQ013_Handler, + (unsigned)&IRQ014_Handler, + (unsigned)&IRQ015_Handler, + (unsigned)&IRQ016_Handler, + (unsigned)&IRQ017_Handler, + (unsigned)&IRQ018_Handler, + (unsigned)&IRQ019_Handler, + (unsigned)&IRQ020_Handler, + (unsigned)&IRQ021_Handler, + (unsigned)&IRQ022_Handler, + (unsigned)&IRQ023_Handler, + (unsigned)&IRQ024_Handler, + (unsigned)&IRQ025_Handler, + (unsigned)&IRQ026_Handler, + (unsigned)&IRQ027_Handler, + (unsigned)&IRQ028_Handler, + (unsigned)&IRQ029_Handler, + (unsigned)&IRQ030_Handler, + (unsigned)&IRQ031_Handler, + (unsigned)&IRQ032_Handler, + (unsigned)&IRQ033_Handler, + (unsigned)&IRQ034_Handler, + (unsigned)&IRQ035_Handler, + (unsigned)&IRQ036_Handler, + (unsigned)&IRQ037_Handler, + (unsigned)&IRQ038_Handler, + (unsigned)&IRQ039_Handler, + (unsigned)&IRQ040_Handler, + (unsigned)&IRQ041_Handler, + (unsigned)&IRQ042_Handler, + (unsigned)&IRQ043_Handler, + (unsigned)&IRQ044_Handler, + (unsigned)&IRQ045_Handler, + (unsigned)&IRQ046_Handler, + (unsigned)&IRQ047_Handler, + (unsigned)&IRQ048_Handler, + (unsigned)&IRQ049_Handler, + (unsigned)&IRQ050_Handler, + (unsigned)&IRQ051_Handler, + (unsigned)&IRQ052_Handler, + (unsigned)&IRQ053_Handler, + (unsigned)&IRQ054_Handler, + (unsigned)&IRQ055_Handler, + (unsigned)&IRQ056_Handler, + (unsigned)&IRQ057_Handler, + (unsigned)&IRQ058_Handler, + (unsigned)&IRQ059_Handler, + (unsigned)&IRQ060_Handler, + (unsigned)&IRQ061_Handler, + (unsigned)&IRQ062_Handler, + (unsigned)&IRQ063_Handler, + (unsigned)&IRQ064_Handler, + (unsigned)&IRQ065_Handler, + (unsigned)&IRQ066_Handler, + (unsigned)&IRQ067_Handler, + (unsigned)&IRQ068_Handler, + (unsigned)&IRQ069_Handler, + (unsigned)&IRQ070_Handler, + (unsigned)&IRQ071_Handler, + (unsigned)&IRQ072_Handler, + (unsigned)&IRQ073_Handler, + (unsigned)&IRQ074_Handler, + (unsigned)&IRQ075_Handler, + (unsigned)&IRQ076_Handler, + (unsigned)&IRQ077_Handler, + (unsigned)&IRQ078_Handler, + (unsigned)&IRQ079_Handler, + (unsigned)&IRQ080_Handler, + (unsigned)&IRQ081_Handler, + (unsigned)&IRQ082_Handler, + (unsigned)&IRQ083_Handler, + (unsigned)&IRQ084_Handler, + (unsigned)&IRQ085_Handler, + (unsigned)&IRQ086_Handler, + (unsigned)&IRQ087_Handler, + (unsigned)&IRQ088_Handler, + (unsigned)&IRQ089_Handler, + (unsigned)&IRQ090_Handler, + (unsigned)&IRQ091_Handler, + (unsigned)&IRQ092_Handler, + (unsigned)&IRQ093_Handler, + (unsigned)&IRQ094_Handler, + (unsigned)&IRQ095_Handler, + (unsigned)&IRQ096_Handler, + (unsigned)&IRQ097_Handler, + (unsigned)&IRQ098_Handler, + (unsigned)&IRQ099_Handler, + (unsigned)&IRQ100_Handler, + (unsigned)&IRQ101_Handler, + (unsigned)&IRQ102_Handler, + (unsigned)&IRQ103_Handler, + (unsigned)&IRQ104_Handler, + (unsigned)&IRQ105_Handler, + (unsigned)&IRQ106_Handler, + (unsigned)&IRQ107_Handler, + (unsigned)&IRQ108_Handler, + (unsigned)&IRQ109_Handler, + (unsigned)&IRQ110_Handler, + (unsigned)&IRQ111_Handler, + (unsigned)&IRQ112_Handler, + (unsigned)&IRQ113_Handler, + (unsigned)&IRQ114_Handler, + (unsigned)&IRQ115_Handler, + (unsigned)&IRQ116_Handler, + (unsigned)&IRQ117_Handler, + (unsigned)&IRQ118_Handler, + (unsigned)&IRQ119_Handler, + (unsigned)&IRQ120_Handler, + (unsigned)&IRQ121_Handler, + (unsigned)&IRQ122_Handler, + (unsigned)&IRQ123_Handler, + (unsigned)&IRQ124_Handler, + (unsigned)&IRQ125_Handler, + (unsigned)&IRQ126_Handler, + (unsigned)&IRQ127_Handler, + (unsigned)&IRQ128_Handler, + (unsigned)&IRQ129_Handler, + (unsigned)&IRQ130_Handler, + (unsigned)&IRQ131_Handler, + (unsigned)&IRQ132_Handler, + (unsigned)&IRQ133_Handler, + (unsigned)&IRQ134_Handler, + (unsigned)&IRQ135_Handler, + (unsigned)&IRQ136_Handler, + (unsigned)&IRQ137_Handler, + (unsigned)&IRQ138_Handler, + (unsigned)&IRQ139_Handler, + (unsigned)&IRQ140_Handler, + (unsigned)&IRQ141_Handler, + (unsigned)&IRQ142_Handler, + (unsigned)&IRQ143_Handler + +// [2 ... (15 + ARMV7M_PERIPHERAL_INTERRUPTS)] = (unsigned)&exception_common +}; +#endif diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_gpio.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_gpio.h index 7dab7070e..a4a7ec06a 100755 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_gpio.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_gpio.h @@ -137,6 +137,8 @@ typedef struct #define GPIO_PORT_SHIFT 16 #define GPIO_PINSET(_port, _pin) ((uint32_t)(_port << GPIO_PORT_SHIFT) | _pin) +#define GPIO_PIN(_pinset) ((_pinset >> GPIO_PIN_SHIFT) & GPIO_PIN_MASK) +#define GPIO_PORT(_pinset) ((_pinset >> GPIO_PORT_SHIFT) & GPIO_PORT_MASK) /** * @} diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_spi.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_spi.c new file mode 100755 index 000000000..c75068dff --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_spi.c @@ -0,0 +1,1095 @@ +/** + ******************************************************************************* + * @file hc32f4a0_spi.c + * @brief This file provides firmware functions to manage the Serial Peripheral + * Interface(SPI). + @verbatim + Change Logs: + Date Author Notes + 2020-06-12 Wangmin First version + 2020-08-31 Wangmin Modify for MISRAC2012 + 2020-10-13 Wangmin Define variable for count as __IO type + @endverbatim + ******************************************************************************* + * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by HDSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "hc32f4a0_spi.h" +#include "hc32f4a0_utility.h" + +/** + * @addtogroup HC32F4A0_DDL_Driver + * @{ + */ + +/** + * @defgroup DDL_SPI SPI + * @brief Serial Peripheral Interface Driver Library + * @{ + */ + +#if (DDL_SPI_ENABLE == DDL_ON) + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ +/** + * @defgroup SPI_Local_Macros SPI Local Macros + * @{ + */ + +#define SPI_CFG1_DEFAULT (0x00000010UL) +#define SPI_CFG2_DEFAULT (0x00000F1DUL) +#define SPI_SR_DEFAULT (0x00000020UL) + +#define SPI_IRQ_MASK ( SPI_INT_ERROR | \ + SPI_INT_TX_BUFFER_EMPTY | \ + SPI_INT_RX_BUFFER_FULL | \ + SPI_INT_IDLE ) +#define SPI_GET_STD_MASK ( SPI_FLAG_OVERLOAD | \ + SPI_FLAG_IDLE | \ + SPI_FLAG_MODE_FAULT | \ + SPI_FLAG_PARITY_ERROR | \ + SPI_FLAG_UNDERLOAD | \ + SPI_FLAG_TX_BUFFER_EMPTY | \ + SPI_FLAG_RX_BUFFER_FULL ) +#define SPI_CLR_STD_MASK ( SPI_FLAG_OVERLOAD | \ + SPI_FLAG_MODE_FAULT | \ + SPI_FLAG_PARITY_ERROR | \ + SPI_FLAG_UNDERLOAD ) + +#define SPI_SS0_VALID_CFG (0UL) +#define SPI_SS1_VALID_CFG (SPI_CFG2_SSA_0) +#define SPI_SS2_VALID_CFG (SPI_CFG2_SSA_1) +#define SPI_SS3_VALID_CFG (SPI_CFG2_SSA_0 | SPI_CFG2_SSA_1) + +/** + * @defgroup SPI_Check_Parameters_Validity SPI check parameters validity + * @{ + */ + +/*! Parameter valid check for SPI peripheral */ +#define IS_VALID_SPI_UNIT(x) \ +( (M4_SPI1 == (x)) || \ + (M4_SPI2 == (x)) || \ + (M4_SPI3 == (x)) || \ + (M4_SPI4 == (x)) || \ + (M4_SPI5 == (x)) || \ + (M4_SPI6 == (x))) + +/*! Parameter valid check for SPI wire mode */ +#define IS_SPI_WIRE_MODE(x) \ +( ((x) == SPI_WIRE_4) || \ + ((x) == SPI_WIRE_3)) + +/*! Parameter valid check for SPI transfer mode */ +#define IS_SPI_TRANS_MODE(x) \ +( ((x) == SPI_FULL_DUPLEX) || \ + ((x) == SPI_SEND_ONLY)) + +/*! Parameter valid check for SPI master slave mode */ +#define IS_SPI_MASTER_SLAVE(x) \ +( ((x) == SPI_SLAVE) || \ + ((x) == SPI_MASTER)) + +/*! Parameter valid check for SPI loopback mode */ +#define IS_SPI_SPLPBK(x) \ +( ((x) == SPI_SPLPBK_INVALID) || \ + ((x) == SPI_SPLPBK_MOSI_INVERT) || \ + ((x) == SPI_SPLPBK_MOSI)) + +/*! Parameter valid check for SPI communication suspend function status */ +#define IS_SPI_SUSP_MODE_STD(x) \ +( ((x) == SPI_COM_SUSP_FUNC_OFF) || \ + ((x) == SPI_COM_SUSP_FUNC_ON)) + +/*! Parameter valid check for SPI fault dectet function status */ +#define IS_SPI_MODFE_CMD(x) \ +( ((x) == SPI_MODFE_DISABLE) || \ + ((x) == SPI_MODFE_ENABLE)) + +/*! Parameter valid check for SPI parity check mode */ +#define IS_SPI_PARITY_CHECK(x) \ +( ((x) == SPI_PARITY_INVALID) || \ + ((x) == SPI_PARITY_EVEN) || \ + ((x) == SPI_PARITY_ODD)) + +/*! Parameter valid check for SPI interval time delay */ +#define IS_SPI_INTERVAL_DELAY(x) \ +( ((x) == SPI_INTERVAL_TIME_1SCK_2PCLK1) || \ + ((x) == SPI_INTERVAL_TIME_2SCK_2PCLK1) || \ + ((x) == SPI_INTERVAL_TIME_3SCK_2PCLK1) || \ + ((x) == SPI_INTERVAL_TIME_4SCK_2PCLK1) || \ + ((x) == SPI_INTERVAL_TIME_5SCK_2PCLK1) || \ + ((x) == SPI_INTERVAL_TIME_6SCK_2PCLK1) || \ + ((x) == SPI_INTERVAL_TIME_7SCK_2PCLK1) || \ + ((x) == SPI_INTERVAL_TIME_8SCK_2PCLK1)) + +/*! Parameter valid check for SPI release time delay */ +#define IS_SPI_RELEASE_DELAY(x) \ +( ((x) == SPI_RELEASE_TIME_1SCK) || \ + ((x) == SPI_RELEASE_TIME_2SCK) || \ + ((x) == SPI_RELEASE_TIME_3SCK) || \ + ((x) == SPI_RELEASE_TIME_4SCK) || \ + ((x) == SPI_RELEASE_TIME_5SCK) || \ + ((x) == SPI_RELEASE_TIME_6SCK) || \ + ((x) == SPI_RELEASE_TIME_7SCK) || \ + ((x) == SPI_RELEASE_TIME_8SCK)) + +/*! Parameter valid check for SPI Setup time delay delay */ +#define IS_SPI_SETUP_DELAY(x) \ +( ((x) == SPI_SETUP_TIME_1SCK) || \ + ((x) == SPI_SETUP_TIME_2SCK) || \ + ((x) == SPI_SETUP_TIME_3SCK) || \ + ((x) == SPI_SETUP_TIME_4SCK) || \ + ((x) == SPI_SETUP_TIME_5SCK) || \ + ((x) == SPI_SETUP_TIME_6SCK) || \ + ((x) == SPI_SETUP_TIME_7SCK) || \ + ((x) == SPI_SETUP_TIME_8SCK)) + +/*! Parameter valid check for SPI SS active level */ +#define IS_SPI_SS_ACTIVE_LEVEL(x) \ +( ((x) == SPI_SS_ACTIVE_LOW) || \ + ((x) == SPI_SS_ACTIVE_HIGH)) + +/*! Parameter valid check for SPI read data register target buffer */ +#define IS_SPI_RD_TARGET_BUFF(x) \ +( ((x) == SPI_RD_TARGET_RD_BUF) || \ + ((x) == SPI_RD_TARGET_WR_BUF)) + +/*! Parameter valid check for SPI mode */ +#define IS_SPI_SPI_MODE(x) \ +( ((x) == SPI_MODE_0) || \ + ((x) == SPI_MODE_1) || \ + ((x) == SPI_MODE_2) || \ + ((x) == SPI_MODE_3)) + +/*! Parameter valid check for SPI SS signal */ +#define IS_SPI_SS_PIN(x) \ +( ((x) == SPI_PIN_SS0) || \ + ((x) == SPI_PIN_SS1) || \ + ((x) == SPI_PIN_SS2) || \ + ((x) == SPI_PIN_SS3)) + +/*! Parameter valid check for SPI baudrate prescaler */ +#define IS_SPI_BIT_RATE_DIV(x) \ +( ((x) == SPI_BR_PCLK1_DIV2) || \ + ((x) == SPI_BR_PCLK1_DIV4) || \ + ((x) == SPI_BR_PCLK1_DIV8) || \ + ((x) == SPI_BR_PCLK1_DIV16) || \ + ((x) == SPI_BR_PCLK1_DIV32) || \ + ((x) == SPI_BR_PCLK1_DIV64) || \ + ((x) == SPI_BR_PCLK1_DIV128) || \ + ((x) == SPI_BR_PCLK1_DIV256)) + +/*! Parameter valid check for SPI data bits */ +#define IS_SPI_DATA_SIZE(x) \ +( ((x) == SPI_DATA_SIZE_4BIT) || \ + ((x) == SPI_DATA_SIZE_5BIT) || \ + ((x) == SPI_DATA_SIZE_6BIT) || \ + ((x) == SPI_DATA_SIZE_7BIT) || \ + ((x) == SPI_DATA_SIZE_8BIT) || \ + ((x) == SPI_DATA_SIZE_9BIT) || \ + ((x) == SPI_DATA_SIZE_10BIT) || \ + ((x) == SPI_DATA_SIZE_11BIT) || \ + ((x) == SPI_DATA_SIZE_12BIT) || \ + ((x) == SPI_DATA_SIZE_13BIT) || \ + ((x) == SPI_DATA_SIZE_14BIT) || \ + ((x) == SPI_DATA_SIZE_15BIT) || \ + ((x) == SPI_DATA_SIZE_16BIT) || \ + ((x) == SPI_DATA_SIZE_20BIT) || \ + ((x) == SPI_DATA_SIZE_24BIT) || \ + ((x) == SPI_DATA_SIZE_32BIT)) + +/*! Parameter valid check for SPI data frame level */ +#define IS_SPI_DATA_FRAME(x) \ +( ((x) == SPI_FRAME_1) || \ + ((x) == SPI_FRAME_2) || \ + ((x) == SPI_FRAME_3) || \ + ((x) == SPI_FRAME_4)) + +/*! Parameter valid check for SPI LSB MSB mode */ +#define IS_SPI_FIRST_BIT(x) \ +( ((x) == SPI_FIRST_MSB) || \ + ((x) == SPI_FIRST_LSB)) + +/*! Parameter valid check for interrupt flag */ +#define IS_SPI_IRQ_FLAG(x) \ +( ((x) != 0UL) && \ + (((x) | SPI_IRQ_MASK) == SPI_IRQ_MASK)) + +/*! Parameter valid check for SPI status flag */ +#define IS_SPI_STD_FLAG(x) \ +( ((x) != 0UL) && \ + (((x) | SPI_GET_STD_MASK) == SPI_GET_STD_MASK)) + +/*! Parameter valid check for SPI status flag for clear */ +#define IS_SPI_CLR_STD_FLAG(x) \ +( ((x) != 0UL) && \ + (((x) | SPI_CLR_STD_MASK) == SPI_CLR_STD_MASK)) + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ +/** + * @defgroup SPI_Local_Functions SPI Local Functions + * @{ + */ + +static en_result_t SPI_TxRx(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, void *pvRxBuf, uint32_t u32Length); +static en_result_t SPI_Tx(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, uint32_t u32Length); + +/** + * @} + */ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ + + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @defgroup SPI_Global_Functions SPI Global Functions + * @{ + */ + +/** + * @brief Initializes the SPI peripheral according to the specified parameters + * in the structure stc_spi_init. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] pstcInit Pointer to a stc_spi_init_t structure that contains + * the configuration information for the SPI. + * @retval An en_result_t enumeration value: + * @arg Ok: No errors occurred + * @arg ErrorInvalidParameter: pstcInit == NULL or configuration parameter error. + */ +en_result_t SPI_Init(M4_SPI_TypeDef *SPIx, const stc_spi_init_t *pstcInit) +{ + en_result_t enRet = ErrorInvalidParameter; + + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + + if (NULL != pstcInit) + { + DDL_ASSERT(IS_SPI_WIRE_MODE(pstcInit->u32WireMode)); + DDL_ASSERT(IS_SPI_TRANS_MODE(pstcInit->u32TransMode)); + DDL_ASSERT(IS_SPI_MASTER_SLAVE(pstcInit->u32MasterSlave)); + DDL_ASSERT(IS_SPI_SUSP_MODE_STD(pstcInit->u32SuspMode)); + DDL_ASSERT(IS_SPI_MODFE_CMD(pstcInit->u32Modfe)); + DDL_ASSERT(IS_SPI_PARITY_CHECK(pstcInit->u32Parity)); + DDL_ASSERT(IS_SPI_SPI_MODE(pstcInit->u32SpiMode)); + DDL_ASSERT(IS_SPI_BIT_RATE_DIV(pstcInit->u32BaudRatePrescaler)); + DDL_ASSERT(IS_SPI_DATA_SIZE(pstcInit->u32DataBits)); + DDL_ASSERT(IS_SPI_FIRST_BIT(pstcInit->u32FirstBit)); + DDL_ASSERT(IS_SPI_DATA_FRAME(pstcInit->u32FrameLevel)); + + /* Configuration parameter check */ + if((SPI_MASTER == pstcInit->u32MasterSlave)&&(SPI_MODFE_ENABLE == pstcInit->u32Modfe)) + { + /* pstcInit->u32Modfe can not be SPI_MODFE_ENABLE in master mode */ + } + else if((SPI_WIRE_3 == pstcInit->u32WireMode) + && (SPI_SLAVE == pstcInit->u32MasterSlave) + &&((SPI_MODE_0 == pstcInit->u32SpiMode)||(SPI_MODE_2 == pstcInit->u32SpiMode))) + { + /* SPI_WIRE_3 can not support SPI_MODE_0 and SPI_MODE_2 */ + } + else + { + WRITE_REG32(SPIx->_CR1, pstcInit->u32WireMode + | pstcInit->u32TransMode + | pstcInit->u32MasterSlave + | pstcInit->u32SuspMode + | pstcInit->u32Modfe + | pstcInit->u32Parity ); + + MODIFY_REG32(SPIx->CFG1, SPI_CFG1_FTHLV, pstcInit->u32FrameLevel); + + WRITE_REG32(SPIx->CFG2, pstcInit->u32SpiMode + | pstcInit->u32BaudRatePrescaler + | pstcInit->u32DataBits + | pstcInit->u32FirstBit); + + enRet = Ok; + } + } + return enRet; +} + +/** + * @brief De-initializes the SPI peripheral. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @retval None + */ +void SPI_DeInit(M4_SPI_TypeDef *SPIx) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + + SPI_FunctionCmd(SPIx, Disable); + + WRITE_REG32(SPIx->_CR1, 0x00000000UL); + WRITE_REG32(SPIx->CFG1, SPI_CFG1_DEFAULT); + WRITE_REG32(SPIx->CFG2, SPI_CFG2_DEFAULT); + WRITE_REG32(SPIx->SR, SPI_SR_DEFAULT); +} + +/** + * @brief Set a default value for the SPI initialization structure. + * @param [in] pstcInit Pointer to a stc_spi_init_t structure that + * contains configuration information. + * @retval An en_result_t enumeration value. + * @arg Ok: No errors occurred. + * @arg ErrorInvalidParameter: pstcInit == NULL. + */ +en_result_t SPI_StructInit(stc_spi_init_t *pstcInit) +{ + en_result_t enRet = ErrorInvalidParameter; + + if (NULL != pstcInit) + { + pstcInit->u32WireMode = SPI_WIRE_4; + pstcInit->u32TransMode = SPI_FULL_DUPLEX; + pstcInit->u32MasterSlave = SPI_MASTER; + pstcInit->u32SuspMode = SPI_COM_SUSP_FUNC_OFF; + pstcInit->u32Modfe = SPI_MODFE_DISABLE; + pstcInit->u32Parity = SPI_PARITY_INVALID; + pstcInit->u32SpiMode = SPI_MODE_0; + pstcInit->u32BaudRatePrescaler = SPI_BR_PCLK1_DIV8; + pstcInit->u32DataBits = SPI_DATA_SIZE_8BIT; + pstcInit->u32FirstBit = SPI_FIRST_MSB; + pstcInit->u32FrameLevel = SPI_FRAME_1; + + enRet = Ok; + } + return enRet; +} + +/** + * @brief Enable or disable SPI interrupt. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32IntType SPI interrupt type. Can be one or any + * combination of the parameter @ref SPI_Interrupt_Type_Define + * @arg SPI_INT_ERROR + * @arg SPI_INT_TX_BUFFER_EMPTY + * @arg SPI_INT_RX_BUFFER_FULL + * @arg SPI_INT_IDLE + * @param [in] enNewState An en_functional_state_t enumeration value. + * @arg Enable: Enable the specified interrupt of SPI. + * @arg Disable: Disable the specified interrupt of SPI. + * @retval None + */ +void SPI_IntCmd(M4_SPI_TypeDef *SPIx, uint32_t u32IntType, en_functional_state_t enNewState) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState)); + DDL_ASSERT(IS_SPI_IRQ_FLAG(u32IntType)); + + if (enNewState == Enable) + { + SET_REG32_BIT(SPIx->_CR1, u32IntType); + } + else + { + CLEAR_REG32_BIT(SPIx->_CR1, u32IntType); + } +} + +/** + * @brief SPI function enable or disable. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] enNewState An en_functional_state_t enumeration value. + * @arg Enable: Enable SPI function. + * @arg Disable: Disable SPI function. + * @retval None + */ +void SPI_FunctionCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState)); + + if(Enable == enNewState) + { + SET_REG32_BIT(SPIx->_CR1, SPI_CR1_SPE); + } + else + { + CLEAR_REG32_BIT(SPIx->_CR1, SPI_CR1_SPE); + } +} + +/** + * @brief Write SPI data register. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32Data The data will be written to the data register. + * @retval None. + */ +void SPI_WriteDataReg(M4_SPI_TypeDef *SPIx, uint32_t u32Data) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + WRITE_REG32(SPIx->DR, u32Data); +} + +/** + * @brief Read SPI data register. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @retval A 32-bit data of SPI data register. + */ +uint32_t SPI_ReadDataReg(const M4_SPI_TypeDef *SPIx) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + + return READ_REG32(SPIx->DR); +} + + +/** + * @brief SPI get status flag. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32Flag SPI state flag. Can be one or any + * combination of the parameter of @ref SPI_State_Flag_Define + * @arg SPI_FLAG_OVERLOAD + * @arg SPI_FLAG_IDLE + * @arg SPI_FLAG_MODE_FAULT + * @arg SPI_FLAG_PARITY_ERROR + * @arg SPI_FLAG_UNDERLOAD + * @arg SPI_FLAG_TX_BUFFER_EMPTY + * @arg SPI_FLAG_RX_BUFFER_FULL + * @retval An en_flag_status_t enumeration. + * @arg Set: The specified flag has set. + * @arg Reset: The specified flag has not set. + */ +en_flag_status_t SPI_GetStatus(const M4_SPI_TypeDef *SPIx, uint32_t u32Flag) +{ + en_flag_status_t enFlag = Reset; + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_SPI_STD_FLAG(u32Flag)); + + if(0U != READ_REG32_BIT(SPIx->SR, u32Flag)) + { + enFlag = Set; + } + + return enFlag; +} + +/** + * @brief SPI clear state flag. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32Flag SPI state flag. + * Can be one or any combination of the parameter below + * @arg SPI_FLAG_OVERLOAD + * @arg SPI_FLAG_MODE_FAULT + * @arg SPI_FLAG_PARITY_ERROR + * @arg SPI_FLAG_UNDERLOAD + * @retval None + */ +void SPI_ClearFlag(M4_SPI_TypeDef *SPIx, uint32_t u32Flag) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_SPI_CLR_STD_FLAG(u32Flag)); + + CLEAR_REG32_BIT(SPIx->SR, u32Flag); +} + +/** + * @brief SPI loopback function configuration. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32Mode Loopback mode. + * Can be one parameter @ref SPI_Loopback_Selection_Define + * @arg SPI_SPLPBK_INVALID + * @arg SPI_SPLPBK_MOSI_INVERT + * @arg SPI_SPLPBK_MOSI + * @retval None + */ +void SPI_LoopbackModeCfg(M4_SPI_TypeDef *SPIx, uint32_t u32Mode) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_SPI_SPLPBK(u32Mode)); + + MODIFY_REG32(SPIx->_CR1, SPI_CR1_SPLPBK | SPI_CR1_SPLPBK2, u32Mode); +} + +/** + * @brief SPI parity check error self diagnosis function enable or disable. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] enNewState An en_functional_state_t enumeration value. + * @arg Enable: Enable function. + * @arg Disable: Disable function. + * @retval None + */ +void SPI_PateCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState)); + + if(Enable == enNewState) + { + SET_REG32_BIT(SPIx->_CR1, SPI_CR1_PATE); + } + else + { + CLEAR_REG32_BIT(SPIx->_CR1, SPI_CR1_PATE); + } +} + +/** + * @brief SPI signals delay time configuration + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] pstcDelayCfg Pointer to a stc_spi_delay_t structure that contains + * the configuration information for the SPI delay time. + * @retval An en_result_t enumeration value: + * @arg Ok: No errors occurred + * @arg ErrorInvalidParameter: pstcDelayCfg == NULL + */ +en_result_t SPI_DelayTimeCfg(M4_SPI_TypeDef *SPIx, const stc_spi_delay_t *pstcDelayCfg) +{ + en_result_t enRet = ErrorInvalidParameter; + + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + + if (NULL != pstcDelayCfg) + { + DDL_ASSERT(IS_SPI_INTERVAL_DELAY(pstcDelayCfg->u32IntervalDelay)); + DDL_ASSERT(IS_SPI_RELEASE_DELAY(pstcDelayCfg->u32ReleaseDelay)); + DDL_ASSERT(IS_SPI_SETUP_DELAY(pstcDelayCfg->u32SetupDelay)); + + /* Interval delay */ + if(SPI_INTERVAL_TIME_1SCK_2PCLK1 == pstcDelayCfg->u32IntervalDelay) + { + CLEAR_REG32_BIT(SPIx->CFG2, SPI_CFG2_MIDIE); + CLEAR_REG32_BIT(SPIx->CFG1, SPI_CFG1_MIDI); + } + else + { + MODIFY_REG32(SPIx->CFG1, SPI_CFG1_MIDI, pstcDelayCfg->u32IntervalDelay); + SET_REG32_BIT(SPIx->CFG2, SPI_CFG2_MIDIE); + } + + /* SCK release delay */ + if(SPI_RELEASE_TIME_1SCK == pstcDelayCfg->u32ReleaseDelay) + { + CLEAR_REG32_BIT(SPIx->CFG2, SPI_CFG2_MSSDLE); + CLEAR_REG32_BIT(SPIx->CFG1, SPI_CFG1_MSSDL); + } + else + { + SET_REG32_BIT(SPIx->CFG2, SPI_CFG2_MSSDLE); + MODIFY_REG32(SPIx->CFG1, SPI_CFG1_MSSDL, pstcDelayCfg->u32ReleaseDelay); + } + + /* Setup delay */ + if(SPI_SETUP_TIME_1SCK == pstcDelayCfg->u32SetupDelay) + { + CLEAR_REG32_BIT(SPIx->CFG2, SPI_CFG2_MSSIE); + CLEAR_REG32_BIT(SPIx->CFG1, SPI_CFG1_MSSI); + } + else + { + SET_REG32_BIT(SPIx->CFG2, SPI_CFG2_MSSIE); + MODIFY_REG32(SPIx->CFG1, SPI_CFG1_MSSI, pstcDelayCfg->u32SetupDelay); + } + + enRet = Ok; + } + return enRet; +} + +/** + * @brief Set a default value for the SPI delay time configuration structure. + * @param [in] pstcDelayCfg Pointer to a stc_spi_delay_t structure that + * contains configuration information. + * @retval An en_result_t enumeration value. + * @arg Ok: No errors occurred. + * @arg ErrorInvalidParameter: pstcDelayCfg == NULL. + */ +en_result_t SPI_DelayStructInit(stc_spi_delay_t *pstcDelayCfg) +{ + en_result_t enRet = ErrorInvalidParameter; + + if (NULL != pstcDelayCfg) + { + pstcDelayCfg->u32IntervalDelay = SPI_INTERVAL_TIME_1SCK_2PCLK1; + pstcDelayCfg->u32ReleaseDelay = SPI_RELEASE_TIME_1SCK; + pstcDelayCfg->u32SetupDelay = SPI_SETUP_TIME_1SCK; + enRet = Ok; + } + return enRet; +} + +/** + * @brief SPI SS signal valid level configuration + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32SSPin Specify the SS pin @ref SPI_SS_Pin_Define + * @param [in] enNewState An en_functional_state_t enumeration value. + * @arg Enable: SS pin high level valid. + * @arg Disable: SS pin low level valid. + * @retval None + */ +void SPI_SSValidLevelCfg(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin, en_functional_state_t enNewState) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_SPI_SS_PIN(u32SSPin)); + DDL_ASSERT(IS_FUNCTIONAL_STATE(enNewState)); + + if(Enable == enNewState) + { + SET_REG32_BIT(SPIx->CFG1, u32SSPin); + } + else + { + CLEAR_REG32_BIT(SPIx->CFG1, u32SSPin); + } +} + +/** + * @brief SPI valid SS signal configuration + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32SSPin Specify the SS pin @ref SPI_SS_Pin_Define + * @retval None + */ +void SPI_SSPinSel(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin) +{ + uint32_t u32RegCfg; + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_SPI_SS_PIN(u32SSPin)); + + switch (u32SSPin) + { + case SPI_PIN_SS0: + u32RegCfg = SPI_SS0_VALID_CFG; + break; + case SPI_PIN_SS1: + u32RegCfg = SPI_SS1_VALID_CFG; + break; + case SPI_PIN_SS2: + u32RegCfg = SPI_SS2_VALID_CFG; + break; + case SPI_PIN_SS3: + u32RegCfg = SPI_SS3_VALID_CFG; + break; + + default: + u32RegCfg = SPI_SS0_VALID_CFG; + break; + } + MODIFY_REG32(SPIx->CFG2, SPI_CFG2_SSA, u32RegCfg); +} + +/** + * @brief SPI read buffer configuration + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] u32ReadBuf Target buffer for read operation @ref SPI_Read_Target_Buffer_Define + * @retval None + */ +void SPI_ReadBufCfg(M4_SPI_TypeDef *SPIx, uint32_t u32ReadBuf) +{ + DDL_ASSERT(IS_VALID_SPI_UNIT(SPIx)); + DDL_ASSERT(IS_SPI_RD_TARGET_BUFF(u32ReadBuf)); + + MODIFY_REG32(SPIx->CFG1, SPI_CFG1_SPRDTD, u32ReadBuf); +} + +/** + * @brief SPI transmit data. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] pvTxBuf The pointer to the buffer which contains the data to be sent. + * @param [in] u32TxLength The length of the data to be sent. + * @retval An en_result_t enumeration value: + * @arg Ok: No errors occurred + * @arg ErrorTimeout: SPI transmit timeout. + * @arg ErrorInvalidParameter: pvTxBuf == NULL or u32TxLength == 0U + * @note -No SS pin active and inactive operation in 3-wire mode. Add operations of SS pin depending on your application. + * -This function supports full duplex mode and send only mode. + */ +en_result_t SPI_Transmit(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, uint32_t u32TxLength) +{ + uint32_t u32Flags; + en_result_t enRet = ErrorInvalidParameter; + + if ((pvTxBuf != NULL) && (u32TxLength != 0U)) + { + u32Flags = READ_REG32_BIT(SPIx->_CR1, SPI_CR1_TXMDS); + if (u32Flags == SPI_SEND_ONLY) + { + /* Transmit data in send only mode. */ + enRet = SPI_Tx(SPIx, pvTxBuf, u32TxLength); + } + else + { + /* Transmit data in full duplex mode. */ + enRet = SPI_TxRx(SPIx, pvTxBuf, NULL, u32TxLength); + } + } + return enRet; +} + +/** + * @brief SPI receive data. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] pvRxBuf The pointer to the buffer which the received data to be stored. + * @param [in] u32RxLength The length of the data to be received. + * @retval An en_result_t enumeration value: + * @arg Ok: No errors occurred + * @arg ErrorTimeout: SPI receive timeout. + * @arg ErrorInvalidParameter: pvRxBuf == NULL or u32RxLength == 0U + * @note -No SS pin active and inactive operation in 3-wire mode. Add operations of SS pin depending on your application. + * -This function only works in full duplex master mode. + */ +en_result_t SPI_Receive(M4_SPI_TypeDef *SPIx, void *pvRxBuf, uint32_t u32RxLength) +{ + en_result_t enRet = ErrorInvalidParameter; + + if ((pvRxBuf != NULL) && (u32RxLength != 0U)) + { + /* Receives data in full duplex master mode. */ + enRet = SPI_TxRx(SPIx, NULL, pvRxBuf, u32RxLength); + } + return enRet; +} + +/** + * @brief SPI transmit and receive data. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] pvTxBuf The pointer to the buffer which contains the data to be sent. + * If this pointer is NULL and the pvRxBuf is NOT NULL, the MOSI output high + * and the the received data will be stored in the buffer pointed by pvRxBuf. + * @param [out] pvRxBuf The pointer to the buffer which the received data will be stored. + * This for full duplex transfer. + * @param [in] u32Length The length of the data(in byte or half word) to be sent and received. + * @retval An en_result_t enumeration value: + * @arg Ok: No errors occurred + * @arg ErrorTimeout: SPI transmit and receive timeout. + * @arg ErrorInvalidParameter: pvRxBuf == NULL or pvRxBuf == NULL or u32Length == 0U + * @note SPI receives data while sending data. Only works in full duplex master mode. + */ +en_result_t SPI_TransmitReceive(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, void *pvRxBuf, uint32_t u32Length) +{ + en_result_t enRet = ErrorInvalidParameter; + + if ((pvTxBuf != NULL) && (pvRxBuf != NULL) && (u32Length != 0U)) + { + /* Transmit and receive data in full duplex master mode. */ + enRet = SPI_TxRx(SPIx, pvTxBuf, pvRxBuf, u32Length); + } + return enRet; +} +/** + * @} + */ + +/** + * @addtogroup SPI_Local_Functions SPI Local Functions + * @{ + */ +/** + * @brief SPI transmit and receive data in full duplex mode. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] pvTxBuf The pointer to the buffer which contains the data to be sent. + * @param [out] pvRxBuf The pointer to the buffer which the received data will be stored. + * @param [in] u32Length The length of the data in byte or half word. + * @retval An en_result_t enumeration value: + * @arg Ok: No errors occurred + * @arg ErrorTimeout: SPI transmit and receive timeout. + */ +static en_result_t SPI_TxRx(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, void *pvRxBuf, uint32_t u32Length) +{ + uint32_t u32BitSize; + __IO uint32_t u32Timecount; + __IO uint32_t u32Count = 0U; + en_result_t enRet = Ok; + uint32_t u32Tmp; + __UNUSED __IO uint32_t u32Read; + + /* Get data bit size, SPI_DATA_SIZE_4BIT ~ SPI_DATA_SIZE_32BIT */ + u32BitSize = READ_REG32_BIT(SPIx->CFG2, SPI_CFG2_DSIZE); + + while (u32Count < u32Length) + { + if (pvTxBuf != NULL) + { + if (u32BitSize <= SPI_DATA_SIZE_8BIT) + { + /* SPI_DATA_SIZE_4BIT ~ SPI_DATA_SIZE_8BIT */ + WRITE_REG32(SPIx->DR, ((const uint8_t *)pvTxBuf)[u32Count]); + } + else if(u32BitSize <= SPI_DATA_SIZE_16BIT) + { + /* SPI_DATA_SIZE_9BIT ~ SPI_DATA_SIZE_16BIT */ + WRITE_REG32(SPIx->DR, ((const uint16_t *)pvTxBuf)[u32Count]); + } + else + { + /* SPI_DATA_SIZE_20BIT ~ SPI_DATA_SIZE_32BIT */ + WRITE_REG32(SPIx->DR, ((const uint32_t *)pvTxBuf)[u32Count]); + } + } + else + { + WRITE_REG32(SPIx->DR, 0xFFFFFFFFUL); + } + + /* Delay about 10ms */ + u32Timecount = HCLK_VALUE/100UL; + do + { + if(0UL != READ_REG32_BIT(SPIx->SR, SPI_FLAG_RX_BUFFER_FULL)) + { + break; + } + u32Timecount--; + } while (u32Timecount != 0U); + + if (u32Timecount == 0U) + { + enRet = ErrorTimeout; + break; + } + + u32Tmp = READ_REG32(SPIx->DR); + if (pvRxBuf != NULL) + { + if (u32BitSize <= SPI_DATA_SIZE_8BIT) + { + /* SPI_DATA_SIZE_4BIT ~ SPI_DATA_SIZE_8BIT */ + ((uint8_t *)pvRxBuf)[u32Count] = (uint8_t)u32Tmp; + } + else if(u32BitSize <= SPI_DATA_SIZE_16BIT) + { + /* SPI_DATA_SIZE_9BIT ~ SPI_DATA_SIZE_16BIT */ + ((uint16_t *)pvRxBuf)[u32Count] = (uint16_t)u32Tmp; + } + else + { + /* SPI_DATA_SIZE_20BIT ~ SPI_DATA_SIZE_32BIT */ + ((uint32_t *)pvRxBuf)[u32Count] = (uint32_t)u32Tmp; + } + } + else + { + /* Dummy read */ + u32Read = READ_REG32(SPIx->DR); + } + + u32Count++; + } + return enRet; +} + +/** + * @brief SPI send data only. + * @param [in] SPIx SPI unit + * @arg M4_SPI1 + * @arg M4_SPI2 + * @arg M4_SPI3 + * @arg M4_SPI4 + * @arg M4_SPI5 + * @arg M4_SPI6 + * @param [in] pvTxBuf The pointer to the buffer which contains the data to be sent. + * @param [in] u32Length The length of the data in byte or half word or word. + * @retval An en_result_t enumeration value: + * @arg Ok: No errors occurred. + * @arg ErrorTimeout: SPI transmit timeout. + */ +static en_result_t SPI_Tx(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, uint32_t u32Length) +{ + __IO uint32_t u32Count = 0U; + __IO uint32_t u32Timecount; + uint32_t u32BitSize; + en_result_t enRet = Ok; + + /* Get data bit size, SPI_DATA_SIZE_4BIT ~ SPI_DATA_SIZE_32BIT */ + u32BitSize = READ_REG32_BIT(SPIx->CFG2, SPI_CFG2_DSIZE); + + while (u32Count < u32Length) + { + if (u32BitSize <= SPI_DATA_SIZE_8BIT) + { + /* SPI_DATA_SIZE_4BIT ~ SPI_DATA_SIZE_8BIT */ + WRITE_REG32(SPIx->DR, ((const uint8_t *)pvTxBuf)[u32Count]); + } + else if(u32BitSize <= SPI_DATA_SIZE_16BIT) + { + /* SPI_DATA_SIZE_9BIT ~ SPI_DATA_SIZE_16BIT */ + WRITE_REG32(SPIx->DR, ((const uint16_t *)pvTxBuf)[u32Count]); + } + else + { + /* SPI_DATA_SIZE_20BIT ~ SPI_DATA_SIZE_32BIT */ + WRITE_REG32(SPIx->DR, ((const uint32_t *)pvTxBuf)[u32Count]); + } + + /* Delay about 10ms */ + u32Timecount = HCLK_VALUE/100UL; + do + { + if(0UL != READ_REG32_BIT(SPIx->SR, SPI_FLAG_TX_BUFFER_EMPTY)) + { + break; + } + u32Timecount--; + } while (u32Timecount != 0U); + + if (u32Timecount == 0U) + { + enRet = ErrorTimeout; + } + + u32Count++; + } + return enRet; +} + +/** + * @} + */ + +#endif /* DDL_SPI_ENABLE */ + +/** + * @} + */ + +/** +* @} +*/ + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_spi.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_spi.h new file mode 100755 index 000000000..961babdd2 --- /dev/null +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/hc32f4a0_spi.h @@ -0,0 +1,446 @@ +/** + ******************************************************************************* + * @file hc32f4a0_spi.h + * @brief This file contains all the functions prototypes of the SPI driver + * library. + @verbatim + Change Logs: + Date Author Notes + 2020-06-12 Wangmin First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by HDSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ +#ifndef __HC32F4A0_SPI_H__ +#define __HC32F4A0_SPI_H__ + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include "hc32_common.h" +#include "ddl_config.h" + +/** + * @addtogroup HC32F4A0_DDL_Driver + * @{ + */ + +/** + * @addtogroup DDL_SPI + * @{ + */ + +#if (DDL_SPI_ENABLE == DDL_ON) + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ +/** + * @defgroup SPI_Global_Types SPI Global Types + * @{ + */ + +/** + * @brief Structure definition of SPI initialization. + */ +typedef struct +{ + uint32_t u32WireMode; /*!< SPI wire mode, 3 wire mode or 4 wire mode. + This parameter can be a value of @ref SPI_Wire_Mode_Define */ + uint32_t u32TransMode; /*!< SPI transfer mode, send only or full duplex. + This parameter can be a value of @ref SPI_Transfer_Mode_Define */ + uint32_t u32MasterSlave; /*!< SPI master/slave mode. + This parameter can be a value of @ref SPI_Master_Slave_Mode_Define */ + uint32_t u32SuspMode; /*!< SPI communication suspend function. + This parameter can be a value of @ref SPI_Communication_Suspend_Function_Define */ + uint32_t u32Modfe; /*!< SPI mode fault detect command. + This parameter can be a value of @ref SPI_Mode_Fault_Dectet_Command_Define */ + uint32_t u32Parity; /*!< SPI parity check selection. + This parameter can be a value of @ref SPI_Parity_Check_Define */ + uint32_t u32SpiMode; /*!< SPI mode. + This parameter can be a value of @ref SPI_Mode_Define */ + uint32_t u32BaudRatePrescaler; /*!< SPI baud rate prescaler. + This parameter can be a value of @ref SPI_Baud_Rate_Prescaler_Define */ + uint32_t u32DataBits; /*!< SPI data bits, 4 bits ~ 32 bits. + This parameter can be a value of @ref SPI_Data_Size_Define */ + uint32_t u32FirstBit; /*!< MSB first or LSB first. + This parameter can be a value of @ref SPI_First_Bit_Define */ + uint32_t u32FrameLevel; /*!< SPI frame level, SPI_FRAME_1 ~ SPI_FRAME_4. + This parameter can be a value of @ref SPI_Frame_Level_Define */ +} stc_spi_init_t; + +/** + * @brief Structure definition of SPI delay time configuration. + */ +typedef struct +{ + uint32_t u32IntervalDelay; /*!< SPI interval time delay (Next access delay time) + This parameter can be a value of @ref SPI_Interval_Delay_Time_define */ + uint32_t u32ReleaseDelay; /*!< SPI release time delay (SCK invalid delay time) + This parameter can be a value of @ref SPI_Release_Delay_Time_define */ + uint32_t u32SetupDelay; /*!< SPI Setup time delay (SCK valid delay time) define + This parameter can be a value of @ref SPI_Setup_Delay_Time_define */ +} stc_spi_delay_t; + +/** + * @} + */ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +/** + * @defgroup SPI_Global_Macros SPI Global Macros + * @{ + */ + +/** + * @defgroup SPI_Wire_Mode_Define SPI wire mode define + * @{ + */ +#define SPI_WIRE_4 (0UL) +#define SPI_WIRE_3 (SPI_CR1_SPIMDS) +/** + * @} + */ + +/** + * @defgroup SPI_Transfer_Mode_Define SPI transfer mode define + * @{ + */ +#define SPI_FULL_DUPLEX (0UL) /*!< Full duplex. */ +#define SPI_SEND_ONLY (SPI_CR1_TXMDS) /*!< Send only. */ +/** + * @} + */ + +/** + * @defgroup SPI_Master_Slave_Mode_Define SPI master slave mode define + * @{ + */ +#define SPI_SLAVE (0UL) +#define SPI_MASTER (SPI_CR1_MSTR) +/** + * @} + */ + +/** + * @defgroup SPI_Loopback_Selection_Define SPI loopback selection define + * @note Loopback mode is mainly used for parity self-diagnosis in 4-wire full-duplex mode. + * @{ + */ +#define SPI_SPLPBK_INVALID (0UL) +#define SPI_SPLPBK_MOSI_INVERT (SPI_CR1_SPLPBK) /*!< MISO data is the inverse of the data output by MOSI. */ +#define SPI_SPLPBK_MOSI (SPI_CR1_SPLPBK2) /*!< MISO data is the data output by MOSI. */ +/** + * @} + */ + +/** + * @defgroup SPI_Communication_Suspend_Function_Define SPI communication suspend function define + * @{ + */ +#define SPI_COM_SUSP_FUNC_OFF (0UL) +#define SPI_COM_SUSP_FUNC_ON (SPI_CR1_CSUSPE) +/** + * @} + */ + +/** + * @defgroup SPI_Interrupt_Type_Define SPI interrupt type define + * @{ + */ +#define SPI_INT_ERROR (SPI_CR1_EIE) /*!< Including overload, underload and parity error. */ +#define SPI_INT_TX_BUFFER_EMPTY (SPI_CR1_TXIE) +#define SPI_INT_RX_BUFFER_FULL (SPI_CR1_RXIE) +#define SPI_INT_IDLE (SPI_CR1_IDIE) +/** + * @} + */ + +/** + * @defgroup SPI_Mode_Fault_Dectet_Command_Define SPI mode fault dectect command define + * @{ + */ +#define SPI_MODFE_DISABLE (0UL) /*!< Disable mode fault detection. */ +#define SPI_MODFE_ENABLE (SPI_CR1_MODFE) /*!< Enable mode fault detection. */ +/** + * @} + */ + +/** + * @defgroup SPI_Parity_Check_Error_Self_Diagnosis_Define SPI parity check error self diagnosis define + * @{ + */ +#define SPI_PATE_DISABLE (0UL) /*!< Disable self diagnosis of parity check. */ +#define SPI_PATE_ENABLE (SPI_CR1_PATE) /*!< Enable self diagnosis of parity check. */ +/** + * @} + */ + +/** + * @defgroup SPI_Parity_Check_Define SPI parity check mode define + * @{ + */ +#define SPI_PARITY_INVALID (0UL) /*!< Parity check invalid. */ +#define SPI_PARITY_EVEN (SPI_CR1_PAE) /*!< Parity check selection even parity. */ +#define SPI_PARITY_ODD (SPI_CR1_PAE | SPI_CR1_PAOE) /*!< Parity check selection odd parity. */ +/** + * @} + */ + +/** + * @defgroup SPI_Interval_Delay_Time_define SPI interval time delay (Next access delay time) define + * @{ + */ +#define SPI_INTERVAL_TIME_1SCK_2PCLK1 (0UL) +#define SPI_INTERVAL_TIME_2SCK_2PCLK1 (SPI_CFG1_MIDI_0) +#define SPI_INTERVAL_TIME_3SCK_2PCLK1 (SPI_CFG1_MIDI_1) +#define SPI_INTERVAL_TIME_4SCK_2PCLK1 (SPI_CFG1_MIDI_1 | SPI_CFG1_MIDI_0) +#define SPI_INTERVAL_TIME_5SCK_2PCLK1 (SPI_CFG1_MIDI_2) +#define SPI_INTERVAL_TIME_6SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_0) +#define SPI_INTERVAL_TIME_7SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_1) +#define SPI_INTERVAL_TIME_8SCK_2PCLK1 (SPI_CFG1_MIDI_2 | SPI_CFG1_MIDI_1 | SPI_CFG1_MIDI_0) +/** + * @} + */ + +/** + * @defgroup SPI_Release_Delay_Time_define SPI release time delay (SCK invalid delay time) define + * @{ + */ +#define SPI_RELEASE_TIME_1SCK (0UL) +#define SPI_RELEASE_TIME_2SCK (SPI_CFG1_MSSDL_0) +#define SPI_RELEASE_TIME_3SCK (SPI_CFG1_MSSDL_1) +#define SPI_RELEASE_TIME_4SCK (SPI_CFG1_MSSDL_1 | SPI_CFG1_MSSDL_0) +#define SPI_RELEASE_TIME_5SCK (SPI_CFG1_MSSDL_2) +#define SPI_RELEASE_TIME_6SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_0) +#define SPI_RELEASE_TIME_7SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_1) +#define SPI_RELEASE_TIME_8SCK (SPI_CFG1_MSSDL_2 | SPI_CFG1_MSSDL_1 | SPI_CFG1_MSSDL_0) +/** + * @} + */ + +/** + * @defgroup SPI_Setup_Delay_Time_define SPI Setup time delay (SCK valid delay time) define + * @{ + */ +#define SPI_SETUP_TIME_1SCK (0UL) +#define SPI_SETUP_TIME_2SCK (SPI_CFG1_MSSI_0) +#define SPI_SETUP_TIME_3SCK (SPI_CFG1_MSSI_1) +#define SPI_SETUP_TIME_4SCK (SPI_CFG1_MSSI_1 | SPI_CFG1_MSSI_0) +#define SPI_SETUP_TIME_5SCK (SPI_CFG1_MSSI_2) +#define SPI_SETUP_TIME_6SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_0) +#define SPI_SETUP_TIME_7SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_1) +#define SPI_SETUP_TIME_8SCK (SPI_CFG1_MSSI_2 | SPI_CFG1_MSSI_1 | SPI_CFG1_MSSI_0) +/** + * @} + */ + +/** + * @defgroup SPI_SS_Pin_Define SPI SSx define + * @{ + */ +#define SPI_PIN_SS0 (SPI_CFG1_SS0PV) +#define SPI_PIN_SS1 (SPI_CFG1_SS1PV) +#define SPI_PIN_SS2 (SPI_CFG1_SS2PV) +#define SPI_PIN_SS3 (SPI_CFG1_SS3PV) +/** + * @} + */ + +/** + * @defgroup SPI_SS_Active_Level_Define SPI SSx Active Level define + * @{ + */ +#define SPI_SS_ACTIVE_LOW (0UL) /*!< SS pin active low. */ +#define SPI_SS_ACTIVE_HIGH (1UL) /*!< SS pin active high. */ +/** + * @} + */ + +/** + * @defgroup SPI_Read_Target_Buffer_Define SPI read data register target buffer define + * @{ + */ +#define SPI_RD_TARGET_RD_BUF (0UL) /*!< Read RX buffer. */ +#define SPI_RD_TARGET_WR_BUF (SPI_CFG1_SPRDTD) /*!< Read TX buffer. */ +/** + * @} + */ + +/** + * @defgroup SPI_Frame_Level_Define SPI data frame level define, The Data in the + * SPI_DR register will be send to TX_BUFF after + * enough data frame write to the SPI_DR + * @{ + */ +#define SPI_FRAME_1 (0UL) /*!< Data 1 frame */ +#define SPI_FRAME_2 (SPI_CFG1_FTHLV_0) /*!< Data 2 frame.*/ +#define SPI_FRAME_3 (SPI_CFG1_FTHLV_1) /*!< Data 3 frame.*/ +#define SPI_FRAME_4 (SPI_CFG1_FTHLV_0 | SPI_CFG1_FTHLV_1) /*!< Data 4 frame.*/ +/** + * @} + */ + +/** + * @defgroup SPI_Mode_Define SPI Mode define + * @{ + */ +/* SCK pin output low in idle state; MOSI/MISO pin data valid in odd edge , MOSI/MISO pin data change in even edge */ +#define SPI_MODE_0 (0UL) +/* SCK pin output low in idle state; MOSI/MISO pin data valid in even edge , MOSI/MISO pin data change in odd edge */ +#define SPI_MODE_1 (SPI_CFG2_CPHA) +/* SCK pin output high in idle state; MOSI/MISO pin data valid in odd edge , MOSI/MISO pin data change in even edge */ +#define SPI_MODE_2 (SPI_CFG2_CPOL) +/* SCK pin output high in idle state; MOSI/MISO pin data valid in even edge , MOSI/MISO pin data change in odd edge */ +#define SPI_MODE_3 (SPI_CFG2_CPOL | SPI_CFG2_CPHA) +/** + * @} + */ + +/** + * @defgroup SPI_Baud_Rate_Prescaler_Define SPI baudrate prescaler define + * @{ + */ +#define SPI_BR_PCLK1_DIV2 (0UL) /*!< SPI baud rate is the pclk1 divided by 2. */ +#define SPI_BR_PCLK1_DIV4 (SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 4. */ +#define SPI_BR_PCLK1_DIV8 (SPI_CFG2_MBR_1) /*!< SPI baud rate is the pclk1 clock divided by 8. */ +#define SPI_BR_PCLK1_DIV16 (SPI_CFG2_MBR_1 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 16. */ +#define SPI_BR_PCLK1_DIV32 (SPI_CFG2_MBR_2) /*!< SPI baud rate is the pclk1 clock divided by 32. */ +#define SPI_BR_PCLK1_DIV64 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 clock divided by 64. */ +#define SPI_BR_PCLK1_DIV128 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_1) /*!< SPI baud rate is the pclk1 clock divided by 128. */ +#define SPI_BR_PCLK1_DIV256 (SPI_CFG2_MBR_2 | SPI_CFG2_MBR_1 | SPI_CFG2_MBR_0) /*!< SPI baud rate is the pclk1 divided by 256. */ +/** + * @} + */ + +/** + * @defgroup SPI_Data_Size_Define SPI data size define + * @{ + */ +#define SPI_DATA_SIZE_4BIT (0UL) +#define SPI_DATA_SIZE_5BIT (SPI_CFG2_DSIZE_0) +#define SPI_DATA_SIZE_6BIT (SPI_CFG2_DSIZE_1) +#define SPI_DATA_SIZE_7BIT (SPI_CFG2_DSIZE_0 | SPI_CFG2_DSIZE_1) +#define SPI_DATA_SIZE_8BIT (SPI_CFG2_DSIZE_2) +#define SPI_DATA_SIZE_9BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_0) +#define SPI_DATA_SIZE_10BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1) +#define SPI_DATA_SIZE_11BIT (SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0) +#define SPI_DATA_SIZE_12BIT (SPI_CFG2_DSIZE_3) +#define SPI_DATA_SIZE_13BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_0) +#define SPI_DATA_SIZE_14BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_1) +#define SPI_DATA_SIZE_15BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0) +#define SPI_DATA_SIZE_16BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2) +#define SPI_DATA_SIZE_20BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_0) +#define SPI_DATA_SIZE_24BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1) +#define SPI_DATA_SIZE_32BIT (SPI_CFG2_DSIZE_3 | SPI_CFG2_DSIZE_2 | SPI_CFG2_DSIZE_1 | SPI_CFG2_DSIZE_0) +/** + * @} + */ + +/** + * @defgroup SPI_First_Bit_Define SPI first bit define + * @{ + */ +#define SPI_FIRST_MSB (0UL) +#define SPI_FIRST_LSB (SPI_CFG2_LSBF) +/** + * @} + */ + +/** + * @defgroup SPI_State_Flag_Define SPI state flag define + * @{ + */ +#define SPI_FLAG_OVERLOAD (SPI_SR_OVRERF) +#define SPI_FLAG_IDLE (SPI_SR_IDLNF) +#define SPI_FLAG_MODE_FAULT (SPI_SR_MODFERF) +#define SPI_FLAG_PARITY_ERROR (SPI_SR_PERF) +#define SPI_FLAG_UNDERLOAD (SPI_SR_UDRERF) +#define SPI_FLAG_TX_BUFFER_EMPTY (SPI_SR_TDEF) /*!< This flag is set when the data in the data register \ + is copied into the shift register, but the transmission \ + of the data bit may not have been completed. */ +#define SPI_FLAG_RX_BUFFER_FULL (SPI_SR_RDFF) /*!< When this flag is set, it indicates that a data was received. */ + +/** + * @} + */ + +/** + * @} + */ + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +/** + * @addtogroup SPI_Global_Functions + * @{ + */ +en_result_t SPI_StructInit(stc_spi_init_t *pstcInit); +en_result_t SPI_DelayStructInit(stc_spi_delay_t *pstcDelayCfg); + +en_result_t SPI_Init(M4_SPI_TypeDef *SPIx, const stc_spi_init_t *pstcInit); +void SPI_DeInit(M4_SPI_TypeDef *SPIx); + +void SPI_IntCmd(M4_SPI_TypeDef *SPIx, uint32_t u32IntType, en_functional_state_t enNewState); +void SPI_FunctionCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState); + +void SPI_WriteDataReg(M4_SPI_TypeDef *SPIx, uint32_t u32Data); +uint32_t SPI_ReadDataReg(const M4_SPI_TypeDef *SPIx); + +en_flag_status_t SPI_GetStatus(const M4_SPI_TypeDef *SPIx, uint32_t u32Flag); +void SPI_ClearFlag(M4_SPI_TypeDef *SPIx, uint32_t u32Flag); + +void SPI_LoopbackModeCfg(M4_SPI_TypeDef *SPIx, uint32_t u32Mode); +void SPI_PateCmd(M4_SPI_TypeDef *SPIx, en_functional_state_t enNewState); +en_result_t SPI_DelayTimeCfg(M4_SPI_TypeDef *SPIx, const stc_spi_delay_t *pstcDelayCfg); +void SPI_SSValidLevelCfg(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin, en_functional_state_t enNewState); +void SPI_SSPinSel(M4_SPI_TypeDef *SPIx, uint32_t u32SSPin); +void SPI_ReadBufCfg(M4_SPI_TypeDef *SPIx, uint32_t u32ReadBuf); + +en_result_t SPI_Transmit(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, uint32_t u32TxLength); +en_result_t SPI_Receive(M4_SPI_TypeDef *SPIx, void *pvRxBuf, uint32_t u32RxLength); +en_result_t SPI_TransmitReceive(M4_SPI_TypeDef *SPIx, const void *pvTxBuf, void *pvRxBuf, uint32_t u32Length); + +/** + * @} + */ + +#endif /* DDL_SPI_ENABLE */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __HC32F4A0_SPI_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/w25qxx.c b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/w25qxx.c deleted file mode 100755 index 5a5f5c807..000000000 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/w25qxx.c +++ /dev/null @@ -1,575 +0,0 @@ -/** - ******************************************************************************* - * @file w25qxx.c - * @brief This midware file provides firmware functions to W25QXX group spi flash. - @verbatim - Change Logs: - Date Author Notes - 2020-06-12 Wangmin First version - 2020-08-31 Wangmin Modify for MISRAC2012 - @endverbatim - ******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ******************************************************************************* - */ - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "w25qxx.h" -#include "ev_hc32f4a0_lqfp176_w25qxx.h" - -/** - * @addtogroup BSP - * @{ - */ - -/** - * @addtogroup Components - * @{ - */ - -/** @defgroup W25QXX Flash Driver for W25QXX - * @{ - */ - -#if (BSP_W25QXX_ENABLE == BSP_ON) - -/******************************************************************************* - * Local type definitions ('typedef') - ******************************************************************************/ - -/******************************************************************************* - * Local pre-processor symbols/macros ('#define') - ******************************************************************************/ -/** - * @defgroup W25QXX_Local_Macros W25QXX Local Macros - * @{ - */ -#define W25Q_BIT_0 (1UL << 0U) -#define W25Q_BIT_1 (1UL << 1U) -#define W25Q_BIT_2 (1UL << 2U) -#define W25Q_BIT_3 (1UL << 3U) -#define W25Q_BIT_4 (1UL << 4U) -#define W25Q_BIT_5 (1UL << 5U) -#define W25Q_BIT_6 (1UL << 6U) -#define W25Q_BIT_7 (1UL << 7U) -#define W25Q_BIT_8 (1UL << 8U) -#define W25Q_BIT_9 (1UL << 9U) -#define W25Q_BIT_10 (1UL << 10U) -#define W25Q_BIT_11 (1UL << 11U) -#define W25Q_BIT_12 (1UL << 12U) -#define W25Q_BIT_13 (1UL << 13U) -#define W25Q_BIT_14 (1UL << 14U) -#define W25Q_BIT_15 (1UL << 15U) - -#define W25Q_ST_BUSY ((uint16_t)W25Q_BIT_0) -#define W25Q_ST_WEL ((uint16_t)W25Q_BIT_1) /*> 16U); \ - (a)[2U] = (uint8_t)((addr) >> 8U); \ - (a)[3U] = (uint8_t)(addr); \ - } while (0U) - -/** - * @} - */ - -/******************************************************************************* - * Global variable definitions (declared in header file with 'extern') - ******************************************************************************/ - -/******************************************************************************* - * Local function prototypes ('static') - ******************************************************************************/ -/** - * @defgroup W25QXX_Local_Functions W25QXX Local Functions - * @{ - */ -static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength); -static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength, - uint8_t *pu8Info, uint8_t u8InfoLength); - -static void W25QXX_Wt(uint8_t u8Cmd, uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength); -static void W25QXX_Rd(uint8_t u8Cmd, uint32_t u32Address, uint8_t *pu8Data, uint32_t u32DataLength); - -static void W25QXX_WaitBusy(void); - -static void W25QXX_WriteEnable(void); -static void W25QXX_WriteDisable(void); - -static void W25QXX_WritePage(uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength); - -static void W25QXX_Write_NoCheck(const uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite); -static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength); -static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength, - uint8_t *pu8Info, uint8_t u8InfoLength); -/** - * @} - */ - -/******************************************************************************* - * Local variable definitions ('static') - ******************************************************************************/ -static uint8_t W25QXX_BUFFER[4096U]; - -/******************************************************************************* - * Function implementation - global ('extern') and local ('static') - ******************************************************************************/ -/** - * @defgroup W25QXX_Global_Functions W25QXX Global Functions - * @{ - */ - -/** - * @brief Initializes W25QXX. - * @param [out] pstcW25qxx Pointer to a stc_w25qxx_t structure which contains the information of the SPI flash. - * @retval None - */ -void W25QXX_Init(stc_w25qxx_t *pstcW25qxx) -{ - BSP_W25Q_SPI_Init(); - - if (pstcW25qxx != NULL) - { - /* Read Flash ID */ - pstcW25qxx->u16ManId = W25QXX_ReadManDeviceId(); - - switch (pstcW25qxx->u16ManId) - { - case W25Q64: - pstcW25qxx->u32PageCount = 32768UL; /* W25Q64 contains 32768 pages. */ - pstcW25qxx->u32SectorCount = 2048U; /* W25Q64 contains 2048 sectors. */ - pstcW25qxx->u32BlockCount32k = 0U; /* DO NOT support 32K block. */ - pstcW25qxx->u32BlockCount64k = 128U; - pstcW25qxx->u32CapacityInBytes = pstcW25qxx->u32PageCount * W25Q_SIZE_PAGE; - pstcW25qxx->u32CapacityInKB = pstcW25qxx->u32CapacityInBytes * W25Q_SIZE_1K; - break; - - default: - break; - } - } -} - -/** - * @brief Read manufacturer device ID. - * @param None - * @retval 16 bit manufacturer device ID. - */ -uint16_t W25QXX_ReadManDeviceId(void) -{ - uint8_t au8TempId[2U]; - uint8_t au8Dummy[3U] = {0U}; - uint16_t u16ManID; - - W25QXX_ReadCmd(W25Q_MANUFACTURER_DEVICE_ID, au8Dummy, 3U, au8TempId, 2U); - - u16ManID = (uint16_t)au8TempId[0U] << 8U; - u16ManID |= au8TempId[1U]; - - return u16ManID; -} - -/** - * @brief Read unique ID. - * @param [out] pu8UniqueId Pointer to a buffer the 64 bit unique ID to be stored. - * @retval None - */ -void W25QXX_ReadUniqueId(uint8_t *pu8UniqueId) -{ - uint8_t au8Dummy[4U] = {0U}; - - W25QXX_ReadCmd(W25Q_READ_UNIQUE_ID, au8Dummy, 4U, pu8UniqueId, 8U); -} - -/** - * @brief W25QXX read status register. - * @param None - * @retval 16 bit W25QXX status. - */ -uint16_t W25QXX_ReadStatus(void) -{ - uint8_t u8TempStatus; - uint16_t u16RetStatus; - - W25QXX_ReadCmd(W25Q_READ_STATUS_REG_2, NULL, 0U, &u8TempStatus, 1U); - - u16RetStatus = u8TempStatus; - - W25QXX_ReadCmd(W25Q_READ_STATUS_REG_1, NULL, 0U, &u8TempStatus, 1U); - - u16RetStatus <<= 8U; - u16RetStatus |= u8TempStatus; - - return u16RetStatus; -} - -/** - * @brief W25QXX write status register - * @param [in] u16Status Specified status. - * @retval None - */ -void W25QXX_WriteStatus(uint16_t u16Status) -{ - uint8_t au8Data[2U]; - - au8Data[0U] = (uint8_t)u16Status; - au8Data[1U] = (uint8_t)(u16Status >> 8U); - - W25QXX_WriteCmd(W25Q_WRITE_STATUS_REG, au8Data, 2U); -} - -/** - * @brief W25QXX power down. - * @param None - * @retval None - */ -void W25QXX_PowerDown(void) -{ - W25QXX_WriteCmd(W25Q_POWER_DOWN, NULL, 0U); - - W25QXX_DELAY_MS(1U); -} - -/** - * @brief W25QXX release power down. - * @param None - * @retval None - */ -void W25QXX_ReleasePowerDown(void) -{ - W25QXX_WriteCmd(W25Q_RELEASE_POWER_DOWN, NULL, 0U); - - W25QXX_DELAY_MS(1U); -} - -/** - * @brief W25QXX chip ease. - * @param None - * @retval None - */ -void W25QXX_EraseChip(void) -{ - W25QXX_WriteEnable(); - W25QXX_WaitBusy(); - W25QXX_WriteCmd(W25Q_CHIP_ERASE, NULL, 0U); - W25QXX_WaitBusy(); -} - -/** - * @brief W25QXX sector ease. - * @param [in] u32SectorAddress The address of the specified sector. - * @retval None - */ -void W25QXX_EraseSector(uint32_t u32SectorAddress) -{ - u32SectorAddress *= W25Q_SIZE_SECTOR; - - W25QXX_WriteEnable(); - W25QXX_WaitBusy(); - - W25QXX_Wt(W25Q_SECTOR_ERASE, u32SectorAddress, NULL, 0U); - - W25QXX_WaitBusy(); - W25QXX_WriteDisable(); -} - -/** - * @brief W25QXX block ease. - * @param [in] u32BlockAddress The address of the specified block. - * @retval None - */ -void W25QXX_EraseBlock(uint32_t u32BlockAddress) -{ - W25QXX_Wt(W25Q_BLOCK_ERASE_64K, u32BlockAddress, NULL, 0U); -} - - -/** - * @brief W25QXX flash write - * @param [in] pBuffer Data buffer to be written - * @param [in] WriteAddr Address to be written - * @param [in] NumByteToWrite Number to be written, (MAX. 65535) - * @retval None - */ -static void W25QXX_Write_NoCheck(const uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) -{ - uint32_t pageremain; - uint32_t u32BufAdrTmp = (uint32_t)pBuffer; - pageremain = 256U - WriteAddr % 256U; - if (NumByteToWrite <= pageremain) - { - pageremain = NumByteToWrite; - } - for(;;) - { - W25QXX_WritePage(WriteAddr, (uint8_t *)u32BufAdrTmp, pageremain); - if (NumByteToWrite == (uint16_t)pageremain) - { - break; - } - else //NumByteToWrite>pageremain - { - u32BufAdrTmp += pageremain; - WriteAddr += pageremain; - - NumByteToWrite -= (uint16_t)pageremain; - if (NumByteToWrite > 256U) - { - pageremain = 256U; - } - else - { - pageremain = (uint32_t)NumByteToWrite; - } - } - } -} - - -/** - * @brief W25QXX write data. - * @param [in] u32Address The start address of the data to be written. - * @param [in] pu8WriteBuf The pointer to the buffer contains the data to be written. - * @param [in] u32NumByteToWrite Buffer size in bytes. - * @retval None - */ -void W25QXX_WriteData(uint32_t u32Address, const uint8_t *pu8WriteBuf, uint32_t u32NumByteToWrite) -{ - uint32_t secpos; - uint16_t secoff; - uint16_t secremain; - uint16_t i; - uint8_t *pW25QXX_BUF; - pW25QXX_BUF = W25QXX_BUFFER; - uint32_t u32WriteBufAddr = (uint32_t)&pu8WriteBuf; - - secpos = u32Address / 4096U; - secoff = (uint16_t)(u32Address % 4096U); - secremain = 4096U - secoff; - - if (u32NumByteToWrite <= secremain) - { - secremain = (uint16_t)u32NumByteToWrite; - } - for(;;) - { - W25QXX_ReadData(secpos * 4096U, pW25QXX_BUF, 4096U); // read one sector content - for (i = 0U; i < secremain; i++) // check if blank sector - { - if (pW25QXX_BUF[secoff + i] != (uint8_t)0xFFU) - { - break; - } - } - if (i < secremain) - { - W25QXX_EraseSector(secpos); // not blank, need erase - for (i = 0U; i < secremain; i++) // backup first - { - pW25QXX_BUF[i + secoff] = pu8WriteBuf[i]; - } - W25QXX_Write_NoCheck(pW25QXX_BUF, secpos * 4096U, 4096U); // write back after erase - - } - else - { - W25QXX_Write_NoCheck((const uint8_t *)u32WriteBufAddr, u32Address, secremain); - } - if (u32NumByteToWrite == secremain) - { - break; - } - else - { - secpos++; // next sector - secoff = 0U; - - u32WriteBufAddr += secremain; - u32Address += secremain; - u32NumByteToWrite -= secremain; - if (u32NumByteToWrite > 4096U) - { - secremain = 4096U; - } - else - { - secremain = (uint16_t)u32NumByteToWrite; - } - } - } -} - -/** - * @brief W25QXX read data. - * @param [in] u32Address The start address of the data to be read. - * @param [in] pu8ReadBuf The pointer to the buffer contains the data to be stored. - * @param [in] u32NumByteToRead Buffer size in bytes. - * @retval None - */ -void W25QXX_ReadData(uint32_t u32Address, uint8_t *pu8ReadBuf, uint32_t u32NumByteToRead) -{ - W25QXX_Rd(W25Q_READ_DATA, u32Address, pu8ReadBuf, u32NumByteToRead); -} - -/** - * @} - */ - -/** - * @addtogroup W25QXX_Local_Functions W25QXX Local Functions - * @{ - */ - -/** - * @brief W25QXX write command. - * @param [in] u8Cmd Command of W25QXX. - * @param [in] pu8CmdData Pointer to a buffer that contains the data following the command. - * @param [in] u32CmdDataLength The length of the command data in bytes. - * @retval None - */ -static void W25QXX_WriteCmd(uint8_t u8Cmd, const uint8_t *pu8CmdData, uint32_t u32CmdDataLength) -{ - W25Q_CS_ACTIVE(); - (void)BSP_W25Q_SPI_Transmit(&u8Cmd, 1U); - (void)BSP_W25Q_SPI_Transmit(pu8CmdData, u32CmdDataLength); - W25Q_CS_INACTIVE(); -} - -/** - * @brief W25QXX read command. - * @param [in] u8Cmd Command of W25QXX. - * @param [in] pu8CmdData Pointer to a buffer that contains the data following the command. - * @param [in] u32CmdDataLength The length of the command data in bytes. - * @param [in] pu8Info The information of the command. - * @param [in] u8InfoLength The length of the information. - * @retval None - */ -static void W25QXX_ReadCmd(uint8_t u8Cmd, uint8_t *pu8CmdData, uint32_t u32CmdDataLength, - uint8_t *pu8Info, uint8_t u8InfoLength) -{ - W25Q_CS_ACTIVE(); - (void)BSP_W25Q_SPI_Transmit(&u8Cmd, 1U); - (void)BSP_W25Q_SPI_Transmit(pu8CmdData, u32CmdDataLength); - (void)BSP_W25Q_SPI_Receive(pu8Info, (uint32_t)u8InfoLength); - W25Q_CS_INACTIVE(); -} - -/** - * @brief W25QXX write data. - * @param [in] u8Cmd Command of W25QXX. - * @param [in] u32Address The start address of the data to be written. - * @param [in] pu8Data The data to be written. - * @param [in] u32DataLength The length of the data in bytes. - * @retval None - */ -static void W25QXX_Wt(uint8_t u8Cmd, uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength) -{ - uint8_t au8Cmd[4U]; - - LOAD_CMD(au8Cmd, u8Cmd, u32Address); - - W25Q_CS_ACTIVE(); - (void)BSP_W25Q_SPI_Transmit(au8Cmd, 4U); - (void)BSP_W25Q_SPI_Transmit(pu8Data, u32DataLength); - W25Q_CS_INACTIVE(); -} - -/** - * @brief W25QXX read data. - * @param [in] u8Cmd Command of W25QXX. - * @param [in] u32Address The start address of the data to be written. - * @param [in] pu8Data The data to be stored. - * @param [in] u32DataLength The length of the data in bytes. - * @retval None - */ -static void W25QXX_Rd(uint8_t u8Cmd, uint32_t u32Address, uint8_t *pu8Data, uint32_t u32DataLength) -{ - uint8_t au8Cmd[4U]; - - LOAD_CMD(au8Cmd, u8Cmd, u32Address); - - W25Q_CS_ACTIVE(); - (void)BSP_W25Q_SPI_Transmit(au8Cmd, 4U); - (void)BSP_W25Q_SPI_Receive(pu8Data, u32DataLength); - W25Q_CS_INACTIVE(); -} - -/** - * @brief W25QXX Write enable. - * @param None - * @retval None - */ -static void W25QXX_WriteEnable(void) -{ - W25QXX_WriteCmd(W25Q_WRITE_ENABLE, NULL, 0U); -} - -/** - * @brief W25QXX Write disable. - * @param None - * @retval None - */ -static void W25QXX_WriteDisable(void) -{ - W25QXX_WriteCmd(W25Q_WRITE_DISABLE, NULL, 0U); -} - -/** - * @brief Wait while W25QXX is busy. - * @param None - * @retval None - */ -static void W25QXX_WaitBusy(void) -{ - while ((W25QXX_ReadStatus() & W25Q_ST_BUSY) == W25Q_ST_BUSY) - { - ; - } -} - -/** - * @brief W25QXX page program. - * @param [in] u32Address Start address of the page. - * @param [in] pu8Data Pointer to a buffer that contains the data to be written. - * @param [in] u32DataLength Size of the buffer in bytes. - * @retval None - */ -static void W25QXX_WritePage(uint32_t u32Address, const uint8_t *pu8Data, uint32_t u32DataLength) -{ - W25QXX_WriteEnable(); - W25QXX_Wt(W25Q_PAGE_PROGRAM, u32Address, pu8Data, u32DataLength); - W25QXX_WaitBusy(); -} - -/** - * @} - */ - -#endif /* BSP_W25QXX_ENABLE */ - -/** - * @} - */ - -/** - * @} - */ - - -/** -* @} -*/ - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/w25qxx.h b/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/w25qxx.h deleted file mode 100755 index d68dda1c1..000000000 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/app_match_nuttx/nuttx/arch/arm/src/hc32/w25qxx.h +++ /dev/null @@ -1,197 +0,0 @@ -/** - ******************************************************************************* - * @file w25qxx.h - * @brief This file provides firmware functions to W25QXX group spi flash. - @verbatim - Change Logs: - Date Author Notes - 2020-06-12 Wangmin First version - @endverbatim - ******************************************************************************* - * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved. - * - * This software component is licensed by HDSC under BSD 3-Clause license - * (the "License"); You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ******************************************************************************* - */ -#ifndef __W25QXX_H__ -#define __W25QXX_H__ - -/* C binding of definitions if building with C++ compiler */ -#ifdef __cplusplus -extern "C" -{ -#endif - -/******************************************************************************* - * Include files - ******************************************************************************/ -#include "hc32_common.h" - -/** - * @addtogroup BSP - * @{ - */ - -/** - * @addtogroup Components - * @{ - */ - -/** @addtogroup W25QXX - * @{ - */ - -#if (BSP_W25QXX_ENABLE == BSP_ON) - -/******************************************************************************* - * Global type definitions ('typedef') - ******************************************************************************/ -/** - * @defgroup W25QXX_Global_Types W25QXX Global Types - * @{ - */ - -/** - * @brief Structure definition of W25QXX information. - */ -typedef struct -{ - uint16_t u16ManId; /*!< Manufacturer device ID. */ - uint8_t au8UniqueId[8U]; /*!< 64 bit unique ID number. */ - uint32_t u32PageCount; - uint32_t u32SectorCount; - uint32_t u32BlockCount32k; - uint32_t u32BlockCount64k; - uint32_t u32CapacityInBytes; - uint32_t u32CapacityInKB; -} stc_w25qxx_t; - - -/** - * @} - */ - -/******************************************************************************* - * Global pre-processor symbols/macros ('#define') - ******************************************************************************/ -/** - * @defgroup W25QXX_Global_Macros W25QXX Global Macros - * @{ - */ - -/** - * @defgroup W25QXX_ID W25QXX ID - * @{ - */ -#define W25Q80 (0xEF13U) -#define W25Q16 (0xEF14U) -#define W25Q32 (0xEF15U) -#define W25Q64 (0xEF16U) -#define W25Q128 (0xEF17U) -/** - * @} - */ - -/** - * @defgroup W25QXX_Command W25QXX Command - * @{ - */ -#define W25Q_WRITE_ENABLE ((uint8_t)0x06U) -#define W25Q_VOLATILE_SR_WRITE_ENABLE ((uint8_t)0x50U) -#define W25Q_WRITE_DISABLE ((uint8_t)0x04U) -#define W25Q_READ_STATUS_REG_1 ((uint8_t)0x05U) -#define W25Q_READ_STATUS_REG_2 ((uint8_t)0x35U) -#define W25Q_WRITE_STATUS_REG ((uint8_t)0x01U) -#define W25Q_PAGE_PROGRAM ((uint8_t)0x02U) -#define W25Q_SECTOR_ERASE ((uint8_t)0x20U) -#define W25Q_BLOCK_ERASE_32K ((uint8_t)0x52U) -#define W25Q_BLOCK_ERASE_64K ((uint8_t)0xD8U) -#define W25Q_CHIP_ERASE ((uint8_t)0xC7U) -#define W25Q_ERASE_PROGRAM_SUSPEND ((uint8_t)0x75U) -#define W25Q_ERASE_PROGRAM_RESUME ((uint8_t)0x7AU) -#define W25Q_POWER_DOWN ((uint8_t)0xB9U) -#define W25Q_READ_DATA ((uint8_t)0x03U) -#define W25Q_FAST_READ ((uint8_t)0x0BU) -#define W25Q_DEVICE_ID ((uint8_t)0xABU) -#define W25Q_RELEASE_POWER_DOWN (W25Q_DEVICE_ID) -#define W25Q_MANUFACTURER_DEVICE_ID ((uint8_t)0x90U) -#define W25Q_JEDEC_ID ((uint8_t)0x9FU) -#define W25Q_READ_UNIQUE_ID ((uint8_t)0x4BU) -#define W25Q_READ_SFDP_REG ((uint8_t)0x5AU) -#define W25Q_REASE_SECURITY_REG ((uint8_t)0x44U) -#define W25Q_PROGRAM_SECURITY_REG ((uint8_t)0x42U) -#define W25Q_READ_SECURITY_REG ((uint8_t)0x48U) -#define W25Q_ENABLE_QPI ((uint8_t)0x38U) -#define W25Q_ENABLE_RESET ((uint8_t)0x66U) -#define W25Q_RESET ((uint8_t)0x99U) -/** - * @} - */ - -#define W25Q_SIZE_1K (1024U) /*!< 1KB */ -#define W25Q_SIZE_PAGE (256U) /*!< 256B/page */ -#define W25Q_SIZE_SECTOR (W25Q_SIZE_1K * 4U) /*!< 4KB/sector */ -#define W25Q_SIZE_BLOCK (W25Q_SIZE_1K * 64U) /*!< 64KB/block */ - -/** - * @} - */ - -/******************************************************************************* - * Global variable definitions ('extern') - ******************************************************************************/ - -/******************************************************************************* - Global function prototypes (definition in C source) - ******************************************************************************/ -/** - * @addtogroup W25QXX_Global_Functions W25QXX Global Functions - * @{ - */ -void W25QXX_Init(stc_w25qxx_t *pstcW25qxx); -uint16_t W25QXX_ReadManDeviceId(void); -void W25QXX_ReadUniqueId(uint8_t *pu8UniqueId); - -uint16_t W25QXX_ReadStatus(void); -void W25QXX_WriteStatus(uint16_t u16Status); -void W25QXX_PowerDown(void); -void W25QXX_ReleasePowerDown(void); - -void W25QXX_EraseChip(void); -void W25QXX_EraseSector(uint32_t u32SectorAddress); -void W25QXX_EraseBlock(uint32_t u32BlockAddress); - -void W25QXX_WriteData(uint32_t u32Address, const uint8_t *pu8WriteBuf, uint32_t u32NumByteToWrite); -void W25QXX_ReadData(uint32_t u32Address, uint8_t *pu8ReadBuf, uint32_t u32NumByteToRead); -/** - * @} - */ - - -#endif /* BSP_W25QXX_ENABLE */ - -/** - * @} - */ - -/** - * @} - */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* __W25QXX_H__ */ - -/******************************************************************************* - * EOF (not truncated) - ******************************************************************************/ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/Kconfig b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/Kconfig new file mode 100644 index 000000000..d36030958 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/Kconfig @@ -0,0 +1,36 @@ +menu "TableStorage" + + config TABLE_STORAGE + bool "Using Table storage system" + default n + +if TABLE_STORAGE + + config TABLE_STORAGE_BASIC + bool "Enable TableStorage Basic" + default y + + config TABLE_STORAGE_QUERY + bool "[System-level] Enable TableStorage Buffer" + default n + + config TABLE_STORAGE_CACHE + bool "[System-level] Enable TableStorage Prefetcher" + default n + + config TABLE_STORAGE_PREFETCH + bool "[Table-level] Enable TableStorage Query Cache" + default n + + config TABLE_STORAGE_SECOND_INDEX + bool "[Table-level] Enable TableStorage Second Index" + default n + + config TABLE_STORAGE_TRANSACTION + bool "(Other) Enable TableStorage Transaction" + default n + + +endif + +endmenu diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/README.md b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/README.md new file mode 100644 index 000000000..f08c33635 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/README.md @@ -0,0 +1,153 @@ +## README + +TableStorage是一款面向泛在操作系统的轻量级表存储原型系统。TableStorage专注于泛在操作系统场景下结构化数据的存储,与传统的多层堆叠式软件栈(数据库 + 文件系统)不同,TableStorage避免过度分层,从存储全栈角度,进行跨层(数据库的存储引擎 + 文件系统)的设计,主要包含以下三个属性 + +- 低冗余:去除文件抽象并直接将“表”存储到设备中, 避免功能冗余和不必要的软件开销 +- 兼容性:提供一组通用的API 以支持表级的存取操作,与传统数据库中的读写操作兼容 +- 可集成:支持组件的深度集成,具体来说, 可以集成事务和执行引擎以满足复杂的事务和查询处理需求 + + + +### 开发板 + +- K210最小系统板(Max bit) + +- SD卡配置 + + | 引脚 | 作用 | RW007板子 | + | :----------------: | :-------: | :-------: | + | io 27(印丝标注SCK) | SPI1_SCK | SCK | + | io 26(印丝标注SO) | SPI1_MISO | MISO | + | io 28(印丝标注SI) | SPI1_MOSI | MOSI | + | io 29 | CS/BOOT1 | CS | + + + +### 编译说明 + +- 环境搭建 + + - 参考https://gitlink.org.cn/xuos/xiuos/tree/prepare_for_master/Ubiquitous%2FXiZi_IIoT%2Fboard%2Fkd233下的**开发环境搭建**小节,搭建好XiUOS的开发环境 + + - 参考https://gitlink.org.cn/xuos/xiuos/tree/prepare_for_master/Ubiquitous%2FRT-Thread_Fusion_XiUOS%2Faiit_board%2Fk210搭建好XiUOS-RTThread的开发环境 + +- 配置XiUOS-RTThread基本环境 + + - SD卡的配置:按照上表SD卡引脚说明配置 + + image-20221123215723700 + + - 其他推荐配置 + + image-20221123215509060 + + - (可选)如果编译时,出现定时器错误,则可以选择使用软件定时器 + + image-20221123215939427 + +- 配置TableStorage + + ```shell + scons --menuconfig + ``` + + - 若不开启TableStorage组件,则自动在SD卡上使用FATFS + + - 若开启TableStorage组件,则在SD卡上使用TableStorage,默认打开了Enable TableStorage Basic模块(注:当前版本仅支持Basic模块) + + image-20221123213344406 + +- 执行 scons 编译,若编译正确无误,在当前文件夹下生成rtthread.elf、rtthread.bin。其中rtthread.bin需要烧写到设备中进行运行 + +- 烧录及运行结果图 + + ```shell + sudo kflash -t rtthread.bin -p /dev/ttyUSB0 + ``` + + - 烧录并运行无误,则 + + image-20221123215143184 + + + +### 调试 + +- 修改k210/rtconfig.py中的BUILD选项来配置debug模式,并重新编译 + +- 安装openocd(下载ubuntu版本64位), + + - 下载地址:[Releases · kendryte/openocd-kendryte (github.com)](https://github.com/kendryte/openocd-kendryte/releases),推荐下载地址为:http://101.36.126.201:8011/kendryte-openocd-0.2.3-ubuntu64.tar.gz + + - 安装 + + ```shell + sudo apt install libusb-dev libftdi-dev libhidapi-dev + sudo mv kendryte-openocd-0.2.3-ubuntu64.tar.gz /opt + cd /opt + sudo tar -zxvf kendryte-openocd-0.2.3-ubuntu64.tar.gz + ``` + + - 修改配置文件 + + sudo vim /opt/kendryte-openocd/tcl/k210.cfg,并复制以下内容 + + ```shell + # SiPEED USB-JTAG/TTL + interface ftdi + ftdi_device_desc "Dual RS232" + ftdi_vid_pid 0x0403 0x6010 + ftdi_layout_init 0x0508 0x0f1b + ftdi_layout_signal nTRST -data 0x0200 -noe 0x0100 + ftdi_layout_signal nSRST -data 0x0800 -noe 0x0400 + + jtag_rclk 3000 + + # server port + gdb_port 9999 + telnet_port 4444 + + # add cpu target + set _CHIPNAME riscv + jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x04e4796b + + set _TARGETNAME $_CHIPNAME.cpu + target create $_TARGETNAME riscv -chain-position $_TARGETNAME + + # command + init + if {[ info exists pulse_srst]} { + ftdi_set_signal nSRST 0 + ftdi_set_signal nSRST 1 + ftdi_set_signal nSRST z + } + halt + ``` + +- 调试器和Max bit开发板的硬件连线 + + image-20221123220234259 + +- 启动调试器 + + ```shell + sudo /opt/kendryte-openocd/bin/openocd -f /opt/kendryte-openocd/tcl/k210.cfg + ``` + + image-20221123221828637 + +- 在Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210目录下,连接调试器 + + ```shell + /opt/xpack-riscv-none-embed-gcc-10.2.0-1.2/bin/riscv-none-embed-gdb rtthread.elf --eval-command="target remote 127.0.0.1:9999" + ``` + + - gdb终端调试 + + image-20221123222125802 + +image-20221123223127817 + +- vscode调试 + + image-20221123225705614 diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/SConscript b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/SConscript new file mode 100644 index 000000000..f4118ef8b --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/SConscript @@ -0,0 +1,26 @@ +from building import * + +# get current directory +cwd = GetCurrentDir() + +# the set of source files associated with this SConscript file. +src = Glob('src/common/*.cc') +src += Glob('src/execution/*.cc') +src += Glob('src/storage/*.cc') + +# compile optional modules +if GetDepend(['TABLE_STORAGE_CACHE']): + src += ['src/modules/prefetcher.cc'] +if GetDepend(['TABLE_STORAGE_CACHE']): + src += ['src/modules/queryCache.cc'] +if GetDepend(['TABLE_STORAGE_CACHE']): + src += ['src/modules/buffer.cc'] +if GetDepend(['TABLE_STORAGE_CACHE']): + src += ['src/modules/secondIndex.cc'] + +# include path +path = [cwd + '/include'] + +group = DefineGroup('TableStorage', src, depend = ['TABLE_STORAGE'], CPPPATH = path) + +Return('group') \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/BufferItem.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/BufferItem.h new file mode 100644 index 000000000..7ab6aa5dd --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/BufferItem.h @@ -0,0 +1,35 @@ +/** + * @file BufferItem.h + * @brief BufferItem + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef BUFFERITEM_H +#define BUFFERITEM_H + +#include + +#include "Common.h" + +namespace LightTable { + +class BufferItem { + public: + BufferItem(uint64_t tableID); + + virtual ~BufferItem(); + + // virtual void flush() const = 0; + + uint64_t getTableID() { return tableID; } + + protected: + uint64_t tableID; + DISALLOW_COPY_AND_ASSIGN(BufferItem); +}; + +} // namespace LightTable + +#endif // BUFFERITEM_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Common.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Common.h new file mode 100644 index 000000000..a23b31a74 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Common.h @@ -0,0 +1,144 @@ +/** + * @file Common.h + * @brief parameter configuration + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ +#ifndef COMMON_H +#define COMMON_H + +#include +#include + +#include +#include + +namespace LightTable { + +#define YCSB_TEST + +extern int cacheReadNum; +extern int cacheWriteNum; + +extern std::chrono::steady_clock::time_point start_time; +extern std::chrono::steady_clock::time_point end_time; +extern double diff_sdcard_read; +extern double diff_sdcard_write; + +#define SYSTEM_MAX_CORES 0 +#define SYSTEM_MAX_IO_QUEUES 8 + +#ifndef YCSB_TEST +#define NETWORK_MESSAGE_DATA_MAX_SIZE 4088 +#define NETWORK_TRANSMIT_MAX_SIZE 4096 +#else +#define NETWORK_MESSAGE_DATA_MAX_SIZE 51192 +#define NETWORK_TRANSMIT_MAX_SIZE 51200 +#endif + +#define SDCARD_TEST_WRITE_BLOCKID 200 +#define SDCARD_TEST_READ_BLOCKID 1000 +#define SDCARD_TEST_NUM 10000 + +#define HASH_BUCKET_SIZE 50 +#define CACHE_SIZE 500 + +#define SEGMENT_TYPE_SMALL_BITMAP_SIZE 32768 +#define SEGMENT_TYPE_MEDIUM_BITMAP_SIZE 4096 +#ifndef YCSB_TEST +#define SEGMENT_TYPE_BIG_BITMAP_SIZE 512 +#else +#define SEGMENT_TYPE_BIG_BITMAP_SIZE 512 +#endif + +#define SEGMENT_TYPE_SMALL_START 64 +#define SEGMENT_TYPE_MEDIUM_START 2097216 +#define SEGMENT_TYPE_BIG_START 6291528 + +#define SEGMENT_TYPE_SMALL_CELL_SIZE 4096 +#define SEGMENT_TYPE_MEDIUM_CELL_SIZE 65536 +#ifndef YCSB_TEST +#define SEGMENT_TYPE_BIG_CELL_SIZE 2097152 +#else +#define SEGMENT_TYPE_BIG_CELL_SIZE 65536000 +#endif + +#define PREFETCH_BLOCK_SERIALIZED_LENGTH 33 + +#define MAX_BRANCH_COUNT 4 + +#define PRELOAD_BLOCK_COUNT 10 +#define PRELOAD_CHECK_INTERVAL_US 50 + +#define BLOCK_SIZE 512 + +#ifndef YCSB_TEST +#define BUFFER_SIZE 200 +#else +#define BUFFER_SIZE 300000 +#endif + +#define CACHED_PAGE_COUNT 100 + +#define ROOTTABLE_TUPLE_SIZE sizeof(RootTable::TableTuple) + +#define TABLE_ID_SIZE sizeof(uint64_t) + +#define SYSTEM_TABLE_COUNT 1 +#define ROOTTABLE_TABLE_ID 1 +#define ROOTTABLE_SEGMENT_ID 1 +#define ROOTTABLE_FIRST_BLOCK_ID 14680164 + +#define TABLE1_META_BLOCKID 1000 +#define TABLE1_META_LOG_BLOCKID 10000 +#define TABLE1_INDEX_BLOCKID 2000 +#define TABLE1_INDEX_LOG_BLOCKID 20000 +#define TABLE1_DATA_LOG_BLOCKID 30000 +#define META_ENTRY_NUM 8 +#define META_ENTRY_SIZE 64 +#define BUFFER_MAX 4096 +#define COMMON_TABLE_START_ID 101 +#define YCSB_TABLE_ID 100 +#define TABLE_NAME_LENGTH 32 +#define PRIMARY_KEY_LENGTH 128 +#define FILE_PATH_LENGTH 1024 +#define FILE_NAME_LENGTH 128 +#define USER_NAME_LENGTH 32 +#define COLUMN_NAME_LENGTH 128 +#define COLUMN_TYPE_NAME_LENGTH 32 + +#define PREFETCH_BLOCK_SERIALIZED_LENGTH 33 +#define ROWMAP_SERIALIZED_LENGTH 42 +#define SCHEMA_ENTRY_SERIALIZED_LENGTH 181 + +#define MAX_META_LENGTH 2048 + +#define MAX_PATH_LENGTH 128 +const char METAPATH[MAX_PATH_LENGTH] = "../../data"; + +struct timespec diff(struct timespec start, struct timespec end); + +class Queue { + public: +#ifdef IO_PROFILING + static struct timespec accumulate_io_times(); + static struct timespec accumulate_io_submit_times(); +#endif + +#ifdef IO_PROFILING + static std::queue io_times; + static std::queue io_submit_times; +#endif +}; + +// A macro to disallow the copy constructor and operator= functions +#ifndef DISALLOW_COPY_AND_ASSIGN +#define DISALLOW_COPY_AND_ASSIGN(TypeName) \ + TypeName(const TypeName &) = delete; \ + TypeName &operator=(const TypeName &) = delete; +#endif + +} // namespace LightTable + +#endif // COMMON_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/CommonTable.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/CommonTable.h new file mode 100644 index 000000000..bfc111259 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/CommonTable.h @@ -0,0 +1,35 @@ +/** + * @file CommonTable.h + * @brief CommonTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef COMMONTABLE_H +#define COMMONTABLE_H + +#include "Table.h" + +namespace LightTable { + +class CommonTable : public Table { + public: + CommonTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + std::vector schemaEntrys, + bool usePrimaryKeyIndex = false); + + CommonTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + bool usePrimaryKeyIndex = false); + + friend class MetaHandle; + + protected: + DISALLOW_COPY_AND_ASSIGN(CommonTable); +}; + +} // namespace LightTable + +#endif // COMMONTABLE_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Driver.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Driver.h new file mode 100644 index 000000000..03d1f2945 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Driver.h @@ -0,0 +1,61 @@ +/** + * @file Driver.h + * @brief driver + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ +#ifndef DRIVER_H +#define DRIVER_H + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "Common.h" +#include "Error.h" + +// #include +// #include +// #include + +#ifdef __cplusplus +extern "C" { +#endif +uint32_t MakeTableStorage(const char *device_name); +#ifdef __cplusplus +} +#endif + +namespace LightTable { + +class Driver { + public: + static uint32_t driver_init(const char *device_name); + + static void driver_cleanup(const char *device_name); + + static uint32_t driver_read(uint8_t *buf, uint64_t blockID); + + static uint32_t driver_write(uint8_t *buf, uint64_t blockID); + + static uint32_t read(uint8_t *buf, uint64_t blockID); + + static uint32_t write(uint8_t *buf, uint64_t blockID); + + Driver(){}; + +#ifdef TABLE_STORAGE_CACHE + static BlockCache *blkCache; +#endif +}; + +} // namespace LightTable + +#endif // DRIVER_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Error.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Error.h new file mode 100644 index 000000000..14fceb967 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Error.h @@ -0,0 +1,62 @@ +/** + * @file Error.h + * @brief error number + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef ERROR_H +#define ERROR_H + +namespace LightTable { + +enum ErrorCode { + SUCCESS = 0, + ERROR_TABLE = 1, + SEGMENT_TYPE_ERROR = 2, + SEGMENT_STATUS_ERROR = 3, + SEGMENT_IS_EXHAUSTED = 4, + BUCKET_ITEM_NOT_FOUND = 5, + ADD_BUCKET_ITEM_ERROR = 6, + PREFETCH_BLOCK_NOT_FOUND = 7, + GET_AVAILABLE_BLOCK_ERROR = 8, + BLOCK_OCCUPIED = 9, + ADD_ROW_MAP_ENTRY_ERROR = 10, + ROW_MAP_ENTRY_NOT_FOUND = 11, + ADD_SCHEMA_ENTRY_ERROR = 12, + SCHEMA_ENTRY_NOT_FOUND = 13, + COLUMN_ITEM_NOT_FOUND = 14, + COLUMN_ID_NOT_CONTINUOUS = 15, + DELETE_PARIMARY_KEY_COLUMN = 16, + TABLE_NOT_FOUND = 17, + TABLE_TUPLE_NOT_FOUND = 18, + ADD_TABLE_TUPLE_ERROR = 19, + BUFFER_EMPTY = 20, + TYPE_INVALID = 21, + ROWLOCATION_INVALID = 22, + CREATE_SOCKET_ERROR = 23, + INET_PTON_ERROR = 24, + BIND_SOCKET_ERROR = 25, + LISTEN_SOCKET_ERROR = 26, + ACCEPT_SOCKET_ERROR = 27, + CONNECT_SOCKET_ERROR = 28, + SEND_MESSAGE_ERROR = 29, + EVENT_TYPE_NOT_DEFINED = 30, + SCHEMA_NOT_EXIST = 31, + OPEN_META_FILE_ERROR = 32, + INVALID_META_FILE = 33, + INVALID_MEMORY_BLOCK_ID = 34, + UPDATE_TUPLE_ERROR = 35, + INVALID_PAGE_ID = 36, + ADD_QUERY_CACHE_ERROR = 37, + TRIE_LEAF_EXIST = 38, + TRIE_LEAF_NOT_EXIST = 39, + TRIE_LEAF_NOT_FOUND = 40, + INVALID_SCAN_RANGE = 41, + INVALID_PRELOAD_TASK = 42, +}; + +} // namespace LightTable + +#endif // ERROR_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/HashBucket.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/HashBucket.h new file mode 100644 index 000000000..620da30f2 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/HashBucket.h @@ -0,0 +1,59 @@ +/** + * @file HashBucket.h + * @brief HashBucket + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef HASHBUCKET_H +#define HASHBUCKET_H + +#include +// #include + +#include +#include +#include +#include +// #include + +#include "Common.h" +#include "Error.h" + +namespace LightTable { + +typedef struct rowLocation { + uint64_t blockID; + uint64_t rowOffset; +} RowLocation; + +class HashBucket { + public: + HashBucket(); + + uint32_t addBucketItem(uint64_t key, RowLocation rowLocation); + + uint32_t deleteBucketItem(uint64_t key); + + uint32_t updateRowLocation(uint64_t key, RowLocation rowLocation); + + uint32_t getRowLocation(uint64_t key, RowLocation &rowLocation); + + uint64_t getBucketSize(); + + uint32_t setBucketSize(uint64_t bucketSize); + + uint32_t getAllBucketItems(std::map &bucketItems); + + private: + std::map bucketItems; + uint64_t bucketSize; + // pthread_mutex_t mtx; + + DISALLOW_COPY_AND_ASSIGN(HashBucket); +}; + +} // namespace LightTable + +#endif // HASHBUCKET_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/HashTable.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/HashTable.h new file mode 100644 index 000000000..35cc73445 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/HashTable.h @@ -0,0 +1,63 @@ +/** + * @file HashTable.h + * @brief HashTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef HASHTABLE_H +#define HASHTABLE_H + +#include + +#include +#include +#include +#include + +#include "Common.h" +#include "HashBucket.h" + +namespace LightTable { + +class HashTable { + public: + HashTable(); + + ~HashTable(); + + uint64_t getMapKey(const char *primaryKey); + + uint32_t hashToBucket(uint64_t key); + + uint32_t getRowLocation(uint32_t bucketID, uint64_t key, + RowLocation &rowLocation); + + uint32_t addItem(uint32_t bucketID, uint64_t key, RowLocation rowLocation); + + uint32_t deleteItem(uint32_t bucketID, uint64_t key); + + uint32_t updateItem(uint32_t bucketID, uint64_t key, RowLocation rowLocation); + + uint64_t getItemCount(); + + uint32_t getAllBuckets(std::vector &buckets); + uint32_t refreshRowLocations(uint64_t blockID, uint64_t deleteOffset, + uint64_t rowSize, + std::map &locationItems); + + uint32_t clear(); + + private: + std::vector buckets; + + DISALLOW_COPY_AND_ASSIGN(HashTable); + + public: + friend class MetaHandle; +}; + +} // namespace LightTable + +#endif // HASHTABLE_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/PrefetchBlockManager.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/PrefetchBlockManager.h new file mode 100644 index 000000000..7b4ec20f8 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/PrefetchBlockManager.h @@ -0,0 +1,101 @@ +/** + * @file PrefetchBlockManager.h + * @brief PrefetchBlockManager + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef PREFETCHBLOCKMANAGER_H +#define PREFETCHBLOCKMANAGER_H + +#include +#include +#include +// #include + +#include +#include +#include +#include +#include +// #include + +#include "Error.h" +#include "Common.h" +#include "SegmentManager.h" + +namespace LightTable +{ + +enum PrefetchBlockStatus +{ + PREFETCH_BLOCK_STATUS_IDLE = 0, + PREFETCH_BLOCK_STATUS_BUSY, +}; + +class PrefetchBlockManager +{ + public: + + typedef struct prefetchBlockManagerEntry + { + uint64_t blockID; + uint64_t currentOffset; + bool isOccupied; + bool isCached; + uint64_t pageID; + }PrefetchBlockManagerEntry; + + PrefetchBlockManager(uint64_t firstBlockID, uint64_t segmentID, + SegmentType segmentType); + + ~PrefetchBlockManager(); + + uint64_t blockAllocate(uint64_t rowSize); + + uint64_t getNextBlock(); + + uint32_t setBlockState(uint64_t blockID, bool isOccupied); + + uint32_t setOffset(uint64_t blockID, uint64_t currentOffset); + + uint32_t getOffset(uint64_t blockID, uint64_t ¤tOffset); + + uint32_t advanceOffset(uint64_t blockID, uint64_t rowSize); + + uint32_t isOccupied(uint64_t blockID, bool &status); + + uint32_t getPrefetchBlockEntry(uint64_t blockID, + PrefetchBlockManagerEntry &entry); + + uint32_t getAllPrefetchBlockEntrys(std::map &entrys); + + uint32_t lockBlock(uint64_t blockID); + + uint32_t unlockBlock(uint64_t blockID); + + uint32_t setIsCached(uint64_t blockID, bool isCached, uint64_t pageID); + + bool isCached(uint64_t blockID, uint64_t &pageID); + + private: + std::map prefetchBlocks; + + const uint64_t segmentID; + const SegmentType segmentType; + const uint64_t firstBlockID; + uint64_t blockCount; + uint64_t currentID; + + DISALLOW_COPY_AND_ASSIGN(PrefetchBlockManager); + + public: + friend class QueryCache; + friend class MetaHandle; +}; + +} // namespace LightTable + +#endif // PREFETCHBLOCKMANAGER_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RWLock.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RWLock.h new file mode 100644 index 000000000..1f576b5a3 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RWLock.h @@ -0,0 +1,57 @@ +/** + * @file RWLock.h + * @brief RWLock + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ +#ifndef RWLOCK_H +#define RWLOCK_H + +#include +#include + +#include + +namespace LightTable { + +using version_lock_t = uint8_t; +#define LOAD_ORDER std::memory_order_acquire +#define STORE_ORDER std::memory_order_release + +static_assert(sizeof(version_lock_t) == 1, "Lock must be 1 byte."); +static constexpr version_lock_t CLIENT_BIT = 0b10000000; +static constexpr version_lock_t NO_CLIENT_BIT = 0b01111111; +static constexpr version_lock_t USED_BIT = 0b01000000; +static constexpr version_lock_t UNLOCKED_BIT = 0b11111110; + +#define IS_LOCKED(lock) ((lock)&1) + +class RWLock { + std::atomic version_lock; + + public: + bool lock(const bool blocking = true) { + version_lock_t lock_value = version_lock.load(LOAD_ORDER); + // Compare and swap until we are the thread to set the lock bit + lock_value &= UNLOCKED_BIT; + while (!version_lock.compare_exchange_weak(lock_value, lock_value + 1)) { + lock_value &= UNLOCKED_BIT; + if (!blocking) { + return false; + } + } + return true; + } + + void unlock() { + const version_lock_t current_version = version_lock.load(LOAD_ORDER); + version_lock_t new_version = (current_version + 1) % USED_BIT; + new_version |= USED_BIT; + new_version |= (current_version & CLIENT_BIT); + version_lock.store(new_version, STORE_ORDER); + } +}; +} // namespace LightTable + +#endif // HASHTABLE_H \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RootTable.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RootTable.h new file mode 100644 index 000000000..8c2476635 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RootTable.h @@ -0,0 +1,75 @@ +/** + * @file RootTable.h + * @brief RootTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef ROOTTABLE_H +#define ROOTTABLE_H + +#include +#include + +#include +#include +#include + +#include "Common.h" +#include "SystemTable.h" + +namespace LightTable { + +class Buffer; + +class RootTable : public SystemTable { + public: + typedef struct tableTuple { + uint64_t tableID; + char tableName[TABLE_NAME_LENGTH]; + uint64_t firstBlockID; + uint64_t segmentID; + SegmentType segmentType; + char user[USER_NAME_LENGTH]; + struct tm time; + } TableTuple; + + RootTable(std::vector schemaEntrys, + bool usePrimaryKeyIndex) + : SystemTable(ROOTTABLE_TABLE_ID, "RootTable", ROOTTABLE_FIRST_BLOCK_ID, + ROOTTABLE_SEGMENT_ID, SEGMENT_TYPE_BIG, schemaEntrys, + usePrimaryKeyIndex) {} + + RootTable(bool usePrimaryKeyIndex = false); + + uint32_t tableNameToTableID(const char *tableName, uint64_t &tableID); + + uint32_t deleteTableInfo(uint64_t tableID); + + uint32_t appendTableInfo(TableTuple tableTuple); + + uint32_t getTableInfo(uint64_t tableID, TableTuple &tableTupleResult); + + uint32_t modifyTableInfo(uint64_t tableID, TableTuple tableTuple); + + uint32_t getTableTuple(uint64_t tableID, TableTuple &tableTuple); + + uint32_t serializeRow(const TableTuple tableTuple, uint8_t *buf); + + uint32_t deserializeRow(const uint8_t *buf, TableTuple *tableTuple); + + uint64_t getTableCount(); + + private: + std::map tableTupleMap; + + DISALLOW_COPY_AND_ASSIGN(RootTable); + + public: + friend class MetaHandle; +}; + +} // namespace LightTable + +#endif // ROOTTABLE_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RowMap.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RowMap.h new file mode 100644 index 000000000..4a14280c3 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/RowMap.h @@ -0,0 +1,57 @@ +/** + * @file RowMap.h + * @brief + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef ROWMAP_H +#define ROWMAP_H + +#include + +#include +#include +#include +#include + +#include "Common.h" +#include "Error.h" + +namespace LightTable { + +class RowMap { + public: + typedef struct rowMapEntry { + uint64_t key; + uint64_t blockID; + uint64_t rowOffset; + } RowMapEntry; + + RowMap(); + + uint32_t appendEntry(uint64_t key, uint64_t blockID, uint64_t rowOffset); + + uint32_t deleteEntry(uint64_t key); + + uint32_t alterEntry(uint64_t key, uint64_t blockID, uint64_t rowOffset); + + uint32_t queryEntry(uint64_t key, RowMapEntry &rowMapEntry); + + uint32_t queryAllEntry(std::map &allRowMapEntrys); + + uint64_t getRowCount(); + + private: + std::map rowMapEntrys; + + DISALLOW_COPY_AND_ASSIGN(RowMap); + + public: + friend class MetaHandle; +}; + +} // namespace LightTable + +#endif // ROWMAP_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Schema.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Schema.h new file mode 100644 index 000000000..051fde538 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Schema.h @@ -0,0 +1,92 @@ +/** + * @file Schema.h + * @brief table schema + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef SCHEMA_H +#define SCHEMA_H + +#include +#include + +#include +#include +#include +#include + +#include "Common.h" +#include "Error.h" + +namespace LightTable { + +class Schema { + public: + typedef struct schemaEntry { + uint64_t columnID; + char columnName[COLUMN_NAME_LENGTH]; + char type[COLUMN_TYPE_NAME_LENGTH]; + uint32_t length; + bool isPrimaryKey; + bool isEmpty; + + schemaEntry &operator=(schemaEntry &another) { + this->columnID = another.columnID; + memcpy(this->columnName, another.columnName, COLUMN_NAME_LENGTH); + memcpy(this->type, another.type, COLUMN_TYPE_NAME_LENGTH); + this->length = another.length; + this->isPrimaryKey = another.isPrimaryKey; + this->isEmpty = another.isEmpty; + + return *this; + } + + } SchemaEntry; + + Schema(); + + Schema(std::vector schemaEntrys); + + uint32_t appendEntry(SchemaEntry &schemaEntry); + + uint32_t deleteEntry(uint64_t columnID); + + uint32_t alterEntry(uint64_t columnID, SchemaEntry schemaEntry); + + uint32_t getColumnID(const char *columnName, uint64_t &columnID); + + uint32_t queryEntry(uint64_t columnID, Schema::SchemaEntry &schemaEntry); + + uint32_t queryAllEntry(std::map &allSchemaEntrys); + + uint64_t getEntrySize(); + + void setEntrySize(uint64_t entrySize); + + uint32_t getPrimaryKeyLength(); + + uint64_t getColumnCount(); + + void setColumnCount(uint64_t columnCount); + + Schema::SchemaEntry &getPrimaryKeySchema(); + + uint32_t drop(); + + private: + std::map schemaEntrys; + SchemaEntry primaryKeySchema; + uint64_t columnCount; + uint64_t entrySize; + + DISALLOW_COPY_AND_ASSIGN(Schema); + + public: + friend class MetaHandle; +}; + +} // namespace LightTable + +#endif // SCHEMA_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/SegmentManager.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/SegmentManager.h new file mode 100644 index 000000000..740329779 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/SegmentManager.h @@ -0,0 +1,59 @@ +/** + * @file SegmentManager.h + * @brief SegmentManager + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef SEGMENTMANAGER_H +#define SEGMENTMANAGER_H + +#include + +#include "Common.h" +#include "Error.h" +#include "Driver.h" +#include "Common.h" + +namespace LightTable { + +enum SegmentType { + SEGMENT_TYPE_SMALL = 101, + SEGMENT_TYPE_MEDIUM, + SEGMENT_TYPE_BIG, +}; + +enum SegmentStatus { + SEGMENT_STATUS_IDLE = 0, + SEGMENT_STATUS_BUSY, +}; + +class SegmentManager { + public: + SegmentManager(); + ~SegmentManager(); + + uint32_t setBitmap(SegmentType segmentType, uint64_t segmentID, + SegmentStatus segmentStatus); + + uint32_t getIdleSegment(SegmentType segmentType, uint64_t &segmentID, + uint64_t &firstBlockID); + + private: + uint32_t setBit(uint64_t segmentID, uint8_t *buf, uint64_t segmentStart, + SegmentStatus segmentStatus); + + uint32_t findFirstIdle(uint8_t *buf, uint64_t segmentNum, + uint64_t &segmentID); + + uint8_t *bigBitmap; + uint8_t *mediumBitmap; + uint8_t *smallBitmap; + + DISALLOW_COPY_AND_ASSIGN(SegmentManager); +}; + +} // namespace LightTable + +#endif // SEGMENTMANAGER_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/SystemTable.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/SystemTable.h new file mode 100644 index 000000000..d3f19b360 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/SystemTable.h @@ -0,0 +1,33 @@ +/** + * @file SystemTable.h + * @brief SystemTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef SYSTEMTABLE_H +#define SYSTEMTABLE_H + +#include "Table.h" + +namespace LightTable { + +class SystemTable : public Table { + public: + SystemTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + std::vector schemaEntrys, + bool usePrimaryKeyIndex); + + SystemTable(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + bool usePrimaryKeyIndex); + + protected: + DISALLOW_COPY_AND_ASSIGN(SystemTable); +}; + +} // namespace LightTable + +#endif // SYSTEMTABLE_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Table.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Table.h new file mode 100644 index 000000000..17d906f99 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/Table.h @@ -0,0 +1,147 @@ +/** + * @file Table.h + * @brief Table + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef TABLE_H +#define TABLE_H + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "Common.h" +#include "HashTable.h" +#include "RowMap.h" +#include "Schema.h" +#include "Driver.h" +#include "UndoLogEntry.h" +#include "SegmentManager.h" +#include "PrefetchBlockManager.h" + +namespace LightTable { +#ifdef TABLE_STORAGE_SECOND_INDEX + // TODO: second index +#endif + +class Buffer; + +class Table { + typedef struct currentLocation { + uint64_t blockID; + int32_t emptySlotNum; + } currentLocation; + + typedef struct metaLogEntry { + uint64_t tableID; + uint64_t tupleNum; + std::time_t t; + } metaLogEntry; + + public: + Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + std::vector schemaEntrys, + bool usePrimaryKeyIndex = false); + + Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + bool usePrimaryKeyIndex = false); + + uint32_t drop(); + + uint32_t truncate(); + + uint32_t insertRow(const uint8_t *rowData); + + uint32_t insertRow_logging(const uint8_t *rowData); + + uint32_t deleteRow(const char *primaryKey); + + uint32_t updateRow(const char *primaryKey, const uint8_t *rowData); + + uint32_t updateColumnItem(const char *primaryKey, const char *columnName, + const uint8_t *columnData); + + uint32_t updateColumnItem_logging(const char *primaryKey, + const char *columnName, + const uint8_t *columnData); + + uint32_t selectRow(const char *primaryKey, uint8_t *rowData); + + uint32_t selectColumnItem(const char *primaryKey, const char *columnName, + uint8_t *columnData); + + uint64_t getRowCount(); + + uint64_t getTableID(); + + char *getTableName(); + + uint32_t setTableID(uint64_t tableID); + + uint32_t setTableName(const char *tableName); + + Schema &getSchema(); + + HashTable &getHashTable(); + + protected: + uint32_t getColumnID(const char *columnName, uint64_t &columnID); + + uint32_t parsePrimaryKey(const uint8_t *rowData, char *primaryKeyData); + + uint32_t locateRow(const char *primaryKey, RowLocation &rowLocation); + + uint32_t getRowFromBlock(const char *primaryKey, uint8_t *rowData, + const uint8_t *blockData, + const RowLocation rowLocation); + + uint32_t selectRow(const char *primaryKey, uint8_t *rowData, + RowLocation &rowLocation); + + uint32_t deleteRowData(uint64_t key, RowLocation rowLocation); + + uint32_t getColumnOffset(const char *columnName, uint64_t &columnID, + uint32_t &columnLength, uint64_t &offset); + + uint64_t tableID; + char tableName[TABLE_NAME_LENGTH]; + Schema schema; + RowMap rowMap; + HashTable hashTable; + bool usePrimaryKeyIndex; + uint64_t tupleNum; + std::time_t t; + currentLocation indexLocation; + currentLocation metaLogLocation; + currentLocation indexLogLocation; + currentLocation dataLogLocation; + uint8_t indexData[BLOCK_SIZE]; + uint8_t metaData[BLOCK_SIZE]; + uint8_t metaLog[BLOCK_SIZE]; + uint8_t indexLog[BLOCK_SIZE]; + uint8_t dataLog[BLOCK_SIZE]; + PrefetchBlockManager prefetchBlockManager; + + DISALLOW_COPY_AND_ASSIGN(Table); + + public: + friend class DaemonProcess; + friend class MetaHandle; + friend class QueryCache; +}; + +} // namespace LightTable + +#endif // TABLE_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/TableStorage.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/TableStorage.h new file mode 100644 index 000000000..d81d14082 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/TableStorage.h @@ -0,0 +1,145 @@ +/** + * @file TableStorage.h + * @brief TableStorage + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef DAEMONPROCESS_H +#define DAEMONPROCESS_H + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +// #include +// #include +// #include +// #include +// #include + +#include "RootTable.h" +#include "SegmentManager.h" +#include "Common.h" +#include "CommonTable.h" +#include "Error.h" +#include "Driver.h" +#include "Table.h" + +#define TABLE_DEBUG_ENABLE +#define PROJECT_NAME "TanleStorage" + +#ifndef TABLE_PRINT +#define TABLE_PRINT(...) printf(__VA_ARGS__) +#endif +#define TABLE_LOG_PREFIX1() \ + TABLE_PRINT("[\e[1;34m%s\033[0m] \e[1;31m%s\033[0m", PROJECT_NAME, \ + __FUNCTION__) +#define TABLE_LOG_PREFIX2() TABLE_PRINT(" ") +#define TABLE_LOG_PREFIX() \ + TABLE_LOG_PREFIX1(); \ + TABLE_LOG_PREFIX2() + +#ifdef TABLE_DEBUG_ENABLE +#define TABLE_DEBUG(...) \ + TABLE_LOG_PREFIX(); \ + TABLE_PRINT("(\e[1;32m%s:%d\033[0m) ", __FILE__, __LINE__); \ + TABLE_PRINT(__VA_ARGS__) +#else +#define TABLE_DEBUG(...) +#endif + +namespace LightTable { + +enum EventType { + CREATE_TABLE_EVENT = 10001, + INSERT_ROW_EVENT, + DELETE_ROW_EVENT, + SELECT_ROW_EVENT, +#ifdef YCSB_TEST + SCAN_EVENT, +#endif + UPDATE_ROW_EVENT, +#ifdef YCSB_TEST + UPDATE_COLUMNS_EVENT, +#endif + DROP_TABLE_EVENT, + RESPOND_CLIENT_REQUEST, + STOP_SERVICE_EVENT, +#ifdef YCSB_TEST + UNKNOWN_EVENT, +#endif +}; + +typedef struct message { + uint32_t size; + EventType eventType; + uint8_t data[NETWORK_MESSAGE_DATA_MAX_SIZE]; +} Message; + +class TableStorage { + public: + static TableStorage *getInstance(const char *ipAddress, + const uint32_t portNum, + const char *path = METAPATH) { + static TableStorage *daemonProcess; + + // To determine whether the first call. + if (daemonProcess == NULL) { + daemonProcess = new TableStorage(ipAddress, portNum, path); + } + + return daemonProcess; + } + + uint32_t createTable(const char *tableName, SegmentType segmentType, + std::vector &schema); + + uint32_t dropTable(const char *tableName); + + uint32_t insertTuple(const char *tableName, const uint8_t *row); + + uint32_t deleteTuple(const char *tableName, const char *primaryKey); + + uint32_t updateTuple(const char *tableName, const char *primaryKey, + const char *columnName, const uint8_t *value); + + uint32_t selectTuple(const char *tableName, const char *primaryKey, + uint8_t *row); + + uint32_t initTableStorage(); + uint32_t closeTableStorage(); + + private: + TableStorage(const char *ipAddress, const uint32_t portNum, const char *path); + ~TableStorage(); + + RootTable *rootTable; + std::map tableMap; + SegmentManager *segmentManager; + const char *LightTableIPAddress; + const uint32_t LightTablePortNum; + + // int32_t socketfd; + // MetaHandle metaHandle; + // Buffer *buf; + // QueryCache *queryCache; + // BlockPreload *blockPreload; + + friend class Benchmark; +}; + +} // namespace LightTable + +#endif // DAEMONPROCESS_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/ThreadSafeQueue.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/ThreadSafeQueue.h new file mode 100644 index 000000000..5ad130b6f --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/ThreadSafeQueue.h @@ -0,0 +1,81 @@ +/** + * @file ThreadSafeQueue.h + * @brief ThreadSafeQueue + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include + +#include + +#include "Common.h" + +using namespace std; + +namespace LightTable { + +template +class ThreadSafeQueue { + private: + pthread_mutex_t m_lock; + int m_front; + int m_rear; + object m_data[BUFFER_SIZE]; + + public: + ThreadSafeQueue() : m_front(0), m_rear(0) { + pthread_mutex_init(&m_lock, NULL); + } + + bool EnQueue(object data) { + pthread_mutex_lock(&m_lock); + if (isFull()) { + // cout<<"The queue is full!"< + +#include "BufferItem.h" +#include "Common.h" +#include "Error.h" + +namespace LightTable { + +class UndoLogEntry : public BufferItem { + public: + UndoLogEntry(uint64_t tableID, const char *primaryKey, uint64_t keySize, + char *tuple, uint64_t tupleSize, uint64_t blockID, + uint64_t offset); + + static bool getIsExpired(UndoLogEntry *logEntry); + void expireUndoLog(); + + uint32_t getTuple(uint64_t tableID, const char *primaryKey, char *tuple, + uint64_t &blockID, uint64_t &offset); + + char *getPrimaryKey(); + + ~UndoLogEntry(); + + private: + char *tuple; + char *primaryKey; + uint64_t blockID; + uint64_t offset; + uint64_t tupleSize; + uint64_t keySize; + bool isExpired; + DISALLOW_COPY_AND_ASSIGN(UndoLogEntry); +}; + +} // namespace LightTable + +#endif // UNDOLOGENTRY_H diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/integer.h b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/integer.h new file mode 100644 index 000000000..51b560b35 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/include/integer.h @@ -0,0 +1,41 @@ +/** + * @file integer.h + * @brief integer + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#ifndef _FF_INTEGER +#define _FF_INTEGER + +#ifdef _WIN32 /* FatFs development platform */ + +#include +#include +typedef unsigned __int64 QWORD; + +#else /* Embedded platform */ + +/* These types MUST be 16-bit or 32-bit */ +typedef int INT; +typedef unsigned int UINT; + +/* This type MUST be 8-bit */ +typedef unsigned char BYTE; + +/* These types MUST be 16-bit */ +typedef short SHORT; +typedef unsigned short WORD; +typedef unsigned short WCHAR; + +/* These types MUST be 32-bit */ +typedef long LONG; +typedef unsigned long DWORD; + +/* This type MUST be 64-bit (Remove this for C89 compatibility) */ +typedef unsigned long long QWORD; + +#endif + +#endif diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123213344406.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123213344406.png new file mode 100644 index 000000000..d84f32b7c Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123213344406.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215143184.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215143184.png new file mode 100644 index 000000000..9cce6c818 Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215143184.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215509060.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215509060.png new file mode 100644 index 000000000..0e65521af Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215509060.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215723700.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215723700.png new file mode 100644 index 000000000..00d9c63ce Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215723700.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215939427.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215939427.png new file mode 100644 index 000000000..8ce855731 Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123215939427.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123220234259.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123220234259.png new file mode 100644 index 000000000..7250d5b6e Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123220234259.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123221828637.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123221828637.png new file mode 100644 index 000000000..2cde14d8b Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123221828637.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123222125802.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123222125802.png new file mode 100644 index 000000000..448670d67 Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123222125802.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123223127817.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123223127817.png new file mode 100644 index 000000000..42b8c8164 Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123223127817.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123225705614.png b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123225705614.png new file mode 100644 index 000000000..c8dea4253 Binary files /dev/null and b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/pic/image-20221123225705614.png differ diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Common.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Common.cc new file mode 100644 index 000000000..e3d1d3d77 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Common.cc @@ -0,0 +1,80 @@ +/** + * @file Common.cc + * @brief Common + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "Common.h" + +namespace LightTable { + +int cacheReadNum = 0; +int cacheWriteNum = 0; + +std::chrono::steady_clock::time_point start_time = + std::chrono::steady_clock::now(); +std::chrono::steady_clock::time_point end_time = + std::chrono::steady_clock::now(); +double diff_sdcard_read = 0.0; +double diff_sdcard_write = 0.0; + +struct timespec diff(struct timespec start, struct timespec end) { + struct timespec temp; + if ((end.tv_nsec - start.tv_nsec) < 0) { + temp.tv_sec = end.tv_sec - start.tv_sec - 1; + temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec - start.tv_sec; + temp.tv_nsec = end.tv_nsec - start.tv_nsec; + } + return temp; +} + +#ifdef IO_PROFILING +std::queue Queue::io_times; +std::queue Queue::io_submit_times; +#endif + +#ifdef IO_PROFILING +struct timespec Queue::accumulate_io_times() { + struct timespec sum; + sum.tv_sec = 0; + sum.tv_nsec = 0; + + while (!io_times.empty()) { + sum.tv_sec += io_times.front().tv_sec; + if (1000000000 <= sum.tv_nsec + io_times.front().tv_nsec) { + sum.tv_sec++; + sum.tv_nsec = sum.tv_nsec + io_times.front().tv_nsec - 1000000000; + } else { + sum.tv_nsec += io_times.front().tv_nsec; + } + io_times.pop(); + } + + return sum; +} + +struct timespec Queue::accumulate_io_submit_times() { + struct timespec sum; + sum.tv_sec = 0; + sum.tv_nsec = 0; + + while (!io_submit_times.empty()) { + sum.tv_sec += io_submit_times.front().tv_sec; + if (1000000000 <= sum.tv_nsec + io_submit_times.front().tv_nsec) { + sum.tv_sec++; + sum.tv_nsec = sum.tv_nsec + io_submit_times.front().tv_nsec - 1000000000; + } else { + sum.tv_nsec += io_submit_times.front().tv_nsec; + } + io_submit_times.pop(); + } + + return sum; +} +#endif + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Driver.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Driver.cc new file mode 100644 index 000000000..2774936a4 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Driver.cc @@ -0,0 +1,92 @@ +/** + * @file Driver.cc + * @brief Driver + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "Driver.h" + +extern "C" { + #include "ff.h" + #include "ffconf.h" + + #include + #include +} + +/* Definitions of physical drive number for each drive */ +#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */ +#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */ +#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */ + +static rt_device_t disk[FF_VOLUMES] = {0}; + +namespace LightTable { + +uint32_t Driver::write(uint8_t *buf, uint64_t blockID) { + rt_size_t result; + rt_device_t device = disk[0]; + +#ifdef TABLE_STORAGE_CACHE + // TODO: cache +#endif + + if (rt_device_write(device, blockID, buf, 1) == 1) + return RES_OK; + else + return RES_ERROR; +} + +uint32_t Driver::read(uint8_t *buf, uint64_t blockID) { + rt_size_t result; + rt_device_t device = disk[0]; + +#ifdef TABLE_STORAGE_CACHE + // TODO: cache +#endif + + if (rt_device_read(device, blockID, buf, 1) == 1) { + return RES_OK; + } + + return RES_OK; +} + +void Driver::driver_cleanup(const char *device_name) { + /* clean device */ + return; +} + +uint32_t Driver::driver_init(const char *device_name) { + /* init device */ + /* note: initialization of the device is done at the MakeTableStorage*/ + return 0; +} +} // namespace LightTable + +uint32_t MakeTableStorage(const char *device_name) { + rt_device_t dev_id; + + /* open specific device */ + if (device_name == NULL) { + /* which is a non-device filesystem mount */ + dev_id = NULL; + } else if ((dev_id = rt_device_find(device_name)) == NULL) { + /* no this device */ + rt_set_errno(-ENODEV); + return -1; + } + + /* open device, but do not check the status of device */ + if (dev_id != NULL) { + if (rt_device_open(dev_id, RT_DEVICE_OFLAG_RDWR) != RT_EOK) { + return -1; + } + } + + disk[0] = dev_id; + + return 0; +} diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Makefile b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Makefile new file mode 100644 index 000000000..c5b1f927f --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/common/Makefile @@ -0,0 +1,22 @@ +ifndef LIGHTTABLE_DIR +LIGHTTABLE_DIR = ../.. +endif + +SRC_FILES := $(wildcard *.cc) +INCLUDE_DIR = -I$(LIGHTTABLE_DIR)/src -I. -I$(LIGHTTABLE_DIR)/spdk/include + +SOURCE_FOR_CC = $(foreach source_file_1, $(SOURCES),$(filter %.cc, $(source_file_1))) + +CXXFLAGS += -Werror -fno-omit-frame-pointer -Wall -Wextra -Wno-unused-parameter \ + -Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing \ + $(INCLUDE_DIR) -Wformat -Wformat-security -D_GNU_SOURCE \ + -fPIC -fno-stack-protector -fno-common -DNDEBUG -U_FORTIFY_SOURCE \ + -D_FORTIFY_SOURCE=2 -std=c++11 + +CXXFLAGS += -DYCSB_TEST + +CXXFLAGS += -Wl,-z,relro,-z,now -Wl,-z,noexecstack -lpthread -Wl,-z,relro,-z,now \ + -Wl,-z,noexecstack \ + -Wl,--whole-archive -Wl,--no-whole-archive + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/BufferItem.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/BufferItem.cc new file mode 100644 index 000000000..fa2de2f8b --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/BufferItem.cc @@ -0,0 +1,17 @@ +/** + * @file BufferItem.cc + * @brief BufferItem + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "BufferItem.h" + +namespace LightTable { + +BufferItem::BufferItem(uint64_t tableID) : tableID(tableID) {} + +BufferItem::~BufferItem() {} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/Makefile b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/Makefile new file mode 100644 index 000000000..1e1a1c1f4 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/Makefile @@ -0,0 +1,23 @@ +ifndef LIGHTTABLE_DIR +LIGHTTABLE_DIR = ../.. +endif + +SRC_FILES := $(wildcard *.cc) +INCLUDE_DIR = -I$(LIGHTTABLE_DIR)/src -I. + +SOURCE_FOR_CC = $(foreach source_file_1, $(SOURCES),$(filter %.cc, $(source_file_1))) + +CXXFLAGS += -Werror -fno-omit-frame-pointer -Wall -Wextra -Wno-unused-parameter \ + -Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing \ + $(INCLUDE_DIR) -Wformat -Wformat-security -D_GNU_SOURCE \ + -fPIC -fno-stack-protector -fno-common -DNDEBUG -U_FORTIFY_SOURCE \ + -D_FORTIFY_SOURCE=2 -std=c++11 + +CXXFLAGS += -DYCSB_TEST + +CXXFLAGS += -Wl,-z,relro,-z,now -Wl,-z,noexecstack -lpthread -Wl,-z,relro,-z,now \ + -Wl,-z,noexecstack \ + -Wl,--whole-archive -Wl,--no-whole-archive + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/TableStorage.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/TableStorage.cc new file mode 100644 index 000000000..5ba3542fe --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/TableStorage.cc @@ -0,0 +1,184 @@ +/** + * @file TableStorage.cc + * @brief TableStorage + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "TableStorage.h" + +// #include "ThreadPool.h" +// #include "Buffer.h" + +// static struct timespec time1, time2, time3; +// static uint32_t coreNum = 0; + +namespace LightTable { + +TableStorage::TableStorage(const char *ipAddress, const uint32_t portNum, + const char *path) + : // metaHandle(path), + LightTableIPAddress(ipAddress), + LightTablePortNum(portNum) { + + segmentManager = new SegmentManager(); + rootTable = new RootTable(); + + std::cout << "INIT TableStorage SUCCESS" << "\n"; + // threadPool = ThreadPool::getInstance(SYSTEM_MAX_CORES); + // buf = Buffer::getInstance(); + // queryCache = QueryCache::getInstance(&tableMap); + // blockPreload = BlockPreload::getInstance(); + // blockPreload->setParameters(queryCache); + // buf->setParameters(&metaHandle, rootTable); +} + +uint32_t TableStorage::createTable(const char *tableName, + SegmentType segmentType, + std::vector &schema) { + uint64_t segmentID = 0; + uint64_t firstBlockID = 0; + uint64_t tableID = + tableMap.size() + COMMON_TABLE_START_ID - SYSTEM_TABLE_COUNT; + uint32_t err = + segmentManager->getIdleSegment(segmentType, segmentID, firstBlockID); + if (err != SUCCESS) { + return err; + } + + CommonTable *commonTable = new CommonTable(tableID, tableName, firstBlockID, + segmentID, segmentType, schema); + std::pair::iterator, bool> ret; + ret = tableMap.insert(std::pair(tableID, commonTable)); + if (false == ret.second) { + return ERROR_TABLE; + } + time_t timeNow = time(NULL); + struct tm *now = localtime(&timeNow); + RootTable::TableTuple tuple; + tuple.tableID = tableID; + memcpy(tuple.tableName, tableName, TABLE_NAME_LENGTH); + tuple.firstBlockID = firstBlockID; + tuple.segmentType = segmentType; + tuple.segmentID = segmentID; + memcpy(tuple.user, "user", 5); + tuple.time = *now; + err = rootTable->appendTableInfo(tuple); + + if (err == SUCCESS) std::cout << "create table: " << tableName << std::endl; + return err; +} + +uint32_t TableStorage::dropTable(const char *tableName) { + uint64_t tableID = 0; + uint32_t result = rootTable->tableNameToTableID(tableName, tableID); + if (SUCCESS != result) return result; + + std::map::iterator iter = tableMap.find(tableID); + Table *commonTable = iter->second; + commonTable->drop(); + tableMap.erase(tableID); + result = rootTable->deleteTableInfo(tableID); + + if (result == SUCCESS) std::cout << "drop table: " << tableName << std::endl; + return result; +} + +uint32_t TableStorage::insertTuple(const char *tableName, const uint8_t *row) { + uint64_t tableID = 0; + uint32_t result = 0; + +#ifndef SDCARD_TEST + result = rootTable->tableNameToTableID(tableName, tableID); + if (SUCCESS != result) { + return result; + } +#else + tableID = YCSB_TABLE_ID; +#endif + + std::map::iterator iter = tableMap.find(tableID); + Table *commonTable = iter->second; + +#ifndef TABLE_STORAGE_LOGGING + result = commonTable->insertRow(row); +#else + result = commonTable->insertRow_logging(row); +#endif + + return result; +} + +uint32_t TableStorage::deleteTuple(const char *tableName, + const char *primaryKey) { + uint64_t tableID = 0; + uint32_t result = rootTable->tableNameToTableID(tableName, tableID); + if (SUCCESS != result) return result; + + std::map::iterator iter = tableMap.find(tableID); + Table *commonTable = iter->second; + result = commonTable->deleteRow(primaryKey); + + if (result == SUCCESS) + std::cout << "delete a tuple in " << tableName << " success!" << std::endl; + return result; +} + +uint32_t TableStorage::updateTuple(const char *tableName, + const char *primaryKey, + const char *columnName, + const uint8_t *value) { + uint64_t tableID = 0; + uint32_t result = rootTable->tableNameToTableID(tableName, tableID); + if (SUCCESS != result) return result; + + std::map::iterator iter = tableMap.find(tableID); + Table *commonTable = iter->second; + +#ifndef TABLE_STORAGE_LOGGING + result = commonTable->updateColumnItem(primaryKey, columnName, value); +#else + result = commonTable->updateColumnItem_logging(primaryKey, columnName, value); +#endif + + return result; +} + +uint32_t TableStorage::selectTuple(const char *tableName, + const char *primaryKey, uint8_t *row) { + uint64_t tableID = 0; + uint32_t result = 0; + +#ifndef SDCARD_TEST + result = rootTable->tableNameToTableID(tableName, tableID); + if (SUCCESS != result) return result; +#else + tableID = YCSB_TABLE_ID; +#endif + + std::map::iterator iter = tableMap.find(tableID); + Table *commonTable = iter->second; + result = commonTable->selectRow(primaryKey, row); + + return result; +} + +uint32_t TableStorage::initTableStorage() { + return SUCCESS; +} + +uint32_t TableStorage::closeTableStorage() { + return SUCCESS; +} + +TableStorage::~TableStorage() { + for (auto ite = tableMap.begin(); ite != tableMap.end(); ++ite) + delete (ite->second); + tableMap.clear(); + delete (rootTable); + delete (segmentManager); + std::cout << "close TableStorage success!\n"; +} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/UndoLogEntry.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/UndoLogEntry.cc new file mode 100644 index 000000000..b43735397 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/execution/UndoLogEntry.cc @@ -0,0 +1,54 @@ +/** + * @file UndoLogEntry.cc + * @brief UndoLogEntry + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "UndoLogEntry.h" + +#include + +namespace LightTable { + +UndoLogEntry::UndoLogEntry(uint64_t tableID, const char *primaryKey, + uint64_t keySize, char *tuple, uint64_t tupleSize, + uint64_t blockID, uint64_t offset) + : BufferItem(tableID), + blockID(blockID), + offset(offset), + tupleSize(tupleSize), + keySize(keySize), + isExpired(false) { + memcpy(this->tuple, tuple, tupleSize); + memcpy(this->primaryKey, primaryKey, keySize); +} + +UndoLogEntry::~UndoLogEntry() { + delete[] primaryKey; + delete[] tuple; +} + +uint32_t UndoLogEntry::getTuple(uint64_t tableID, const char *primaryKey, + char *tuple, uint64_t &blockID, + uint64_t &offset) { + if (this->tableID != tableID || strcmp(this->primaryKey, primaryKey) != 0) { + return ERROR_TABLE; + } + + memcpy(tuple, this->tuple, tupleSize); + blockID = this->blockID; + offset = this->offset; + return SUCCESS; +} + +void UndoLogEntry::expireUndoLog() { isExpired = true; } + +char *UndoLogEntry::getPrimaryKey() { return this->primaryKey; } + +bool UndoLogEntry::getIsExpired(UndoLogEntry *logEntry) { + return logEntry->isExpired; +} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/CommonTable.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/CommonTable.cc new file mode 100644 index 000000000..1a7eb8ea5 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/CommonTable.cc @@ -0,0 +1,31 @@ +/** + * @file CommonTable.cc + * @brief CommonTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "CommonTable.h" + +namespace LightTable { + +CommonTable::CommonTable(uint64_t tableID, const char *tableName, + uint64_t firstBlockID, uint64_t segmentID, + SegmentType segmentType, + std::vector schemaEntrys, + bool usePrimaryKeyIndex) + : Table(tableID, tableName, firstBlockID, segmentID, segmentType, + schemaEntrys, usePrimaryKeyIndex) + +{} + +CommonTable::CommonTable(uint64_t tableID, const char *tableName, + uint64_t firstBlockID, uint64_t segmentID, + SegmentType segmentType, bool usePrimaryKeyIndex) + : Table(tableID, tableName, firstBlockID, segmentID, segmentType, + usePrimaryKeyIndex) + +{} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/HashBucket.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/HashBucket.cc new file mode 100644 index 000000000..a32852020 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/HashBucket.cc @@ -0,0 +1,77 @@ +/** + * @file HashBucket.cc + * @brief HashBucket + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "HashBucket.h" + +namespace LightTable { + +HashBucket::HashBucket() : bucketSize(0) {} + +uint32_t HashBucket::addBucketItem(uint64_t key, RowLocation rowLocation) { + std::pair::iterator, bool> ret; + // std::unique_lock lck(mtx); + // pthread_mutex_lock(&mtx); + ret = bucketItems.insert(std::pair(key, rowLocation)); + // lck.unlock(); + // pthread_mutex_unlock(&mtx); + if (ret.second == false) { + return ADD_BUCKET_ITEM_ERROR; + } + bucketSize++; + return SUCCESS; +} + +uint32_t HashBucket::deleteBucketItem(uint64_t key) { + if (bucketItems.erase(key) == 1) { + bucketSize--; + return SUCCESS; + } + return BUCKET_ITEM_NOT_FOUND; +} + +uint32_t HashBucket::updateRowLocation(uint64_t key, RowLocation rowLocation) { + std::map::iterator iter; + iter = bucketItems.find(key); + + if (iter != bucketItems.end()) { + (iter->second).blockID = rowLocation.blockID; + (iter->second).rowOffset = rowLocation.rowOffset; + return SUCCESS; + } + return BUCKET_ITEM_NOT_FOUND; +} + +uint32_t HashBucket::getRowLocation(uint64_t key, RowLocation &rowLocation) { + std::map::iterator iter; + iter = bucketItems.find(key); + + if (iter != bucketItems.end()) { + rowLocation.blockID = (iter->second).blockID; + rowLocation.rowOffset = (iter->second).rowOffset; + return SUCCESS; + } + + rowLocation.blockID = 0; + rowLocation.rowOffset = 0; + return BUCKET_ITEM_NOT_FOUND; +} + +uint64_t HashBucket::getBucketSize() { return bucketSize; } + +uint32_t HashBucket::setBucketSize(uint64_t bucketSize) { + this->bucketSize = bucketSize; + return SUCCESS; +} + +uint32_t HashBucket::getAllBucketItems( + std::map &bucketItems) { + bucketItems = this->bucketItems; + return SUCCESS; +} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/HashTable.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/HashTable.cc new file mode 100644 index 000000000..bbb50dd78 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/HashTable.cc @@ -0,0 +1,113 @@ +/** + * @file HashTable.cc + * @brief HashTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "HashTable.h" + +namespace LightTable { + +HashTable::HashTable() { + buckets.reserve(HASH_BUCKET_SIZE); + + for (uint32_t i = 0; i < HASH_BUCKET_SIZE; i++) { + HashBucket *tempBucket = new HashBucket(); + buckets.push_back(tempBucket); + } +} + +HashTable::~HashTable() { + std::vector::iterator iter = buckets.begin(); + while (iter != buckets.end()) { + iter = buckets.erase(iter); + } +} + +uint64_t HashTable::getMapKey(const char *primaryKey) { + const std::string str = primaryKey; + + uint64_t BitsInUnsignedInt = (uint64_t)(4 * 8); + uint64_t ThreeQuarters = (uint64_t)((BitsInUnsignedInt * 3) / 4); + uint64_t OneEighth = (uint64_t)(BitsInUnsignedInt / 8); + uint64_t HighBits = (uint64_t)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth); + uint64_t hash = 0; + uint64_t test = 0; + for (uint32_t i = 0; i < str.length(); i++) { + hash = (hash << OneEighth) + str[i]; + if ((test = hash & HighBits) != 0) { + hash = ((hash ^ (test >> ThreeQuarters)) & (~HighBits)); + } + } + return hash; +} + +uint32_t HashTable::hashToBucket(uint64_t key) { + return key % HASH_BUCKET_SIZE; +} + +uint32_t HashTable::getRowLocation(uint32_t bucketID, uint64_t key, + RowLocation &rowLocation) { + return buckets[bucketID]->getRowLocation(key, rowLocation); +} + +uint32_t HashTable::addItem(uint32_t bucketID, uint64_t key, + RowLocation rowLocation) { + return buckets[bucketID]->addBucketItem(key, rowLocation); +} + +uint32_t HashTable::deleteItem(uint32_t bucketID, uint64_t key) { + return buckets[bucketID]->deleteBucketItem(key); +} + +uint32_t HashTable::updateItem(uint32_t bucketID, uint64_t key, + RowLocation rowLocation) { + return buckets[bucketID]->updateRowLocation(key, rowLocation); +} + +uint64_t HashTable::getItemCount() { + if (buckets.size() == 0) { + return buckets.size(); + } + uint64_t itemCount = 0; + for (uint32_t i = 0; i < HASH_BUCKET_SIZE; i++) { + itemCount += buckets[i]->getBucketSize(); + } + return itemCount; +} + +uint32_t HashTable::getAllBuckets(std::vector &buckets) { + buckets = this->buckets; + return SUCCESS; +} + +uint32_t HashTable::refreshRowLocations( + uint64_t blockID, uint64_t deleteOffset, uint64_t rowSize, + std::map &locationItems) { + for (uint32_t i = 0; i < HASH_BUCKET_SIZE; i++) { + std::map bucketItems; + buckets[i]->getAllBucketItems(bucketItems); + std::map::iterator iter = bucketItems.begin(); + while (iter != bucketItems.end()) { + if ((iter->second).blockID == blockID && + (iter->second).rowOffset > deleteOffset) { + (iter->second).rowOffset -= rowSize; + locationItems.insert( + std::pair(iter->first, iter->second)); + } + } + } + return SUCCESS; +} + +uint32_t HashTable::clear() { + std::vector::iterator iter = buckets.begin(); + while (iter != buckets.end()) { + iter = buckets.erase(iter); + } + return SUCCESS; +} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Makefile b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Makefile new file mode 100644 index 000000000..13f5df2ac --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Makefile @@ -0,0 +1,23 @@ +ifndef LIGHTTABLE_DIR +LIGHTTABLE_DIR = ../.. +endif + +SRC_FILES := $(wildcard *.cc) +INCLUDE_DIR = -I$(LIGHTTABLE_DIR)/src -I. -I$(LIGHTTABLE_DIR)/spdk/include -I/opt/gnu-mcu-eclipse/riscv-none-gcc/8.2.0-2.1-20190425-1021/riscv-none-embed/include/c++/8.2.0 + +SOURCE_FOR_CC = $(foreach source_file_1, $(SOURCES),$(filter %.cc, $(source_file_1))) + +CXXFLAGS += -fno-omit-frame-pointer \ + -Wno-missing-field-initializers -Wmissing-declarations -fno-strict-aliasing \ + $(INCLUDE_DIR) -Wformat -Wformat-security -D_GNU_SOURCE \ + -fPIC -fno-stack-protector -fno-common -DNDEBUG -U_FORTIFY_SOURCE \ + -D_FORTIFY_SOURCE=2 -std=c++11 + +CXXFLAGS += -DYCSB_TEST + +CXXFLAGS += -Wl,-z,relro,-z,now -Wl,-z,noexecstack -lpthread -Wl,-z,relro,-z,now \ + -Wl,-z,noexecstack \ + -Wl,--whole-archive -Wl,--no-whole-archive -lrt + + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/PrefetchBlockManager.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/PrefetchBlockManager.cc new file mode 100644 index 000000000..53d968529 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/PrefetchBlockManager.cc @@ -0,0 +1,267 @@ +/** + * @file PrefetchBlockManager.cc + * @brief PrefetchBlockManager + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "PrefetchBlockManager.h" + +namespace LightTable +{ + +PrefetchBlockManager::PrefetchBlockManager(uint64_t firstBlockID, + uint64_t segmentID, + SegmentType segmentType) + : segmentID(segmentID), segmentType(segmentType), firstBlockID(firstBlockID), currentID(0) +{ + uint32_t num = 0; + + switch (segmentType) + { + case SEGMENT_TYPE_SMALL: + num = SEGMENT_TYPE_SMALL_CELL_SIZE / BLOCK_SIZE; + break; + case SEGMENT_TYPE_MEDIUM: + num = SEGMENT_TYPE_MEDIUM_CELL_SIZE / BLOCK_SIZE; + break; + case SEGMENT_TYPE_BIG: + num = SEGMENT_TYPE_BIG_CELL_SIZE / BLOCK_SIZE; + break; + default: + break; + } + + blockCount = num; + +#ifndef YCSB_TEST + while (num--) + { + PrefetchBlockManagerEntry *entry = new PrefetchBlockManagerEntry(); + entry->blockID = firstBlockID + num; + entry->currentOffset = 0; + entry->isOccupied = PREFETCH_BLOCK_STATUS_IDLE; + prefetchBlocks.insert(std::pair(entry->blockID, *entry)); + } +#endif + +} + +PrefetchBlockManager::~PrefetchBlockManager() +{ + prefetchBlocks.clear(); +} + +uint64_t +PrefetchBlockManager::getNextBlock() +{ + uint32_t count = blockCount - currentID; + if (count <= 0) + { + return 0; + } + currentID++; + return currentID + firstBlockID - 1; +} + +uint64_t +PrefetchBlockManager::blockAllocate(uint64_t rowSize) +{ + if (blockCount == 0) + { + return 0; + } + // struct timespec time; + // clock_gettime(CLOCK_REALTIME, &time); + srand((unsigned)time(NULL)); + std::map::iterator iter; + uint32_t count = blockCount - currentID; + + while (count--) + { + uint64_t blockID = currentID + firstBlockID; + iter = prefetchBlocks.find(blockID); + + if (!iter->second.isOccupied) + { + if (rowSize < (BLOCK_SIZE - iter->second.currentOffset)) + { + iter->second.isOccupied = PREFETCH_BLOCK_STATUS_BUSY; + return blockID; + } + } + + currentID++; + } + + return 0; +} + +uint32_t +PrefetchBlockManager::setBlockState(uint64_t blockID, bool isOccupied) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + + if (iter != prefetchBlocks.end()) + { + iter->second.isOccupied = isOccupied; + return SUCCESS; + } + else + { + return PREFETCH_BLOCK_NOT_FOUND; + } +} + +uint32_t +PrefetchBlockManager::setOffset(uint64_t blockID, uint64_t currentOffset) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + + if (iter != prefetchBlocks.end()) + { + iter->second.currentOffset = currentOffset; + return SUCCESS; + } + else + { + return PREFETCH_BLOCK_NOT_FOUND; + } +} + +uint32_t +PrefetchBlockManager::getOffset(uint64_t blockID, uint64_t ¤tOffset) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + + if (iter != prefetchBlocks.end()) + { + currentOffset = iter->second.currentOffset; + return SUCCESS; + } + else + { + return PREFETCH_BLOCK_NOT_FOUND; + } +} + +uint32_t +PrefetchBlockManager::advanceOffset(uint64_t blockID, uint64_t rowSize) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + + if (iter != prefetchBlocks.end()) + { + iter->second.currentOffset += rowSize; + return SUCCESS; + } + else + { + return PREFETCH_BLOCK_NOT_FOUND; + } +} + +uint32_t +PrefetchBlockManager::isOccupied(uint64_t blockID, bool &status) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + + if (iter != prefetchBlocks.end()) + { + status = iter->second.isOccupied; + return SUCCESS; + } + else + { + return PREFETCH_BLOCK_NOT_FOUND; + } +} + +uint32_t +PrefetchBlockManager::getPrefetchBlockEntry(uint64_t blockID, + PrefetchBlockManagerEntry &entry) +{ + entry = prefetchBlocks[blockID]; + return SUCCESS; +} + +uint32_t +PrefetchBlockManager::getAllPrefetchBlockEntrys(std::map &entrys) +{ + entrys = prefetchBlocks; + return SUCCESS; +} + +uint32_t +PrefetchBlockManager::lockBlock(uint64_t blockID) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + if (iter != prefetchBlocks.end()) + { + if (iter->second.isOccupied == PREFETCH_BLOCK_STATUS_BUSY) + { + return BLOCK_OCCUPIED; + } + iter->second.isOccupied = PREFETCH_BLOCK_STATUS_BUSY; + return SUCCESS; + } + return PREFETCH_BLOCK_NOT_FOUND; +} + +uint32_t +PrefetchBlockManager::unlockBlock(uint64_t blockID) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + if (iter != prefetchBlocks.end()) + { + if (iter->second.isOccupied == PREFETCH_BLOCK_STATUS_BUSY) + { + iter->second.isOccupied = PREFETCH_BLOCK_STATUS_IDLE; + } + return SUCCESS; + } + return PREFETCH_BLOCK_NOT_FOUND; +} + +bool +PrefetchBlockManager::isCached(uint64_t blockID, uint64_t &pageID) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + + if (iter != prefetchBlocks.end() && iter->second.isCached) + { + pageID = iter->second.pageID; + return true; + } + return false; +} + +uint32_t +PrefetchBlockManager::setIsCached(uint64_t blockID, bool isCached, uint64_t pageID) +{ + std::map::iterator iter; + iter = prefetchBlocks.find(blockID); + + if (iter != prefetchBlocks.end()) + { + iter->second.isCached = isCached; + if (isCached) + { + iter->second.pageID = pageID; + } + return SUCCESS; + } + return PREFETCH_BLOCK_NOT_FOUND; +} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/RootTable.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/RootTable.cc new file mode 100644 index 000000000..72f05ef87 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/RootTable.cc @@ -0,0 +1,244 @@ +/** + * @file RootTable.cc + * @brief RootTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "RootTable.h" + +namespace LightTable { + +RootTable::RootTable(bool usePrimaryKeyIndex) + : SystemTable(ROOTTABLE_TABLE_ID, "RootTable", ROOTTABLE_FIRST_BLOCK_ID, + ROOTTABLE_SEGMENT_ID, SEGMENT_TYPE_SMALL, + usePrimaryKeyIndex) { + Schema::SchemaEntry entry1 = {1, "tableID", "uint64_t", 8, true, false}; + schema.appendEntry(entry1); + Schema::SchemaEntry entry2 = {2, "tableName", "string", TABLE_NAME_LENGTH, + false, false}; + schema.appendEntry(entry2); + Schema::SchemaEntry entry3 = {3, "firstBlockID", "uint64_t", 8, false, false}; + schema.appendEntry(entry3); + Schema::SchemaEntry entry4 = {4, "segmentID", "uint64_t", 8, false, false}; + schema.appendEntry(entry4); + Schema::SchemaEntry entry5 = {5, "segmentType", "uint32_t", 4, false, false}; + schema.appendEntry(entry5); + Schema::SchemaEntry entry6 = {6, "user", "string", USER_NAME_LENGTH, + false, true}; + schema.appendEntry(entry6); + Schema::SchemaEntry entry7 = {7, "time", "time", 60, false, false}; + schema.appendEntry(entry7); +} + +uint32_t RootTable::tableNameToTableID(const char *tableName, + uint64_t &tableID) { + std::map::iterator iter = tableTupleMap.begin(); + + while (iter != tableTupleMap.end()) { + if (0 == strncmp(tableName, iter->second.tableName, TABLE_NAME_LENGTH)) { + tableID = iter->second.tableID; + return SUCCESS; + } + iter++; + } + return TABLE_NOT_FOUND; +} + +uint32_t RootTable::deleteTableInfo(uint64_t tableID) { + uint32_t ret = SUCCESS; + + RowLocation rowLocation; + uint32_t bucketID = hashTable.hashToBucket(tableID); + ret = hashTable.getRowLocation(bucketID, tableID, rowLocation); + + uint64_t deleteBlockID = rowLocation.blockID; + uint64_t deleteRowOffset = rowLocation.rowOffset; + char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH]; + uint32_t size = 0; + + while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS) + ; + uint64_t currentOffset = 0; + ret = prefetchBlockManager.getOffset(rowLocation.blockID, currentOffset); + if (ret != SUCCESS) { + return ret; + } + + if (rowLocation.rowOffset + schema.getEntrySize() != currentOffset) { + // RowBufferItem::Tuple item; + // uint8_t str[ROOTTABLE_TUPLE_SIZE]; + // memcpy(str, &tableTupleMap[tableID], sizeof(tableTupleMap[tableID])); + // item.blockID = rowLocation.blockID; + // item.rowOffset = rowLocation.rowOffset; + // item.isDelete = true; + // RowBufferItem *rowBufferItem = new RowBufferItem(item); + // buf->append(rowBufferItem); + + std::map locationItems; + hashTable.refreshRowLocations(deleteBlockID, deleteRowOffset, + schema.getEntrySize(), locationItems); + // std::map::iterator iter = locationItems.begin(); + // while (iter != locationItems.end()) { + // MetaHandle::serialize(std::pair(iter->first, + // iter->second), tableID, hashTableMetaData, size); + // MetaBufferItem *nextMeta= new MetaBufferItem(tableID, hashTableMetaData, + // size); buf->append(nextMeta); + // } + } + + hashTable.deleteItem(bucketID, tableID); + rowLocation.blockID = 0; + // MetaHandle::serialize(std::pair(tableID, + // rowLocation), + // ROOTTABLE_TABLE_ID, hashTableMetaData, size); + // MetaBufferItem *hashTableMeta= new MetaBufferItem(ROOTTABLE_TABLE_ID, + // hashTableMetaData, size); + // buf->append(hashTableMeta); + + uint64_t newOffset = currentOffset - schema.getEntrySize(); + prefetchBlockManager.setOffset(deleteBlockID, newOffset); + + PrefetchBlockManager::PrefetchBlockManagerEntry blockEntry; + prefetchBlockManager.unlockBlock(deleteBlockID); + prefetchBlockManager.getPrefetchBlockEntry(deleteBlockID, blockEntry); + // char *pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH]; + // MetaHandle::serialize(blockEntry, ROOTTABLE_TABLE_ID, pbmData, size); + // MetaBufferItem *pbmMeta = new MetaBufferItem(ROOTTABLE_TABLE_ID, pbmData, + // size); buf->append(pbmMeta); + + if (tableTupleMap.erase(tableID) == 1) { + return SUCCESS; + } + return ERROR_TABLE; +} + +uint32_t RootTable::appendTableInfo(TableTuple tableTuple) { + uint32_t err = SUCCESS; + + tableTupleMap.insert( + std::pair(tableTuple.tableID, tableTuple)); + + uint64_t blockID = 0; + uint64_t blockOffset = 0; + blockID = prefetchBlockManager.blockAllocate(schema.getEntrySize()); + err = prefetchBlockManager.getOffset(blockID, blockOffset); + + if (err != SUCCESS) { + // TODO allocate new seg + return GET_AVAILABLE_BLOCK_ERROR; + } + + // RowBufferItem::Tuple item; + // uint8_t str[ROOTTABLE_TUPLE_SIZE]; + // memcpy(str, &tableTuple, sizeof(tableTuple)); + // item.row = str; + // item.blockID = blockID; + // item.rowOffset = blockOffset; + // item.isDelete = false; + // RowBufferItem *rowBufferItem = new RowBufferItem(item); + // buf->append(rowBufferItem); + + uint32_t bucketID = hashTable.hashToBucket(tableTuple.tableID); + RowLocation rowLocation = {blockID, blockOffset}; + err = hashTable.addItem(bucketID, tableTuple.tableID, rowLocation); + + if (err != SUCCESS) { + return err; + } + + // uint32_t size = 0; + // char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH]; + // MetaHandle::serialize(std::pair(tableTuple.tableID, + // rowLocation), tableID, hashTableMetaData, size); + // MetaBufferItem *hashTableMeta = new MetaBufferItem(tableID, + // hashTableMetaData, + // size); + // buf->append(hashTableMeta); + + err = prefetchBlockManager.advanceOffset(blockID, schema.getEntrySize()); + prefetchBlockManager.setBlockState(blockID, PREFETCH_BLOCK_STATUS_IDLE); + + // PrefetchBlockManager::PrefetchBlockManagerEntry blockEntry; + // prefetchBlockManager.getPrefetchBlockEntry(blockID, blockEntry); + // char *pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH]; + // MetaHandle::serialize(blockEntry, tableID, pbmData, size); + // MetaBufferItem *pbmMeta = new MetaBufferItem(tableID, pbmData, size); + // buf->append(pbmMeta); + + return SUCCESS; +} + +uint32_t RootTable::getTableInfo(uint64_t tableID, + TableTuple &tableTupleResult) { + std::map::iterator iter; + iter = tableTupleMap.find(tableID); + + if (iter != tableTupleMap.end()) { + tableTupleResult = iter->second; + return SUCCESS; + } + tableTupleResult.tableID = 0; + return TABLE_TUPLE_NOT_FOUND; +} + +uint32_t RootTable::modifyTableInfo(uint64_t tableID, TableTuple tableTuple) { + uint32_t ret = SUCCESS; + std::map::iterator iter; + iter = tableTupleMap.find(tableID); + + if (iter != tableTupleMap.end()) { + iter->second = tableTuple; + + uint32_t bucketID = hashTable.hashToBucket(tableID); + RowLocation rowLocation; + ret = hashTable.getRowLocation(bucketID, tableID, rowLocation); + if (ret != SUCCESS) { + return ret; + } + // RowBufferItem::Tuple item; + // uint8_t str[ROOTTABLE_TUPLE_SIZE]; + // memcpy(str, &tableTuple, sizeof(tableTuple)); + // item.row = str; + // item.blockID = rowLocation.blockID; + // item.rowOffset = rowLocation.rowOffset; + // item.isDelete = false; + // RowBufferItem *rowBufferItem = new RowBufferItem(item); + // buf->append(rowBufferItem); + + return SUCCESS; + } + return TABLE_TUPLE_NOT_FOUND; +} + +uint32_t RootTable::getTableTuple(uint64_t tableID, TableTuple &tableTuple) { + std::map::iterator iter; + iter = tableTupleMap.find(tableID); + if (iter != tableTupleMap.end()) { + tableTuple = iter->second; + return SUCCESS; + } + return TABLE_TUPLE_NOT_FOUND; +} + +uint32_t RootTable::serializeRow(const TableTuple tableTuple, uint8_t *buf) { + memcpy(buf, &tableTuple, ROOTTABLE_TUPLE_SIZE); + + return SUCCESS; +} + +uint32_t RootTable::deserializeRow(const uint8_t *buf, + TableTuple *tableTupleResult) { + if (buf != NULL) { + memcpy(tableTupleResult, buf, ROOTTABLE_TUPLE_SIZE); + if (tableTupleResult->tableID != 0) { + return SUCCESS; + } + } + return BUFFER_EMPTY; +} + +uint64_t RootTable::getTableCount() { return tableTupleMap.size(); } + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/RowMap.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/RowMap.cc new file mode 100644 index 000000000..459b563ae --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/RowMap.cc @@ -0,0 +1,77 @@ +/** + * @file RowMap.cc + * @brief RowMap + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "RowMap.h" + +namespace LightTable { + +RowMap::RowMap() {} + +uint32_t RowMap::appendEntry(uint64_t key, uint64_t blockID, + uint64_t rowOffset) { + std::pair::iterator, bool> ret; + RowMapEntry rowMapEntry = {key, blockID, rowOffset}; + + ret = rowMapEntrys.insert(std::pair(key, rowMapEntry)); + + if (ret.second == false) { + return ADD_ROW_MAP_ENTRY_ERROR; + } + + return SUCCESS; +} + +uint32_t RowMap::deleteEntry(uint64_t key) { + if (rowMapEntrys.erase(key) == 1) { + return SUCCESS; + } + return ROW_MAP_ENTRY_NOT_FOUND; +} + +uint32_t RowMap::alterEntry(uint64_t key, uint64_t blockID, + uint64_t rowOffset) { + std::map::iterator iter; + iter = rowMapEntrys.find(key); + + if (iter != rowMapEntrys.end()) { + (iter->second).key = key; + (iter->second).blockID = blockID; + (iter->second).rowOffset = rowOffset; + return SUCCESS; + } + + return ROW_MAP_ENTRY_NOT_FOUND; +} + +uint32_t RowMap::queryEntry(uint64_t key, RowMapEntry &rowMapEntry) { + std::map::iterator iter; + iter = rowMapEntrys.find(key); + + if (iter != rowMapEntrys.end()) { + rowMapEntry = iter->second; + return SUCCESS; + } + + rowMapEntry.key = key; + rowMapEntry.blockID = 0; + rowMapEntry.rowOffset = 0; + return ROW_MAP_ENTRY_NOT_FOUND; +} + +uint32_t RowMap::queryAllEntry( + std::map &allRowMapEntrys) { + if (rowMapEntrys.empty() == false) { + allRowMapEntrys = rowMapEntrys; + return SUCCESS; + } + return ROW_MAP_ENTRY_NOT_FOUND; +} + +uint64_t RowMap::getRowCount() { return rowMapEntrys.size(); } + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Schema.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Schema.cc new file mode 100644 index 000000000..f139a3b3e --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Schema.cc @@ -0,0 +1,166 @@ +/** + * @file Schema.cc + * @brief table schema + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "Schema.h" + +namespace LightTable { + +Schema::Schema() { + primaryKeySchema.columnID = 1; + primaryKeySchema.isPrimaryKey = true; + columnCount = 0; + entrySize = 0; +} + +Schema::Schema(std::vector schemaEntrys) { + columnCount = 0; + entrySize = 0; + primaryKeySchema.columnID = 1; + primaryKeySchema.isPrimaryKey = true; + std::vector::iterator iter = schemaEntrys.begin(); + while (iter != schemaEntrys.end()) { + appendEntry(*iter); + iter++; + } +} + +uint32_t Schema::appendEntry(SchemaEntry &schemaEntry) { + if (schemaEntry.columnID != columnCount + 1) { + return COLUMN_ID_NOT_CONTINUOUS; + } + std::pair::iterator, bool> ret; + ret = schemaEntrys.insert(std::pair( + schemaEntry.columnID, schemaEntry)); + + if (ret.second == false) { + return ADD_SCHEMA_ENTRY_ERROR; + } + + if (schemaEntry.isPrimaryKey) { + primaryKeySchema = schemaEntry; + } + + columnCount++; + entrySize = entrySize + schemaEntry.length; + return SUCCESS; +} + +uint32_t Schema::deleteEntry(uint64_t columnID) { + if (columnID == primaryKeySchema.columnID) { + return DELETE_PARIMARY_KEY_COLUMN; + } + + uint64_t newColumnID = columnID; + SchemaEntry schemaEntry; + + std::map::iterator iter; + iter = schemaEntrys.find(columnID); + if (iter != schemaEntrys.end()) { + schemaEntry = iter->second; + schemaEntrys.erase(iter); + entrySize = entrySize - schemaEntry.length; + columnCount--; + + if (columnCount > 0) { + iter = schemaEntrys.find(newColumnID + 1); + + while (iter != schemaEntrys.end()) { + schemaEntry = iter->second; + schemaEntry.columnID = newColumnID; + + schemaEntrys.insert( + std::pair(newColumnID, schemaEntry)); + + schemaEntrys.erase(iter); + newColumnID++; + iter = schemaEntrys.find(newColumnID + 1); + } + } + return SUCCESS; + } + return SCHEMA_ENTRY_NOT_FOUND; +} + +uint32_t Schema::alterEntry(uint64_t columnID, SchemaEntry schemaEntry) { + if (schemaEntry.columnID != columnID) { + return COLUMN_ID_NOT_CONTINUOUS; + } + + std::map::iterator iter; + iter = schemaEntrys.find(columnID); + + entrySize = entrySize - (iter->second).length; + + if (iter != schemaEntrys.end()) { + iter->second = schemaEntry; + primaryKeySchema = schemaEntry; + entrySize = entrySize + (iter->second).length; + return SUCCESS; + } + return SCHEMA_ENTRY_NOT_FOUND; +} + +uint32_t Schema::getColumnID(const char *columnName, uint64_t &columnID) { + std::map::iterator iter = schemaEntrys.begin(); + while (iter != schemaEntrys.end()) { + if (strncmp(iter->second.columnName, columnName, iter->second.length) == + 0) { + columnID = (iter->second).columnID; + return SUCCESS; + } + iter++; + } + return COLUMN_ITEM_NOT_FOUND; +} + +uint32_t Schema::queryEntry(uint64_t columnID, + Schema::SchemaEntry &schemaEntry) { + std::map::iterator iter; + iter = schemaEntrys.find(columnID); + + if (iter != schemaEntrys.end()) { + schemaEntry = iter->second; + return SUCCESS; + } + + schemaEntry.columnID = 0; + return SCHEMA_ENTRY_NOT_FOUND; +} + +uint32_t Schema::queryAllEntry( + std::map &allSchemaEntrys) { + allSchemaEntrys = schemaEntrys; + if (schemaEntrys.empty() == false) { + return SUCCESS; + } + return SCHEMA_ENTRY_NOT_FOUND; +} + +uint64_t Schema::getEntrySize() { return entrySize; } + +void Schema::setEntrySize(uint64_t entrySize) { this->entrySize = entrySize; } + +uint64_t Schema::getColumnCount() { return columnCount; } + +void Schema::setColumnCount(uint64_t columnCount) { + this->columnCount = columnCount; +} + +uint32_t Schema::getPrimaryKeyLength() { return primaryKeySchema.length; } + +Schema::SchemaEntry &Schema::getPrimaryKeySchema() { return primaryKeySchema; } + +uint32_t Schema::drop() { + schemaEntrys.clear(); + primaryKeySchema.length = 0; + columnCount = 0; + entrySize = 0; + return SUCCESS; +} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/SegmentManager.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/SegmentManager.cc new file mode 100644 index 000000000..bf738ab98 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/SegmentManager.cc @@ -0,0 +1,180 @@ +/** + * @file SegmentManager.cc + * @brief SegmentManager + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "SegmentManager.h" + +namespace LightTable { + +SegmentManager::SegmentManager() { + int blockID, num = 0; + + smallBitmap = new uint8_t[SEGMENT_TYPE_SMALL_BITMAP_SIZE]; + mediumBitmap = new uint8_t[SEGMENT_TYPE_MEDIUM_BITMAP_SIZE]; + bigBitmap = new uint8_t[SEGMENT_TYPE_BIG_BITMAP_SIZE]; + +#ifdef YCSB_TEST + blockID = SEGMENT_TYPE_BIG_START; + while (num < SEGMENT_TYPE_BIG_BITMAP_SIZE) { + Driver::read(bigBitmap + num, blockID); + num += BLOCK_SIZE; + blockID++; + } + +#else + num = 0; + blockID = SEGMENT_TYPE_SMALL_START; + while (num < SEGMENT_TYPE_SMALL_BITMAP_SIZE) { + Driver::read(smallBitmap + num, blockID); + num += BLOCK_SIZE; + blockID++; + } + + num = 0; + blockID = SEGMENT_TYPE_MEDIUM_START; + while (num < SEGMENT_TYPE_MEDIUM_BITMAP_SIZE) { + Driver::read(mediumBitmap + num, blockID); + num += BLOCK_SIZE; + blockID++; + } + + num = 0; + blockID = SEGMENT_TYPE_BIG_START; + while (num < SEGMENT_TYPE_BIG_BITMAP_SIZE) { + Driver::read(mediumBitmap + num, blockID); + num += BLOCK_SIZE; + blockID++; + } +#endif +} + +SegmentManager::~SegmentManager() { + delete[] smallBitmap; + delete[] mediumBitmap; + delete[] bigBitmap; +} + +uint32_t SegmentManager::setBitmap(SegmentType segmentType, uint64_t segmentID, + SegmentStatus segmentStatus) { + switch (segmentType) { + case SEGMENT_TYPE_SMALL: + return setBit(segmentID, smallBitmap, SEGMENT_TYPE_SMALL_START, + segmentStatus); + + case SEGMENT_TYPE_MEDIUM: + return setBit(segmentID, mediumBitmap, SEGMENT_TYPE_MEDIUM_START, + segmentStatus); + + case SEGMENT_TYPE_BIG: + return setBit(segmentID, bigBitmap, SEGMENT_TYPE_BIG_START, + segmentStatus); + + default: + return SEGMENT_TYPE_ERROR; + } +} + +uint32_t SegmentManager::getIdleSegment(SegmentType segmentType, + uint64_t &segmentID, + uint64_t &firstBlockID) { + uint32_t stateCode; + + switch (segmentType) { + case SEGMENT_TYPE_SMALL: + stateCode = + findFirstIdle(smallBitmap, SEGMENT_TYPE_SMALL_BITMAP_SIZE, segmentID); + + if (stateCode != SUCCESS) return stateCode; + + firstBlockID = SEGMENT_TYPE_SMALL_START + + (SEGMENT_TYPE_SMALL_CELL_SIZE / BLOCK_SIZE) * segmentID; + + return setBit(segmentID, smallBitmap, SEGMENT_TYPE_SMALL_START, + SEGMENT_STATUS_BUSY); + + case SEGMENT_TYPE_MEDIUM: + stateCode = findFirstIdle(mediumBitmap, SEGMENT_TYPE_MEDIUM_BITMAP_SIZE, + segmentID); + + if (stateCode != SUCCESS) return stateCode; + + firstBlockID = SEGMENT_TYPE_MEDIUM_START + + (SEGMENT_TYPE_MEDIUM_CELL_SIZE / BLOCK_SIZE) * segmentID; + + return setBit(segmentID, mediumBitmap, SEGMENT_TYPE_MEDIUM_START, + SEGMENT_STATUS_BUSY); + + case SEGMENT_TYPE_BIG: + stateCode = + findFirstIdle(bigBitmap, SEGMENT_TYPE_BIG_BITMAP_SIZE, segmentID); + + if (stateCode != SUCCESS) return stateCode; + + firstBlockID = SEGMENT_TYPE_BIG_START + + (SEGMENT_TYPE_BIG_CELL_SIZE / BLOCK_SIZE) * segmentID; + + return setBit(segmentID, bigBitmap, SEGMENT_TYPE_BIG_START, + SEGMENT_STATUS_BUSY); + + default: + return SEGMENT_TYPE_ERROR; + } +} + +uint32_t SegmentManager::setBit(uint64_t segmentID, uint8_t *buf, + uint64_t segmentStart, + SegmentStatus segmentStatus) { + uint32_t integer, remainder; + uint8_t tmp = 1; + + integer = segmentID / 8; + remainder = segmentID % 8; + + tmp = tmp << remainder; + if (segmentStatus == SEGMENT_STATUS_BUSY) { + buf[integer] |= tmp; + } else if (segmentStatus == SEGMENT_STATUS_IDLE) { + buf[integer] &= ~tmp; + } else { + return SEGMENT_STATUS_ERROR; + } + + uint64_t num = integer / BLOCK_SIZE; + uint64_t blockID = num + segmentStart; + + Driver::write(buf + num * BLOCK_SIZE, blockID); + + return SUCCESS; +} + +uint32_t SegmentManager::findFirstIdle(uint8_t *buf, uint64_t segmentNum, + uint64_t &segmentID) { + uint64_t num, place; + uint8_t res, tmp, isfound; + + for (isfound = num = 0; num < segmentNum; num++) { + for (place = 0; place < 8; place++) { + tmp = 0x01 << place; + tmp = tmp & buf[num]; + res = (tmp >> place); + if (res == 0) { + isfound = 1; + break; + } + } + if (isfound == 1) break; + } + + if (isfound == 0) { + return SEGMENT_IS_EXHAUSTED; + } + segmentID = num * 8 + place; + + return SUCCESS; +} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/SystemTable.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/SystemTable.cc new file mode 100644 index 000000000..183035e0b --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/SystemTable.cc @@ -0,0 +1,31 @@ +/** + * @file SystemTable.cc + * @brief SystemTable + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "SystemTable.h" + +namespace LightTable { + +SystemTable::SystemTable(uint64_t tableID, const char *tableName, + uint64_t firstBlockID, uint64_t segmentID, + SegmentType segmentType, + std::vector schemaEntrys, + bool usePrimaryKeyIndex) + : Table(tableID, tableName, firstBlockID, segmentID, segmentType, + schemaEntrys, usePrimaryKeyIndex) + +{} + +SystemTable::SystemTable(uint64_t tableID, const char *tableName, + uint64_t firstBlockID, uint64_t segmentID, + SegmentType segmentType, bool usePrimaryKeyIndex) + : Table(tableID, tableName, firstBlockID, segmentID, segmentType, + usePrimaryKeyIndex) + +{} + +} // namespace LightTable diff --git a/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Table.cc b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Table.cc new file mode 100644 index 000000000..abaa5fdd0 --- /dev/null +++ b/Ubiquitous/RT-Thread_Fusion_XiUOS/aiit_board/k210/tablestorage/src/storage/Table.cc @@ -0,0 +1,639 @@ +/** + * @file Table.cc + * @brief Table + * @version 0.1 + * @author SYS Lab + * @date 2022.11.01 + */ + +#include "Table.h" + +namespace LightTable { + +Table::Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + std::vector schemaEntrys, + bool usePrimaryKeyIndex) + : prefetchBlockManager(firstBlockID, segmentID, segmentType), + schema(schemaEntrys), + rowMap(), + tupleNum(0), + t(time(0)), + indexLocation{TABLE1_INDEX_BLOCKID, META_ENTRY_NUM}, + metaLogLocation{TABLE1_META_LOG_BLOCKID, META_ENTRY_NUM}, + indexLogLocation{TABLE1_INDEX_LOG_BLOCKID, META_ENTRY_NUM}, + dataLogLocation{TABLE1_DATA_LOG_BLOCKID, META_ENTRY_NUM} { + this->tableID = tableID; + memcpy(this->tableName, tableName, sizeof(tableName) + 1); + this->usePrimaryKeyIndex = usePrimaryKeyIndex; + std::map allSchemaEntrys; + schema.queryAllEntry(allSchemaEntrys); +} + +Table::Table(uint64_t tableID, const char *tableName, uint64_t firstBlockID, + uint64_t segmentID, SegmentType segmentType, + bool usePrimaryKeyIndex) + : prefetchBlockManager(firstBlockID, segmentID, segmentType), + schema(), + rowMap() { + this->tableID = tableID; + memcpy(this->tableName, tableName, sizeof(tableName) + 1); + // this->buf = buf; + // this->queryCache = queryCache; + // this->blockPreload = blockPreload; + this->usePrimaryKeyIndex = usePrimaryKeyIndex; +} + +uint32_t Table::drop() { + uint32_t ret = SUCCESS; + + ret = truncate(); + if (ret != SUCCESS) { + return ret; + } + + schema.drop(); + + // std::map allSchemaEntrys; + // schema.queryAllEntry(allSchemaEntrys); + // uint64_t columnCount = allSchemaEntrys.size(); + // uint64_t length = 10 + columnCount * (SCHEMA_ENTRY_SERIALIZED_LENGTH + 1); + // char *schemaData = new char[length]; + // uint32_t size = 0; + // MetaHandle::serialize(allSchemaEntrys, tableID, schemaData, size); + // MetaBufferItem *schemaMetaItem = new MetaBufferItem(tableID, schemaData, + // size); buf->append(schemaMetaItem); delete[] schemaData; + + return SUCCESS; +} + +// uint32_t Table::truncate() { +// uint32_t size = 0; +// char *pbmData; +// MetaBufferItem *pbmMeta; +// char *hashTableData; +// MetaBufferItem *hashTableMeta; +// std::map entrys; +// prefetchBlockManager.getAllPrefetchBlockEntrys(entrys); +// std::map::iterator +// pbmIter = entrys.begin(); +// while (pbmIter != entrys.end()) { +// prefetchBlockManager.lockBlock(pbmIter->first); +// prefetchBlockManager.setOffset(pbmIter->first, 0); +// prefetchBlockManager.unlockBlock(pbmIter->first); +// pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH]; +// MetaHandle::serialize(pbmIter->second, tableID, pbmData, size); +// pbmMeta = new MetaBufferItem(tableID, pbmData, size); +// // buf->append(pbmMeta); +// pbmIter++; +// } + +// std::vector buckets; +// hashTable.getAllBuckets(buckets); +// for (uint32_t i = 0; i < buckets.size(); i++) { +// std::map bucketItems; +// buckets[i]->getAllBucketItems(bucketItems); +// std::map::iterator itemIter; +// itemIter = bucketItems.begin(); +// while (itemIter != bucketItems.end()) { +// itemIter->second.blockID = 0; +// hashTableData = new char[ROWMAP_SERIALIZED_LENGTH]; +// MetaHandle::serialize( +// std::pair(itemIter->first, itemIter->second), +// tableID, hashTableData, size); +// hashTableMeta = new MetaBufferItem(tableID, hashTableData, size); +// // buf->append(hashTableMeta); +// itemIter = bucketItems.erase(itemIter); +// itemIter++; +// } +// } + +// return SUCCESS; +// } + +uint32_t Table::parsePrimaryKey(const uint8_t *rowData, char *primaryKeyData) { + if (strncmp(schema.getPrimaryKeySchema().type, "uint64_t", 8) == 0) { + uint64_t primaryKeyI64 = 0; + memcpy(&primaryKeyI64, rowData, schema.getPrimaryKeySchema().length); + sprintf(primaryKeyData, "%ld", primaryKeyI64); + } else if (strncmp(schema.getPrimaryKeySchema().type, "string", 6) == 0) { + memcpy(primaryKeyData, rowData, schema.getPrimaryKeySchema().length); + } else { + return TYPE_INVALID; + } + return SUCCESS; +} + +uint32_t Table::insertRow(const uint8_t *rowData) { + uint32_t ret = SUCCESS; + uint64_t blockID = 0; + uint64_t blockOffset = 0; + uint8_t blockData[BLOCK_SIZE]; + tupleNum++; + t = time(0); + +#ifndef YCSB_TEST + blockID = prefetchBlockManager.blockAllocate(schema.getEntrySize()); + while (blockID == 0) { + blockID = prefetchBlockManager.blockAllocate(schema.getEntrySize()); + } + ret = prefetchBlockManager.getOffset(blockID, blockOffset); + if (ret != SUCCESS) { + // TODO allocate new seg + return ret; + } +#else + blockID = prefetchBlockManager.getNextBlock(); +#endif + + if (blockOffset != 0) { + Driver::read(blockData, blockID); + } + + memcpy(blockData + blockOffset, rowData, schema.getEntrySize()); +#ifdef SDCARD_TEST + start_time = std::chrono::steady_clock::now(); +#endif + Driver::write(blockData, blockID); +#ifdef SDCARD_TEST + for (int i = 0; i < SDCARD_TEST_NUM; ++i) + Driver::write(blockData, SDCARD_TEST_WRITE_BLOCKID + 100 * i); + end_time = std::chrono::steady_clock::now(); + diff_sdcard_write = std::chrono::duration_cast( + end_time - start_time) + .count(); +#endif + + char *primaryKeyData = new char[schema.getPrimaryKeySchema().length]; + ret = parsePrimaryKey(rowData, primaryKeyData); + if (ret != SUCCESS) { + delete[] primaryKeyData; + prefetchBlockManager.unlockBlock(blockID); + return ret; + } + + uint64_t key = hashTable.getMapKey(primaryKeyData); + uint32_t bucketID = hashTable.hashToBucket(key); + RowLocation rowLocation = {blockID, blockOffset}; + ret = hashTable.addItem(bucketID, key, rowLocation); + + if (ret != SUCCESS) { + delete[] primaryKeyData; + prefetchBlockManager.unlockBlock(blockID); + return ret; + } + +#ifdef TABLE_STORAGE_SECOND_INDEX + ret = secondaryIndex.insert(primaryKeyData, + schema.getPrimaryKeySchema().length, rowLocation); + if (ret != SUCCESS) { + delete[] primaryKeyData; + prefetchBlockManager.unlockBlock(blockID); + return ret; + } +#endif + +#ifndef YCSB_TEST + ret = prefetchBlockManager.advanceOffset(blockID, schema.getEntrySize()); + prefetchBlockManager.setBlockState(blockID, PREFETCH_BLOCK_STATUS_IDLE); +#endif + + delete[] primaryKeyData; + + return ret; +} + +uint32_t Table::insertRow_logging(const uint8_t *rowData) { + uint32_t ret = SUCCESS; + uint64_t blockID = 0; + uint64_t blockOffset = 0; + + tupleNum++; + t = time(0); + + char *primaryKeyData = new char[schema.getPrimaryKeySchema().length]; + ret = parsePrimaryKey(rowData, primaryKeyData); + if (ret != SUCCESS) { + delete[] primaryKeyData; + prefetchBlockManager.unlockBlock(blockID); + return ret; + } + + uint64_t key = hashTable.getMapKey(primaryKeyData); + uint32_t bucketID = hashTable.hashToBucket(key); + RowLocation rowLocation = {blockID, blockOffset}; + + ret = hashTable.addItem(bucketID, key, rowLocation); + if (ret != SUCCESS) { + delete[] primaryKeyData; + prefetchBlockManager.unlockBlock(blockID); + return ret; + } + + metaLogEntry metaEntry{.tableID = tableID, .tupleNum = tupleNum, .t = t}; + + if (metaLogLocation.emptySlotNum != 0) { + memcpy(metaLog + (META_ENTRY_SIZE * + (META_ENTRY_NUM - metaLogLocation.emptySlotNum)), + &metaEntry, sizeof(metaLogEntry)); + } else { + metaLogLocation.blockID++; + metaLogLocation.emptySlotNum = META_ENTRY_NUM; + memset(metaLog, 0, BLOCK_SIZE); + memcpy(metaLog, &metaEntry, sizeof(metaLogEntry)); + } + Driver::write(metaLog, metaLogLocation.blockID); + metaLogLocation.emptySlotNum--; + + uint32_t size = 0; + char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH]; +// MetaHandle::serialize(std::pair(key, rowLocation), +// tableID, hashTableMetaData, size); +// MetaBufferItem *hashTableMeta = +// new MetaBufferItem(tableID, hashTableMetaData, size); +// if (indexLogLocation.emptySlotNum != 0) { +// memcpy(indexLog + (META_ENTRY_SIZE * +// (META_ENTRY_NUM - indexLogLocation.emptySlotNum)), +// hashTableMeta->metaItem, +// META_ENTRY_SIZE > hashTableMeta->metaItemSize +// ? hashTableMeta->metaItemSize +// : META_ENTRY_SIZE); +// } else { +// indexLogLocation.blockID++; +// indexLogLocation.emptySlotNum = META_ENTRY_NUM; +// memset(indexLog, 0, BLOCK_SIZE); +// memcpy(indexLog, hashTableMeta->metaItem, +// META_ENTRY_SIZE > hashTableMeta->metaItemSize +// ? hashTableMeta->metaItemSize +// : META_ENTRY_SIZE); +// } + Driver::write(indexLog, indexLogLocation.blockID); + indexLogLocation.emptySlotNum--; + + memcpy(metaData, &tupleNum, 8); + memcpy(metaData + 8, &t, sizeof(std::time_t)); + Driver::write(metaData, TABLE1_META_BLOCKID); + +// if (indexLocation.emptySlotNum != 0) { +// memcpy(indexData + (META_ENTRY_SIZE * +// (META_ENTRY_NUM - indexLocation.emptySlotNum)), +// hashTableMeta->metaItem, +// META_ENTRY_SIZE > hashTableMeta->metaItemSize +// ? hashTableMeta->metaItemSize +// : META_ENTRY_SIZE); +// } else { +// indexLocation.blockID++; +// indexLocation.emptySlotNum = META_ENTRY_NUM; +// memset(indexData, 0, BLOCK_SIZE); +// memcpy(indexData, hashTableMeta->metaItem, +// META_ENTRY_SIZE > hashTableMeta->metaItemSize +// ? hashTableMeta->metaItemSize +// : META_ENTRY_SIZE); +// } + Driver::write(indexData, indexLocation.blockID); + indexLocation.emptySlotNum--; + + uint8_t blockData[BLOCK_SIZE]; + blockID = dataLogLocation.blockID; + memcpy(blockData, rowData, schema.getEntrySize()); + Driver::write(blockData, blockID); + dataLogLocation.blockID++; + + blockID = prefetchBlockManager.getNextBlock(); + if (blockOffset != 0) { + Driver::read(blockData, blockID); + } + memcpy(blockData + blockOffset, rowData, schema.getEntrySize()); + Driver::write(blockData, blockID); + + delete[] hashTableMetaData; +// delete hashTableMeta; + delete[] primaryKeyData; + + return ret; +} + +uint32_t Table::deleteRow(const char *primaryKey) { + uint32_t ret = SUCCESS; + + RowLocation rowLocation; + ret = locateRow(primaryKey, rowLocation); + if (ret != SUCCESS) { + return ret; + } + uint64_t deleteBlockID = rowLocation.blockID; + uint64_t deleteRowOffset = rowLocation.rowOffset; + + while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS) + ; + uint64_t currentOffset = 0; + ret = prefetchBlockManager.getOffset(rowLocation.blockID, currentOffset); + uint64_t key = hashTable.getMapKey(primaryKey); + + if (rowLocation.rowOffset + schema.getEntrySize() != currentOffset) { + ret = deleteRowData(key, rowLocation); + if (ret != SUCCESS) { + return ret; + } + } + + uint32_t size = 0; + uint32_t bucketID = hashTable.hashToBucket(key); + hashTable.deleteItem(bucketID, key); + char *hashTableMetaData = new char[ROWMAP_SERIALIZED_LENGTH]; + rowLocation.blockID = 0; + // MetaHandle::serialize(std::pair(key, rowLocation), + // tableID, hashTableMetaData, size); + // MetaBufferItem *hashTableMeta= new MetaBufferItem(tableID, + // hashTableMetaData, + // size); + // buf->append(hashTableMeta); + + if (deleteRowOffset + schema.getEntrySize() != currentOffset) { + std::map locationItems; + hashTable.refreshRowLocations(deleteBlockID, deleteRowOffset, + schema.getEntrySize(), locationItems); + // std::map::iterator iter = locationItems.begin(); + // while (iter != locationItems.end()) { + // MetaHandle::serialize(std::pair(iter->first, + // iter->second), tableID, hashTableMetaData, + // size); + // MetaBufferItem *nextMeta= new MetaBufferItem(tableID, + // hashTableMetaData, + // size); + // buf->append(nextMeta); + // } + } + + uint64_t newOffset = currentOffset - schema.getEntrySize(); + prefetchBlockManager.setOffset(deleteBlockID, newOffset); + prefetchBlockManager.unlockBlock(deleteBlockID); + PrefetchBlockManager::PrefetchBlockManagerEntry blockEntry; + prefetchBlockManager.getPrefetchBlockEntry(deleteBlockID, blockEntry); + // char *pbmData = new char[PREFETCH_BLOCK_SERIALIZED_LENGTH]; + // MetaHandle::serialize(blockEntry, tableID, pbmData, size); + // MetaBufferItem *pbmMeta = new MetaBufferItem(tableID, pbmData, size); + // buf->append(pbmMeta); + + return SUCCESS; +} + +uint32_t Table::deleteRowData(uint64_t key, RowLocation rowLocation) { + uint8_t blockData[BLOCK_SIZE]; + Driver::read(blockData, rowLocation.blockID); + + uint64_t start = rowLocation.rowOffset; + uint64_t nextRow = start + schema.getEntrySize(); + memcpy(blockData + start, blockData + nextRow, BLOCK_SIZE - nextRow); + + Driver::write(blockData, rowLocation.blockID); + + return SUCCESS; +} + +uint32_t Table::updateRow(const char *primaryKey, const uint8_t *rowData) { + uint32_t ret = SUCCESS; + + RowLocation rowLocation; + ret = locateRow(primaryKey, rowLocation); + if (ret == BUCKET_ITEM_NOT_FOUND) { + return insertRow(rowData); + } else if (ret != SUCCESS) { + return ret; + } + + uint8_t blockData[BLOCK_SIZE]; + + while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS) + ; + Driver::read(blockData, rowLocation.blockID); + + // char *undoTuple = new char[schema.getEntrySize()]; + // memcpy(undoTuple, blockData+rowLocation.rowOffset, schema.getEntrySize()); + // UndoLogEntry *logEntry = new UndoLogEntry(this->tableID, primaryKey, + // schema.getPrimaryKeyLength(), + // undoTuple, schema.getEntrySize(), + // rowLocation.blockID, rowLocation.rowOffset); + // buf->append(logEntry); + + memcpy(blockData + rowLocation.rowOffset, rowData, schema.getEntrySize()); + + if (SUCCESS != Driver::write(blockData, rowLocation.blockID)) { + // memcpy(blockData + rowLocation.rowOffset, undoTuple, + // schema.getEntrySize()); + // ret = UPDATE_TUPLE_ERROR; + } + + // logEntry->expireUndoLog(); + prefetchBlockManager.unlockBlock(rowLocation.blockID); + return ret; +} + +uint32_t Table::locateRow(const char *primaryKey, RowLocation &rowLocation) { + uint32_t ret = SUCCESS; + + uint64_t key = hashTable.getMapKey(primaryKey); + uint32_t bucketID = hashTable.hashToBucket(key); + + ret = hashTable.getRowLocation(bucketID, key, rowLocation); + return ret; +} + +uint32_t Table::selectRow(const char *primaryKey, uint8_t *rowData) { + RowLocation rowLocation; + return selectRow(primaryKey, rowData, rowLocation); +} + +uint32_t Table::selectRow(const char *primaryKey, uint8_t *rowData, + RowLocation &rowLocation) { + uint32_t ret = SUCCESS; + uint8_t blockData[BLOCK_SIZE]; + + ret = locateRow(primaryKey, rowLocation); + if (ret != SUCCESS) { + return ret; + } + +#ifndef YCSB_TEST + while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS) + ; +#endif + +#ifdef SDCARD_TEST + start_time = std::chrono::steady_clock::now(); +#endif + Driver::read(blockData, rowLocation.blockID); +#ifdef SDCARD_TEST + for (int i = 0; i < SDCARD_TEST_NUM; ++i) + Driver::read(blockData, SDCARD_TEST_READ_BLOCKID + 100 * i); + end_time = std::chrono::steady_clock::now(); + diff_sdcard_read = (std::chrono::duration_cast( + end_time - start_time) + .count()); +#endif +#ifndef YCSB_TEST + prefetchBlockManager.unlockBlock(rowLocation.blockID); +#endif + + ret = getRowFromBlock(primaryKey, rowData, blockData, rowLocation); + + return ret; +} + +uint32_t Table::getRowFromBlock(const char *primaryKey, uint8_t *rowData, + const uint8_t *blockData, + const RowLocation rowLocation) { + uint32_t ret = SUCCESS; + + char *primaryKeyData = new char[schema.getPrimaryKeySchema().length]; + if (rowLocation.rowOffset + schema.getEntrySize() > BLOCK_SIZE) { + delete[] primaryKeyData; + return ROWLOCATION_INVALID; + } + + ret = parsePrimaryKey(blockData + rowLocation.rowOffset, primaryKeyData); + if (ret != SUCCESS) { + delete[] primaryKeyData; + return ret; + } + + if (strncmp(primaryKeyData, primaryKey, + schema.getPrimaryKeySchema().length) != 0) { + delete[] primaryKeyData; + return ERROR_TABLE; + } + + memcpy(rowData, blockData + rowLocation.rowOffset, schema.getEntrySize()); + + delete[] primaryKeyData; + return SUCCESS; +} + +uint32_t Table::selectColumnItem(const char *primaryKey, const char *columnName, + uint8_t *columnData) { + uint32_t ret = SUCCESS; + + uint8_t *rowData = new uint8_t[schema.getEntrySize()]; + RowLocation rowLocation; + ret = selectRow(primaryKey, rowData, rowLocation); + if (ret != SUCCESS) { + delete[] rowData; + return ret; + } + + uint64_t columnOffset = 0; + uint64_t columnID = 0; + uint32_t columnLength = 0; + ret = getColumnOffset(columnName, columnID, columnLength, columnOffset); + + memcpy(columnData, rowData + columnOffset, columnLength); + + delete[] rowData; + return SUCCESS; +} + +uint32_t Table::updateColumnItem(const char *primaryKey, const char *columnName, + const uint8_t *columnData) { + uint32_t ret = SUCCESS; + + uint8_t *blockData = new uint8_t[BLOCK_SIZE]; + RowLocation rowLocation; + ret = locateRow(primaryKey, rowLocation); + if (ret != SUCCESS) { + return ret; + } + +#ifndef YCSB_TEST + while (prefetchBlockManager.lockBlock(rowLocation.blockID) != SUCCESS) + ; +#endif + Driver::read(blockData, rowLocation.blockID); + + // char *undoTuple = new char[schema.getEntrySize()]; + // memcpy(undoTuple, blockData+rowLocation.rowOffset, schema.getEntrySize()); + // UndoLogEntry *logEntry = new UndoLogEntry(this->tableID, primaryKey, + // schema.getPrimaryKeyLength(), + // undoTuple, schema.getEntrySize(), + // rowLocation.blockID, rowLocation.rowOffset); + // buf->append(logEntry); + + uint64_t columnOffset, columnID; + uint32_t columnLength; + ret = getColumnOffset(columnName, columnID, columnLength, columnOffset); + + uint64_t columnStart = rowLocation.rowOffset + columnOffset; + memcpy(blockData + columnStart, columnData, columnLength); + + if (SUCCESS != Driver::write(blockData, rowLocation.blockID)) { + // memcpy(blockData + rowLocation.rowOffset, undoTuple, + // schema.getEntrySize()); + // ret = UPDATE_TUPLE_ERROR; + } + + // logEntry->expireUndoLog(); +#ifndef YCSB_TEST + prefetchBlockManager.unlockBlock(rowLocation.blockID); +#endif + + delete[] blockData; + return SUCCESS; +} + +uint32_t Table::updateColumnItem_logging(const char *primaryKey, + const char *columnName, + const uint8_t *columnData) { + // TODO + return SUCCESS; +} + +uint32_t Table::getColumnOffset(const char *columnName, uint64_t &columnID, + uint32_t &columnLength, uint64_t &offset) { + uint32_t ret = SUCCESS; + offset = 0; + columnID = 0; + columnLength = 0; + + ret = getColumnID(columnName, columnID); + if (ret != SUCCESS) { + return ret; + } + + std::map schemaEntrys; + ret = schema.queryAllEntry(schemaEntrys); + if (ret != SUCCESS) { + return ret; + } + + columnLength = schemaEntrys[columnID].length; + for (uint64_t i = 1; i < columnID; i++) { + offset += schemaEntrys[i].length; + } + + return SUCCESS; +} + +uint64_t Table::getRowCount() { return hashTable.getItemCount(); } + +uint64_t Table::getTableID() { return tableID; } + +char *Table::getTableName() { return tableName; } + +uint32_t Table::setTableID(uint64_t tableID) { + this->tableID = tableID; + return SUCCESS; +} + +uint32_t Table::setTableName(const char *tableName) { + memcpy(this->tableName, tableName, sizeof(tableName) + 1); + return SUCCESS; +} + +uint32_t Table::getColumnID(const char *columnName, uint64_t &columnID) { + return schema.getColumnID(columnName, columnID); +} + +Schema &Table::getSchema() { return schema; } + +HashTable &Table::getHashTable() { return hashTable; } + +} // namespace LightTable diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/Kconfig b/Ubiquitous/XiZi/resources/ethernet/netdev/Kconfig new file mode 100755 index 000000000..ef4e4a99c --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/Kconfig @@ -0,0 +1,3 @@ +menuconfig APP_USING_NETDEV + bool "Enable network interface device" + default y diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/Makefile b/Ubiquitous/XiZi/resources/ethernet/netdev/Makefile new file mode 100755 index 000000000..c93baad5a --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/Makefile @@ -0,0 +1,3 @@ +SRC_DIR := src + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/include/arpa/inet.h b/Ubiquitous/XiZi/resources/ethernet/netdev/include/arpa/inet.h new file mode 100755 index 000000000..e8d0ff162 --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/include/arpa/inet.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2015-02-17 Bernard First version + */ + +/** +* @file inet.h +* @brief using in webnet +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-09-15 +*/ + +#ifndef __INET_H__ +#define __INET_H__ + +#include + +#endif diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/include/netdev.h b/Ubiquitous/XiZi/resources/ethernet/netdev/include/netdev.h new file mode 100755 index 000000000..82b6fd09c --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/include/netdev.h @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2019-03-18 ChenYong First version + */ + +/** +* @file netdev.h +* @brief Structure and function declarations of device and ipaddr +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-09-15 +*/ + +#ifndef __NETDEV_H__ +#define __NETDEV_H__ + + +#include +#include "netdev_ipaddr.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* */ +#define netdev_container_of(ptr, type, member) ((type *)((char *)(ptr) - (unsigned long)(&((type *)0)->member))) +#define netdev_slist_entry(node, type, member) netdev_container_of(node, type, member) +#define netdev_list_entry(node, type, member) netdev_container_of(node, type, member) + +/* the maximum of all used hardware address lengths */ +#ifndef NETDEV_HWADDR_MAX_LEN +#define NETDEV_HWADDR_MAX_LEN 8U +#endif + +/* the maximum of dns server number supported */ +#ifndef NETDEV_DNS_SERVERS_NUM +#define NETDEV_DNS_SERVERS_NUM 2U +#endif + +#if NETDEV_IPV6 +/* the maximum of dns server number supported */ +#ifndef NETDEV_IPV6_NUM_ADDRESSES +#define NETDEV_IPV6_NUM_ADDRESSES 3U +#endif +#endif /* NETDEV_IPV6 */ + +/* whether the network interface device is 'up' (set by the network interface driver or application) */ +#define NETDEV_FLAG_UP 0x01U +/* if set, the network interface device has broadcast capability, only supported in the 'lwIP' stack */ +#define NETDEV_FLAG_BROADCAST 0x02U +/* if set, the network interface device has an active link (set by the network interface driver) */ +#define NETDEV_FLAG_LINK_UP 0x04U +/* if set, the network interface device is an ethernet device using ARP, only supported in the 'lwIP' stack */ +#define NETDEV_FLAG_ETHARP 0x08U +/* if set, the network interface device is an ethernet device, only supported in the 'lwIP' stack */ +#define NETDEV_FLAG_ETHERNET 0x10U +/* if set, the network interface device has IGMP capability, only supported in the 'lwIP' stack */ +#define NETDEV_FLAG_IGMP 0x20U +/* if set, the network interface device has MLD6 capability, only supported in the 'lwIP' stack */ +#define NETDEV_FLAG_MLD6 0x40U +/* if set, the network interface device connected to internet successfully (set by the network interface driver) */ +#define NETDEV_FLAG_INTERNET_UP 0x80U +/* if set, the network interface device has DHCP capability (set by the network interface device driver or application) */ +#define NETDEV_FLAG_DHCP 0x100U + +enum netdev_cb_type +{ + NETDEV_CB_ADDR_IP, /* IP address */ + NETDEV_CB_ADDR_NETMASK, /* subnet mask */ + NETDEV_CB_ADDR_GATEWAY, /* netmask */ + NETDEV_CB_ADDR_DNS_SERVER, /* dns server */ + NETDEV_CB_STATUS_UP, /* changed to 'up' */ + NETDEV_CB_STATUS_DOWN, /* changed to 'down' */ + NETDEV_CB_STATUS_LINK_UP, /* changed to 'link up' */ + NETDEV_CB_STATUS_LINK_DOWN, /* changed to 'link down' */ + NETDEV_CB_STATUS_INTERNET_UP, /* changed to 'internet up' */ + NETDEV_CB_STATUS_INTERNET_DOWN, /* changed to 'internet down' */ + NETDEV_CB_STATUS_DHCP_ENABLE, /* enable DHCP capability */ + NETDEV_CB_STATUS_DHCP_DISABLE, /* disable DHCP capability */ +}; + +struct netdev; + +/* function prototype for network interface device status or address change callback functions */ +typedef void (*netdev_callback_fn )(struct netdev *netdev, enum netdev_cb_type type); + +struct netdev_ops; + +/* network interface device object */ +struct netdev_slist_node +{ + struct netdev_slist_node *next; /**< point to next node. */ +}; + + +typedef struct netdev_slist_node netdev_slist_t; /**< Type for single list. */ + + +#define NETDEV_NAME_MAX 8 +struct netdev +{ + netdev_slist_t list;// + + char name[NETDEV_NAME_MAX]; /* network interface device name */ + ip_addr_t ip_addr; /* IP address */ + ip_addr_t netmask; /* subnet mask */ + ip_addr_t gw; /* gateway */ +#if NETDEV_IPV6 + ip_addr_t ip6_addr[NETDEV_IPV6_NUM_ADDRESSES]; /* array of IPv6 addresses */ +#endif /* NETDEV_IPV6 */ + ip_addr_t dns_servers[NETDEV_DNS_SERVERS_NUM]; /* DNS server */ + uint8_t hwaddr_len; /* hardware address length */ + uint8_t hwaddr[NETDEV_HWADDR_MAX_LEN]; /* hardware address */ + + uint16_t flags; /* network interface device status flag */ + uint16_t mtu; /* maximum transfer unit (in bytes) */ + const struct netdev_ops *ops; /* network interface device operations */ + + netdev_callback_fn status_callback; /* network interface device flags change callback */ + netdev_callback_fn addr_callback; /* network interface device address information change callback */ + + + void *user_data; /* user-specific data */ +}; + +/* The list of network interface device */ +extern struct netdev *netdev_list; +/* The default network interface device */ +extern struct netdev *netdev_default; + +/* The network interface device ping response object */ +struct netdev_ping_resp +{ + ip_addr_t ip_addr; /* response IP address */ + uint16_t data_len; /* response data length */ + uint16_t ttl; /* time to live */ + uint32_t ticks; /* response time, unit tick */ + void *user_data; /* user-specific data */ +}; + +/* The network interface device operations */ +struct netdev_ops +{ + /* set network interface device hardware status operations */ + int (*set_up)(struct netdev *netdev); + int (*set_down)(struct netdev *netdev); + + /* set network interface device address information operations */ + int (*set_addr_info)(struct netdev *netdev, ip_addr_t *ip_addr, ip_addr_t *netmask, ip_addr_t *gw); + int (*set_dns_server)(struct netdev *netdev, uint8_t dns_num, ip_addr_t *dns_server); + int (*set_dhcp)(struct netdev *netdev, _Bool is_enabled); + + + + /* set default network interface device in current network stack*/ + int (*set_default)(struct netdev *netdev); +}; + +/* The network interface device registered and unregistered*/ +int netdev_register(struct netdev *netdev, const char *name, void *user_data); +int netdev_unregister(struct netdev *netdev); + +/* Get network interface device object */ +struct netdev *netdev_get_first_by_flags(uint16_t flags); +struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr); +struct netdev *netdev_get_by_name(const char *name); + + + +/* Set default network interface device in list */ +void netdev_set_default(struct netdev *netdev); + +/* Set network interface device status */ +int netdev_set_up(struct netdev *netdev); +int netdev_set_down(struct netdev *netdev); +int netdev_dhcp_enabled(struct netdev *netdev, _Bool is_enabled); + +/* Get network interface device status */ +#define netdev_is_up(netdev) (((netdev)->flags & NETDEV_FLAG_UP) ? (uint8_t)1 : (uint8_t)0) +#define netdev_is_link_up(netdev) (((netdev)->flags & NETDEV_FLAG_LINK_UP) ? (uint8_t)1 : (uint8_t)0) +#define netdev_is_internet_up(netdev) (((netdev)->flags & NETDEV_FLAG_INTERNET_UP) ? (uint8_t)1 : (uint8_t)0) +#define netdev_is_dhcp_enabled(netdev) (((netdev)->flags & NETDEV_FLAG_DHCP) ? (uint8_t)1 : (uint8_t)0) + +/* Set network interface device address */ +int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ipaddr); +int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask); +int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw); +int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); + +/* Set network interface device callback, it can be called when the status or address changed */ +void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback); +void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback); + +/* Set network interface device status and address, this function can only be called in the network interface device driver */ +void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ipaddr); +void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask); +void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw); +void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server); +void netdev_low_level_set_status(struct netdev *netdev, _Bool is_up); +void netdev_low_level_set_link_status(struct netdev *netdev, _Bool is_up); +void netdev_low_level_set_internet_status(struct netdev *netdev, _Bool is_up); +void netdev_low_level_set_dhcp_status(struct netdev *netdev, _Bool is_enable); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETDEV_H__ */ diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/include/netdev_ipaddr.h b/Ubiquitous/XiZi/resources/ethernet/netdev/include/netdev_ipaddr.h new file mode 100755 index 000000000..4a8eaa381 --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/include/netdev_ipaddr.h @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-05-18 ChenYong First version + */ + +/** +* @file netdev_ipaddr.h +* @brief Structure and function declarations of device and ipaddr +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-09-15 +*/ + +/**modified: + * + * delete some functions already in lwip + */ + +#ifndef __NETDEV_IPADDR_H__ +#define __NETDEV_IPADDR_H__ + +#include + + +#ifdef __cplusplus +extern "C" { +#endif + +#if NETDEV_IPV4 +/** IPv4 only: set the IP address given as an u32_t */ +#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) +/** IPv4 only: get the IP address as an u32_t */ +#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) + +#define IP4ADDR_STRLEN_MAX 16 +#endif /* NETIF_IPV4 */ + +#define PP_NTOHS(x) PP_HTONS(x) +#define PP_NTOHL(x) PP_HTONL(x) + +/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED + to prevent this code from redefining it. */ +#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED) +typedef uint32_t in_addr_t; +#endif + +#if NETDEV_IPV4 +struct in_addr +{ + in_addr_t s_addr; +}; + +typedef struct ip4_addr +{ + uint32_t addr; +} ip4_addr_t; + +/** 255.255.255.255 */ +#define IPADDR_NONE ((uint32_t)0xffffffffUL) +/** 127.0.0.1 */ +#define IPADDR_LOOPBACK ((uint32_t)0x7f000001UL) +/** 0.0.0.0 */ +#define IPADDR_ANY ((uint32_t)0x00000000UL) +/** 255.255.255.255 */ +#define IPADDR_BROADCAST ((uint32_t)0xffffffffUL) + +/** 255.255.255.255 */ +#define INADDR_NONE IPADDR_NONE +/** 127.0.0.1 */ +#define INADDR_LOOPBACK IPADDR_LOOPBACK +/** 0.0.0.0 */ +#define INADDR_ANY IPADDR_ANY +/** 255.255.255.255 */ +#define INADDR_BROADCAST IPADDR_BROADCAST + +#define IPADDR_BROADCAST_STRING "255.255.255.255" + +/** Copy IP address - faster than ip4_addr_set: no NULL check */ +#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr) +#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) +/** Safely copy one IP address to another (src may be NULL) */ +#define ip4_addr_set(dest, src) ((dest)->addr = ((src) == NULL ? 0 : (src)->addr)) +/** Set complete address to zero */ +#define ip4_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) +/** Set address to IPADDR_ANY (no need for htonl()) */ +#define ip4_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) +#define ip4_addr_isany_val(ipaddr) ((ipaddr).addr == IPADDR_ANY) +#define ip4_addr_isany(ipaddr) ((ipaddr) == NULL || ip4_addr_isany_val(*(ipaddr))) + +in_addr_t netdev_ipaddr_addr(const char *cp); +int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr); +char *netdev_ip4addr_ntoa(const ip4_addr_t *addr); +char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen); +#endif /* NETIF_IPV4 */ + +#if NETDEV_IPV6 +struct in6_addr +{ + union + { + uint32_t u32_addr[4]; + uint8_t u8_addr[16]; + } un; +#define s6_addr un.u8_addr +}; + +typedef struct ip6_addr +{ + uint32_t addr[4]; +#ifdef NETDEV_IPV6_SCOPES + uint8_t zone; +#endif /* NETDEV_IPV6_SCOPES */ +} ip6_addr_t; + +/** This macro can be used to initialize a variable of type struct in6_addr + to the IPv6 wildcard address. */ +#define IN6ADDR_ANY_INIT {{{0,0,0,0}}} +/** This macro can be used to initialize a variable of type struct in6_addr + to the IPv6 loopback address. */ +#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}} + +/** This variable is initialized by the system to contain the wildcard IPv6 address. + */ +extern const struct in6_addr in6addr_any; + +#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ + ((addr1)->addr[1] == (addr2)->addr[1]) && \ + ((addr1)->addr[2] == (addr2)->addr[2]) && \ + ((addr1)->addr[3] == (addr2)->addr[3])) +/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ +#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ + (dest).addr[1] = (src).addr[1]; \ + (dest).addr[2] = (src).addr[2]; \ + (dest).addr[3] = (src).addr[3];}while(0) +/** Safely copy one IPv6 address to another (src may be NULL) */ +#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ + (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ + (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ + (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0) +/** Set complete address to zero */ +#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ + (ip6addr)->addr[1] = 0; \ + (ip6addr)->addr[2] = 0; \ + (ip6addr)->addr[3] = 0;}while(0) +/** Set address to ipv6 'any' (no need for lwip_htonl()) */ +#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) +#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \ + ((ip6addr).addr[1] == 0) && \ + ((ip6addr).addr[2] == 0) && \ + ((ip6addr).addr[3] == 0)) +#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr))) + +int netdev_ip6addr_aton(const char *cp, ip6_addr_t *addr); +char *netdev_ip6addr_ntoa(const ip6_addr_t *addr); +char *netdev_ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen); +#endif /* NETIF_IPV6 */ + +#if NETDEV_IPV4 && NETDEV_IPV6 +/* A union struct for both IP version's addresses */ +typedef struct _ip_addr +{ + union + { + ip6_addr_t ip6; + ip4_addr_t ip4; + } u_addr; + /** @ref netdev_ip_addr_type */ + uint8_t type; +} ip_addr_t; + +#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0) +#define IP_SET_TYPE(ipaddr, iptype) do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0) +#define IP_GET_TYPE(ipaddr) ((ipaddr)->type) + +#define IP_IS_V4_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4) +#define IP_IS_V6_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6) +#define IP_IS_V4(ipaddr) (((ipaddr) == NULL) || IP_IS_V4_VAL(*(ipaddr))) +#define IP_IS_V6(ipaddr) (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr))) + +/** Convert generic ip address to specific protocol version */ +#define ip_2_ip6(ipaddr) (&((ipaddr)->u_addr.ip6)) +/** Convert generic ip address to specific protocol version */ +#define ip_2_ip4(ipaddr) (&((ipaddr)->u_addr.ip4)) + +#define ip_addr_copy(dest, src) do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \ + ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \ + ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); }}while(0) +#define ip_addr_cmp(addr1, addr2) ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \ + ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \ + ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2)))) +#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \ + ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \ + ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }}while(0) +#define ip_addr_set_zero(ipaddr) do{ ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0) +#define ip_addr_set_any(is_ipv6, ipaddr) do{ if(is_ipv6){ \ + ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \ + ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0) + +#define ip_addr_isany_val(ipaddr) ((IP_IS_V6_VAL(ipaddr)) ? \ + ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \ + ip4_addr_isany_val(*ip_2_ip4(&(ipaddr)))) +#define ip_addr_isany(ipaddr) ((IP_IS_V6(ipaddr)) ? \ + ip6_addr_isany(ip_2_ip6(ipaddr)) : \ + ip4_addr_isany(ip_2_ip4(ipaddr))) + +/* directly map this to the lwip internal functions */ +#define inet_addr(cp) netdev_ipaddr_addr(cp) +#define inet_aton(cp, addr) ((IP_IS_V6_VAL(*addr)) ? \ + netdev_ip6addr_aton(cp, ip_2_ip6(addr)) : \ + netdev_ip4addr_aton(cp, ip_2_ip4(addr))) +#define inet_ntoa(addr) ((IP_IS_V6_VAL(addr)) ? \ + netdev_ip6addr_ntoa(ip_2_ip6(&addr)) : \ + netdev_ip4addr_ntoa(ip_2_ip4(&addr))) +#define inet_ntoa_r(addr, buf, buflen) ((IP_IS_V6_VAL(addr)) ? \ + netdev_ip6addr_ntoa_r(ip_2_ip6(&addr), buf, buflen) : \ + netdev_ip4addr_ntoa_r(ip_2_ip4(&addr), buf, buflen)) +#elif NETDEV_IPV4 /* NETDEV_IPV4 */ + +typedef ip4_addr_t ip_addr_t; + +#define IP_SET_TYPE_VAL(ipaddr, iptype) +#define IP_SET_TYPE(ipaddr, iptype) +#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V4 + +#define ip_addr_copy(dest, src) ip4_addr_copy(dest, src) +#define ip_addr_cmp(addr1, addr2) ip4_addr_cmp(addr1, addr2) +#define ip_addr_set(dest, src) ip4_addr_set(dest, src) +#define ip_addr_set_zero(ipaddr) ip4_addr_set_zero(ipaddr) +#define ip_addr_set_any(is_ipv6, ipaddr) ip4_addr_set_any(ipaddr) +#define ip_addr_isany_val(ipaddr) ip4_addr_isany_val(ipaddr) +#define ip_addr_isany(ipaddr) ip4_addr_isany(ipaddr) + +/* directly map this to the lwip internal functions */ +#define inet_addr(cp) netdev_ipaddr_addr(cp) +#define inet_aton(cp, addr) netdev_ip4addr_aton(cp,(ip4_addr_t*)addr) +#define inet_ntoa(addr) netdev_ip4addr_ntoa((const ip4_addr_t*)&(addr)) +#define inet_ntoa_r(addr, buf, buflen) netdev_ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen) +#else /* NETDEV_IPV6 */ + +//typedef ip6_addr_t ip_addr_t; + +#define IP_SET_TYPE_VAL(ipaddr, iptype) +#define IP_SET_TYPE(ipaddr, iptype) +#endif /* NTDEV_IPV4 && NTDEV_IPV6 */ + + +const char *netdev_inet_ntop(int af, const void *src, char *dst, int32_t size); +int netdev_inet_pton(int af, const char *src, void *dst); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETDEV_IPADDR_H__ */ diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/src/Makefile b/Ubiquitous/XiZi/resources/ethernet/netdev/src/Makefile new file mode 100755 index 000000000..bf3fa4082 --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/src/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := netdev.c netdev_ipaddr.c + +include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/src/netdev.c b/Ubiquitous/XiZi/resources/ethernet/netdev/src/netdev.c new file mode 100755 index 000000000..1121f6de3 --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/src/netdev.c @@ -0,0 +1,834 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2022-03-18 ChenYong First version + */ + +/** +* @file netdev.c +* @brief functions of getting device address +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-09-15 +*/ + +#include +#include +#include +#include + +#include "../include/netdev_ipaddr.h" +#include "../include/netdev.h" + + +#define DBG_TAG "netdev" +#define DBG_LVL DBG_INFO + + +/* The list of network interface device */ +struct netdev *netdev_list = NULL; +/* The default network interface device */ +struct netdev *netdev_default = NULL; + +/** + * following four functions are basic operations on linked lists + */ +void netdev_slist_init(netdev_slist_t *l) +{ + l->next = NULL; +} + +void netdev_slist_append(netdev_slist_t *l, netdev_slist_t *n) +{ + struct netdev_slist_node *node; + + node = l; + while (node->next) node = node->next; + + /* append the node to the tail */ + node->next = n; + n->next = NULL; +} +netdev_slist_t *netdev_slist_next(netdev_slist_t *n) +{ + return n->next; +} + + +netdev_slist_t *netdev_slist_remove(netdev_slist_t *l, netdev_slist_t *n) +{ + /* remove slist head */ + struct netdev_slist_node *node = l; + while (node->next && node->next != n) node = node->next; + + /* remove node */ + if (node->next != (netdev_slist_t *)0) node->next = node->next->next; + + return l; +} + + + +/** + * This function will register network interface device and + * add it to network interface device list. + * + * @param netdev the network interface device object + * @param name the network interface device name + * @param user_data user-specific data + * + * @return 0: registered successfully + * -1: registered failed + */ + +int netdev_register(struct netdev *netdev, const char *name, void *user_data) +{ + long level; + uint16_t flags_mask; + uint16_t index; + + assert(netdev); + assert(name); + + /* clean network interface device */ + flags_mask = NETDEV_FLAG_UP | NETDEV_FLAG_LINK_UP | NETDEV_FLAG_INTERNET_UP | NETDEV_FLAG_DHCP; + netdev->flags &= ~flags_mask; + + ip_addr_set_zero(&(netdev->ip_addr)); + ip_addr_set_zero(&(netdev->netmask)); + ip_addr_set_zero(&(netdev->gw)); + + IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4); + IP_SET_TYPE_VAL(netdev->netmask, IPADDR_TYPE_V4); + IP_SET_TYPE_VAL(netdev->gw, IPADDR_TYPE_V4); +#if NETDEV_IPV6 + for (index = 0; index < NETDEV_IPV6_NUM_ADDRESSES; index++) + { + ip_addr_set_zero(&(netdev->ip6_addr[index])); + IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V6); + } +#endif /* NETDEV_IPV6 */ + for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++) + { + ip_addr_set_zero(&(netdev->dns_servers[index])); + IP_SET_TYPE_VAL(netdev->ip_addr, IPADDR_TYPE_V4); + } + netdev->status_callback = NULL; + netdev->addr_callback = NULL; + + if(strlen(name) > NETDEV_NAME_MAX) + { + char netdev_name[NETDEV_NAME_MAX + 1] = {0}; + + strncpy(netdev_name, name, NETDEV_NAME_MAX); + printf("netdev name[%s] length is so long that have been cut into [%s].", name, netdev_name); + } + + /* fill network interface device */ + strncpy(netdev->name, name, NETDEV_NAME_MAX); + netdev->user_data = user_data; + + /* initialize current network interface device single list */ + + + + + netdev_slist_init(&(netdev->list)); + + level = CriticalAreaLock(); + + if (netdev_list == NULL) + { + netdev_list = netdev; + netdev_default = netdev; + } + else + { + /* tail insertion */ + netdev_slist_append(&(netdev_list->list), &(netdev->list)); + } + + CriticalAreaUnLock(level); + + return 0; +} + +/** + * This function will unregister network interface device and + * delete it from network interface device list. + * + * @param netdev the network interface device object + * + * @return 0: unregistered successfully + * -1: unregistered failed + */ +int netdev_unregister(struct netdev *netdev) +{ + long level; + netdev_slist_t *node = NULL; + struct netdev *cur_netdev = NULL; + + assert(netdev); + + if (netdev_list == NULL) + { + return -1; + } + + level = CriticalAreaLock(); + + for (node = &(netdev_list->list); node; node = netdev_slist_next(node)) + { + cur_netdev = netdev_slist_entry(node, struct netdev, list); + if (cur_netdev == netdev) + { + /* find this network interface device in network interface device list */ + if (netdev_list == netdev && netdev_slist_next(&netdev_list->list) == NULL) + { + netdev_list = NULL; + } + else + { + netdev_slist_remove(&(netdev_list->list), &(cur_netdev->list)); + } + if (netdev_default == netdev) + { + netdev_default = netdev_list; + } + break; + } + } + CriticalAreaUnLock(level); + + if (cur_netdev == netdev) + { + + memset(netdev, 0, sizeof(*netdev)); + } + + return -1; +} + +/** + * This function will get the first network interface device + * with the flags in network interface device list. + * + * @param flags the network interface device flags + * + * @return != NULL: network interface device object + * NULL: get failed + */ +struct netdev *netdev_get_first_by_flags(uint16_t flags) +{ + long level; + netdev_slist_t *node = NULL; + struct netdev *netdev = NULL; + + if (netdev_list == NULL) + { + return NULL; + } + + level = CriticalAreaLock(); + + for (node = &(netdev_list->list); node; node = netdev_slist_next(node)) + { + netdev = netdev_slist_entry(node, struct netdev, list); + if (netdev && (netdev->flags & flags) != 0) + { + CriticalAreaUnLock(level); + return netdev; + } + } + + CriticalAreaUnLock(level); + + return NULL; +} + +/** + * This function will get the first network interface device + * in network interface device list by IP address. + * + * @param addr the network interface device IP address + * + * @return != NULL: network interface device object + * NULL: get failed + */ +struct netdev *netdev_get_by_ipaddr(ip_addr_t *ip_addr) +{ + long level; + netdev_slist_t *node = NULL; + struct netdev *netdev = NULL; + + if (netdev_list == NULL) + { + return NULL; + } + + level = CriticalAreaLock(); + + for (node = &(netdev_list->list); node; node = netdev_slist_next(node)) + { + netdev = netdev_slist_entry(node, struct netdev, list); + if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr)) + { + CriticalAreaUnLock(level); + return netdev; + } + } + + CriticalAreaUnLock(level); + + return NULL; +} + +/** + * This function will get network interface device + * in network interface device list by netdev name. + * + * @param name the network interface device name + * + * @return != NULL: network interface device object + * NULL: get failed + */ +struct netdev *netdev_get_by_name(const char *name) +{ + long level; + netdev_slist_t *node = NULL; + struct netdev *netdev = NULL; + + if (netdev_list == NULL) + { + return NULL; + } + + level = CriticalAreaLock(); + + for (node = &(netdev_list->list); node; node = netdev_slist_next(node)) + { + netdev = netdev_slist_entry(node, struct netdev, list); + if (netdev && (strncmp(netdev->name, name, strlen(netdev->name) < NETDEV_NAME_MAX ? strlen(netdev->name) : NETDEV_NAME_MAX) == 0)) + { + CriticalAreaUnLock(level); + return netdev; + } + } + + CriticalAreaUnLock(level); + + return NULL; +} + +/** + * This function will set default network interface device. + * + * @param netdev the network interface device to change + */ +void netdev_set_default(struct netdev *netdev) +{ + if (netdev) + { + netdev_default = netdev; + + if (netdev->ops->set_default) + { + /* set default network interface device in the current network stack */ + netdev->ops->set_default(netdev); + } + printf("Setting default network interface device name(%s) successfully.", netdev->name); + } +} + +/** + * This function will enable network interface device . + * + * @param netdev the network interface device to change + * + * @return 0: set status successfully + * -1: set status failed + */ +int netdev_set_up(struct netdev *netdev) +{ + assert(netdev); + + if (!netdev->ops || !netdev->ops->set_up) + { + printf("The network interface device(%s) not support to set status.", netdev->name); + return -1; + } + + /* network interface device status flags check */ + if (netdev_is_up(netdev)) + { + return 0; + } + + /* execute enable network interface device operations by network interface device driver */ + return netdev->ops->set_up(netdev); +} +/** + * This function will disable network interface device. + * + * @param netdev the network interface device to change + * + * @return 0: set status successfully + * -1: set sttaus failed + */ +int netdev_set_down(struct netdev *netdev) +{ + assert(netdev); + + if (!netdev->ops || !netdev->ops->set_down) + { + printf("The network interface device(%s) not support to set status.", netdev->name); + return -1; + } + + /* network interface device status flags check */ + if (!netdev_is_up(netdev)) + { + return 0; + } + + /* execute disable network interface device operations by network interface driver */ + return netdev->ops->set_down(netdev); +} + +/** + * This function will control network interface device DHCP capability enable or disable. + * + * @param netdev the network interface device device to change + * @param is_enable the new DHCP status + * + * @return 0: set DHCP status successfully + * -1: set DHCP status failed + */ +int netdev_dhcp_enabled(struct netdev *netdev, _Bool is_enabled) +{ + assert(netdev); + + if (!netdev->ops || !netdev->ops->set_dhcp) + { + printf("The network interface device(%s) not support to set DHCP status.", netdev->name); + return -1; + } + + /* network interface device DHCP flags check */ + if (netdev_is_dhcp_enabled(netdev) == is_enabled) + { + return 0; + } + + /* execute network interface device DHCP capability control operations */ + return netdev->ops->set_dhcp(netdev, is_enabled); +} + +/** + * This function will set network interface device IP address. + * + * @param netdev the network interface device to change + * @param ipaddr the new IP address + * + * @return 0: set IP address successfully + * -1: set IP address failed + */ +int netdev_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr) +{ + assert(netdev); + assert(ip_addr); + + if (!netdev->ops || !netdev->ops->set_addr_info) + { + printf("The network interface device(%s) not support to set IP address.", netdev->name); + return -1; + } + + if (netdev_is_dhcp_enabled(netdev)) + { + printf("The network interface device(%s) DHCP capability is enable, not support set IP address.", netdev->name); + return -1; + } + + /* execute network interface device set IP address operations */ + return netdev->ops->set_addr_info(netdev, (ip_addr_t *)ip_addr, NULL, NULL); +} + +/** + * This function will set network interface device netmask address. + * + * @param netdev the network interface device to change + * @param netmask the new netmask address + * + * @return 0: set netmask address successfully + * -1: set netmask address failed + */ +int netdev_set_netmask(struct netdev *netdev, const ip_addr_t *netmask) +{ + assert(netdev); + assert(netmask); + + if (!netdev->ops || !netdev->ops->set_addr_info) + { + printf("The network interface device(%s) not support to set netmask address.", netdev->name); + return -1; + } + + if (netdev_is_dhcp_enabled(netdev)) + { + printf("The network interface device(%s) DHCP capability is enable, not support set netmask address.", netdev->name); + return -1; + } + + /* execute network interface device set netmask address operations */ + return netdev->ops->set_addr_info(netdev, NULL, (ip_addr_t *)netmask, NULL); +} + +/** + * This function will set network interface device gateway address. + * + * @param netdev the network interface device to change + * @param gateway the new gateway address + * + * @return 0: set gateway address successfully + * -1: set gateway address failed + */ +int netdev_set_gw(struct netdev *netdev, const ip_addr_t *gw) +{ + assert(netdev); + assert(gw); + + if (!netdev->ops || !netdev->ops->set_addr_info) + { + printf("The network interface device(%s) not support to set gateway address.", netdev->name); + return -1; + } + + if (netdev_is_dhcp_enabled(netdev)) + { + printf("The network interface device(%s) DHCP capability is enable, not support set gateway address.", netdev->name); + return -1; + } + + /* execute network interface device set gateway address operations */ + return netdev->ops->set_addr_info(netdev, NULL, NULL, (ip_addr_t *)gw); +} + +/** + * This function will set network interface device DNS server address. + * + * @param netdev the network interface device to change + * @param dns_server the new DNS server address + * + * @return 0: set netmask address successfully + * -1: set netmask address failed + */ +int netdev_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server) +{ + assert(netdev); + assert(dns_server); + + if (dns_num >= NETDEV_DNS_SERVERS_NUM) + { + printf("The number of DNS servers(%d) set exceeds the maximum number(%d).", dns_num + 1, NETDEV_DNS_SERVERS_NUM); + return -1; + } + + if (!netdev->ops || !netdev->ops->set_dns_server) + { + printf("The network interface device(%s) not support to set DNS server address.", netdev->name); + return -1; + } + + /* execute network interface device set DNS server address operations */ + return netdev->ops->set_dns_server(netdev, dns_num, (ip_addr_t *)dns_server); +} + +/** + * This function will set callback to be called when the network interface device status has been changed. + * + * @param netdev the network interface device to change + * @param status_callback the callback be called when the status has been changed. + */ +void netdev_set_status_callback(struct netdev *netdev, netdev_callback_fn status_callback) +{ + assert(netdev); + assert(status_callback); + + netdev->status_callback = status_callback; +} + +/** + * This function will set callback to be called when the network interface device address has been changed. + * + * @param netdev the network interface device to change + * @param addr_callback the callback be called when the address has been changed. + */ +void netdev_set_addr_callback(struct netdev *netdev, netdev_callback_fn addr_callback) +{ + assert(netdev); + assert(addr_callback); + + netdev->addr_callback = addr_callback; +} + + +/** + * This function will set network interface device IP address. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param ipaddr the new IP address + */ +void netdev_low_level_set_ipaddr(struct netdev *netdev, const ip_addr_t *ip_addr) +{ + assert(ip_addr); + + if (netdev && ip_addr_cmp(&(netdev->ip_addr), ip_addr) == 0) + { + ip_addr_copy(netdev->ip_addr, *ip_addr); + + + + /* execute IP address change callback function */ + if (netdev->addr_callback) + { + netdev->addr_callback(netdev, NETDEV_CB_ADDR_IP); + } + } +} + +/** + * This function will set network interface device netmask address. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param netmask the new netmask address + */ +void netdev_low_level_set_netmask(struct netdev *netdev, const ip_addr_t *netmask) +{ + assert(netmask); + + if (netdev && ip_addr_cmp(&(netdev->netmask), netmask) == 0) + { + ip_addr_copy(netdev->netmask, *netmask); + + /* execute netmask address change callback function */ + if (netdev->addr_callback) + { + netdev->addr_callback(netdev, NETDEV_CB_ADDR_NETMASK); + } + } +} + +/** + * This function will set network interface device gateway address. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param gateway the new gateway address + */ +void netdev_low_level_set_gw(struct netdev *netdev, const ip_addr_t *gw) +{ + assert(gw); + + if (netdev && ip_addr_cmp(&(netdev->gw), gw) == 0) + { + ip_addr_copy(netdev->gw, *gw); + + + + /* execute gateway address change callback function */ + if (netdev->addr_callback) + { + netdev->addr_callback(netdev, NETDEV_CB_ADDR_GATEWAY); + } + } +} + +/** + * This function will set network interface device DNS server address. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param dns_server the new DNS server address + * + */ +void netdev_low_level_set_dns_server(struct netdev *netdev, uint8_t dns_num, const ip_addr_t *dns_server) +{ + unsigned int index; + + assert(dns_server); + + if (netdev == NULL) + { + return; + } + /* check DNS servers is exist */ + for (index = 0; index < NETDEV_DNS_SERVERS_NUM; index++) + { + if (ip_addr_cmp(&(netdev->dns_servers[index]), dns_server)) + { + return; + } + } + + if (dns_num < NETDEV_DNS_SERVERS_NUM) + { + ip_addr_copy(netdev->dns_servers[dns_num], *dns_server); + + /* execute DNS servers address change callback function */ + if (netdev->addr_callback) + { + netdev->addr_callback(netdev, NETDEV_CB_ADDR_DNS_SERVER); + } + } +} + +#ifdef NETDEV_USING_AUTO_DEFAULT +/* Change to the first link_up network interface device automatically */ +static void netdev_auto_change_default(struct netdev *netdev) +{ + struct netdev *new_netdev = NULL; + + if (memcmp(netdev, netdev_default, sizeof(struct netdev)) == 0) + { + new_netdev = netdev_get_first_by_flags(NETDEV_FLAG_LINK_UP); + if (new_netdev) + { + netdev_set_default(new_netdev); + } + } +} +#endif /* NETDEV_USING_AUTO_DEFAULT */ + +/** + * This function will set network interface device status. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param is_up the new status + */ +void netdev_low_level_set_status(struct netdev *netdev, _Bool is_up) +{ + if (netdev && netdev_is_up(netdev) != is_up) + { + if (is_up) + { + netdev->flags |= NETDEV_FLAG_UP; + } + else + { + netdev->flags &= ~NETDEV_FLAG_UP; + +#ifdef NETDEV_USING_AUTO_DEFAULT + /* change to the first link_up network interface device automatically */ + netdev_auto_change_default(netdev); +#endif /* NETDEV_USING_AUTO_DEFAULT */ + } + + /* execute network interface device status change callback function */ + if (netdev->status_callback) + { + netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_UP : NETDEV_CB_STATUS_DOWN); + } + } +} + +/** + * This function will set network interface device active link status. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param is_up the new link status + */ +void netdev_low_level_set_link_status(struct netdev *netdev, _Bool is_up) +{ + if (netdev && netdev_is_link_up(netdev) != is_up) + { + if (is_up) + { + netdev->flags |= NETDEV_FLAG_LINK_UP; + + + } + else + { + netdev->flags &= ~NETDEV_FLAG_LINK_UP; + + /* set network interface device flags to internet down */ + netdev->flags &= ~NETDEV_FLAG_INTERNET_UP; + +#ifdef NETDEV_USING_AUTO_DEFAULT + /* change to the first link_up network interface device automatically */ + netdev_auto_change_default(netdev); +#endif /* NETDEV_USING_AUTO_DEFAULT */ + } + + /* execute link status change callback function */ + if (netdev->status_callback) + { + netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_LINK_UP : NETDEV_CB_STATUS_LINK_DOWN); + } + } +} + +/** + * This function will set network interface device active internet status. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param is_up the new internet status + */ +void netdev_low_level_set_internet_status(struct netdev *netdev, _Bool is_up) +{ + if (netdev && netdev_is_internet_up(netdev) != is_up) + { + if (is_up) + { + netdev->flags |= NETDEV_FLAG_INTERNET_UP; + } + else + { + netdev->flags &= ~NETDEV_FLAG_INTERNET_UP; + } + + /* execute network interface device status change callback function */ + if (netdev->status_callback) + { + netdev->status_callback(netdev, is_up ? NETDEV_CB_STATUS_INTERNET_UP : NETDEV_CB_STATUS_INTERNET_DOWN); + } + } +} + +/** + * This function will set network interface device DHCP status. + * @NOTE it can only be called in the network interface device driver. + * + * @param netdev the network interface device to change + * @param is_up the new DHCP status + */ +void netdev_low_level_set_dhcp_status(struct netdev *netdev, _Bool is_enable) +{ + if (netdev && netdev_is_dhcp_enabled(netdev) != is_enable) + { + if (is_enable) + { + netdev->flags |= NETDEV_FLAG_DHCP; + } + else + { + netdev->flags &= ~NETDEV_FLAG_DHCP; + } + + /* execute DHCP status change callback function */ + if (netdev->status_callback) + { + netdev->status_callback(netdev, is_enable ? NETDEV_CB_STATUS_DHCP_ENABLE : NETDEV_CB_STATUS_DHCP_DISABLE); + } + } +} \ No newline at end of file diff --git a/Ubiquitous/XiZi/resources/ethernet/netdev/src/netdev_ipaddr.c b/Ubiquitous/XiZi/resources/ethernet/netdev/src/netdev_ipaddr.c new file mode 100755 index 000000000..af54b5245 --- /dev/null +++ b/Ubiquitous/XiZi/resources/ethernet/netdev/src/netdev_ipaddr.c @@ -0,0 +1,626 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2018-05-18 ChenYong First version + */ + +/** +* @file netdev_ipaddr.c +* @brief functions of getting device address +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-09-15 +*/ + + +#include +#include +#include +#include + + +/* Here for now until needed in other places in lwIP */ +#ifndef isprint +#define in_range(c, lo, up) ((uint8_t)c >= lo && (uint8_t)c <= up) +#define isprint(c) in_range(c, 0x20, 0x7f) +#define isdigit(c) in_range(c, '0', '9') +#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) +#define islower(c) in_range(c, 'a', 'z') +#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') +#define xchar(i) ((i) < 10 ? '0' + (i) : 'A' + (i) - 10) +#endif + +#if NETDEV_IPV4 + +/** + * Check whether "cp" is a valid ascii representation + * of an Internet address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * This replaces inet_addr, the return value from which + * cannot distinguish between failure and a local broadcast address. + * + * @param cp IP address in ascii representation (e.g. "127.0.0.1") + * @param addr pointer to which to save the ip address in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int netdev_ip4addr_aton(const char *cp, ip4_addr_t *addr) +{ + uint32_t val; + uint8_t base; + char c; + uint32_t parts[4]; + uint32_t *pp = parts; + + c = *cp; + for (;;) + { + /* + * Collect number up to ``.''. + * Values are specified as for C: + * 0x=hex, 0=octal, 1-9=decimal. + */ + if (!isdigit(c)) + { + return 0; + } + val = 0; + base = 10; + if (c == '0') + { + c = *++cp; + if (c == 'x' || c == 'X') + { + base = 16; + c = *++cp; + } + else + { + base = 8; + } + } + for (;;) + { + if (isdigit(c)) + { + val = (val * base) + (uint32_t) (c - '0'); + c = *++cp; + } + else if (base == 16 && isxdigit(c)) + { + val = (val << 4) | (uint32_t) (c + 10 - (islower(c) ? 'a' : 'A')); + c = *++cp; + } + else + { + break; + } + } + if (c == '.') + { + /* + * Internet format: + * a.b.c.d + * a.b.c (with c treated as 16 bits) + * a.b (with b treated as 24 bits) + */ + if (pp >= parts + 3) + { + return 0; + } + *pp++ = val; + c = *++cp; + } + else + { + break; + } + } + /* + * Check for trailing characters. + */ + if (c != '\0' && !isspace(c)) + { + return 0; + } + /* + * Concoct the address according to + * the number of parts specified. + */ + switch (pp - parts + 1) + { + + case 0: + return 0; /* initial nondigit */ + + case 1: /* a -- 32 bits */ + break; + + case 2: /* a.b -- 8.24 bits */ + if (val > 0xffffffUL) + { + return 0; + } + if (parts[0] > 0xff) + { + return 0; + } + val |= parts[0] << 24; + break; + + case 3: /* a.b.c -- 8.8.16 bits */ + if (val > 0xffff) + { + return 0; + } + if ((parts[0] > 0xff) || (parts[1] > 0xff)) + { + return 0; + } + val |= (parts[0] << 24) | (parts[1] << 16); + break; + + case 4: /* a.b.c.d -- 8.8.8.8 bits */ + if (val > 0xff) + { + return 0; + } + if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) + { + return 0; + } + val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); + break; + default: + assert(0); + break; + } + if (addr) + { + ip4_addr_set_u32(addr, htonl(val)); + } + return 1; +} + +/** + * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. + * + * @param addr ip address in network order to convert + * @param buf target buffer where the string is stored + * @param buflen length of buf + * @return either pointer to buf which now holds the ASCII + * representation of addr or NULL if buf was too small + */ +char *netdev_ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen) +{ + uint32_t s_addr; + char inv[3]; + char *rp; + uint8_t *ap; + uint8_t rem; + uint8_t n; + uint8_t i; + int len = 0; + + s_addr = ip4_addr_get_u32(addr); + + rp = buf; + ap = (uint8_t *) &s_addr; + for (n = 0; n < 4; n++) + { + i = 0; + do + { + rem = *ap % (uint8_t) 10; + *ap /= (uint8_t) 10; + inv[i++] = (char) ('0' + rem); + } while (*ap); + while (i--) + { + if (len++ >= buflen) + { + return NULL; + } + *rp++ = inv[i]; + } + if (len++ >= buflen) + { + return NULL; + } + *rp++ = '.'; + ap++; + } + *--rp = 0; + return buf; +} + + +/** + * Convert numeric IP address into decimal dotted ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ip address in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * representation of addr + */ +char *netdev_ip4addr_ntoa(const ip4_addr_t *addr) +{ + static char str[IP4ADDR_STRLEN_MAX]; + return netdev_ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX); +} + + +/** + * Ascii internet address interpretation routine. + * The value returned is in network order. + * + * @param cp IP address in ascii representation (e.g. "127.0.0.1") + * @return ip address in network order + */ +in_addr_t netdev_ipaddr_addr(const char *cp) +{ + ip4_addr_t val; + + if (netdev_ip4addr_aton(cp, &val)) { + return ip4_addr_get_u32(&val); + } + return (IPADDR_NONE); +} + +#endif /* NETDEV_IPV4 */ + + +#if NETDEV_IPV6 + +const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; + +/** + * Check whether "cp" is a valid ascii representation + * of an IPv6 address and convert to a binary address. + * Returns 1 if the address is valid, 0 if not. + * + * @param cp IPv6 address in ascii representation (e.g. "FF01::1") + * @param addr pointer to which to save the ip address in network order + * @return 1 if cp could be converted to addr, 0 on failure + */ +int +netdev_ip6addr_aton(const char *cp, ip6_addr_t *addr) +{ + uint32_t addr_index, zero_blocks, current_block_index, current_block_value; + const char *s; + + /* Count the number of colons, to count the number of blocks in a "::" sequence + zero_blocks may be 1 even if there are no :: sequences */ + zero_blocks = 8; + for (s = cp; *s != 0; s++) + { + if (*s == ':') + { + zero_blocks--; + } + else if (!isxdigit(*s)) + { + break; + } + } + + /* parse each block */ + addr_index = 0; + current_block_index = 0; + current_block_value = 0; + for (s = cp; *s != 0; s++) + { + if (*s == ':') + { + if (addr) + { + if (current_block_index & 0x1) + { + addr->addr[addr_index++] |= current_block_value; + } + else + { + addr->addr[addr_index] = current_block_value << 16; + } + } + current_block_index++; + current_block_value = 0; + if (current_block_index > 7) + { + /* address too long! */ + return 0; + } + if (s[1] == ':') + { + if (s[2] == ':') + { + /* invalid format: three successive colons */ + return 0; + } + s++; + /* "::" found, set zeros */ + while (zero_blocks > 0) + { + zero_blocks--; + if (current_block_index & 0x1) + { + addr_index++; + } + else + { + if (addr) + { + addr->addr[addr_index] = 0; + } + } + current_block_index++; + if (current_block_index > 7) + { + /* address too long! */ + return 0; + } + } + } + } + else if (isxdigit(*s)) + { + /* add current digit */ + current_block_value = (current_block_value << 4) + + (isdigit(*s) ? (uint32_t)(*s - '0') : (uint32_t)(10 + (islower(*s) ? *s - 'a' : *s - 'A'))); + } + else + { + /* unexpected digit, space? CRLF? */ + break; + } + } + + if (addr) + { + if (current_block_index & 0x1) + { + addr->addr[addr_index++] |= current_block_value; + } + else + { + addr->addr[addr_index] = current_block_value << 16; + } + } + + /* convert to network byte order. */ + if (addr) + { + for (addr_index = 0; addr_index < 4; addr_index++) + { + addr->addr[addr_index] = htonl(addr->addr[addr_index]); + } + } + + if (current_block_index != 7) + { + return 0; + } + + return 1; +} + +/** + * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. + * + * @param addr ip6 address in network order to convert + * @param buf target buffer where the string is stored + * @param buflen length of buf + * @return either pointer to buf which now holds the ASCII + * representation of addr or NULL if buf was too small + */ +char * +netdev_ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen) +{ + uint32_t current_block_index, current_block_value, next_block_value; + int32_t i; + uint8_t zero_flag, empty_block_flag; + + i = 0; + empty_block_flag = 0; /* used to indicate a zero chain for "::' */ + + for (current_block_index = 0; current_block_index < 8; current_block_index++) + { + /* get the current 16-bit block */ + current_block_value = htonl(addr->addr[current_block_index >> 1]); + if ((current_block_index & 0x1) == 0) + { + current_block_value = current_block_value >> 16; + } + current_block_value &= 0xffff; + + /* Check for empty block. */ + if (current_block_value == 0) + { + if (current_block_index == 7 && empty_block_flag == 1) + { + /* special case, we must render a ':' for the last block. */ + buf[i++] = ':'; + if (i >= buflen) + { + return NULL; + } + break; + } + if (empty_block_flag == 0) + { + /* generate empty block "::", but only if more than one contiguous zero block, + * according to current formatting suggestions RFC 5952. */ + next_block_value = htonl(addr->addr[(current_block_index + 1) >> 1]); + if ((current_block_index & 0x1) == 0x01) + { + next_block_value = next_block_value >> 16; + } + next_block_value &= 0xffff; + if (next_block_value == 0) + { + empty_block_flag = 1; + buf[i++] = ':'; + if (i >= buflen) + { + return NULL; + } + continue; /* move on to next block. */ + } + } + else if (empty_block_flag == 1) + { + /* move on to next block. */ + continue; + } + } + else if (empty_block_flag == 1) + { + /* Set this flag value so we don't produce multiple empty blocks. */ + empty_block_flag = 2; + } + + if (current_block_index > 0) + { + buf[i++] = ':'; + if (i >= buflen) + { + return NULL; + } + } + + if ((current_block_value & 0xf000) == 0) + { + zero_flag = 1; + } + else + { + buf[i++] = xchar(((current_block_value & 0xf000) >> 12)); + zero_flag = 0; + if (i >= buflen) + { + return NULL; + } + } + + if (((current_block_value & 0xf00) == 0) && (zero_flag)) + { + /* do nothing */ + } + else + { + buf[i++] = xchar(((current_block_value & 0xf00) >> 8)); + zero_flag = 0; + if (i >= buflen) + { + return NULL; + } + } + + if (((current_block_value & 0xf0) == 0) && (zero_flag)) + { + /* do nothing */ + } + else + { + buf[i++] = xchar(((current_block_value & 0xf0) >> 4)); + zero_flag = 0; + if (i >= buflen) + { + return NULL; + } + } + + buf[i++] = xchar((current_block_value & 0xf)); + if (i >= buflen) + { + return NULL; + } + } + + buf[i] = 0; + + return buf; +} + +/** + * Convert numeric IPv6 address into ASCII representation. + * returns ptr to static buffer; not reentrant! + * + * @param addr ip6 address in network order to convert + * @return pointer to a global static (!) buffer that holds the ASCII + * representation of addr + */ +char * +netdev_ip6addr_ntoa(const ip6_addr_t *addr) +{ + static char str[40]; + return netdev_ip6addr_ntoa_r(addr, str, 40); +} + +#endif /* NETDEV_IPV6 */ + +const char * +netdev_inet_ntop(int af, const void *src, char *dst, int32_t size) +{ +#define AF_INET 2 +//#define AF_INET6 10 + + const char *ret = NULL; + int size_int = (int)size; + if (size_int < 0) + { + return NULL; + } + switch (af) + { +#if NETDEV_IPV4 + case AF_INET: + return netdev_ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int); +#endif +#if NETDEV_IPV6 + case AF_INET6: + return netdev_ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int); +#endif + default: + break; + } + return ret; +} + +int +netdev_inet_pton(int af, const char *src, void *dst) +{ +#define AF_INET 2 +//#define AF_INET6 10 + + int err; + switch (af) + { +#if NETDEV_IPV4 + case AF_INET: + err = netdev_ip4addr_aton(src, (ip4_addr_t *)dst); + break; +#endif +#if NETDEV_IPV6 + case AF_INET6: + { + /* convert into temporary variable since ip6_addr_t might be larger + than in6_addr when scopes are enabled */ + ip6_addr_t addr; + err = netdev_ip6addr_aton(src, &addr); + if (err) + { + memcpy(dst, &addr.addr, sizeof(addr.addr)); + } + break; + } +#endif + default: + err = -1; + break; + } + return err; +} diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/i2c/connect_i2c.c index 62610187a..e8e9a35b3 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/i2c/connect_i2c.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-arm32-board/third_party_driver/i2c/connect_i2c.c @@ -478,7 +478,7 @@ static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg retries = ignore_nack ? 0 : msg->retries; - if (flags & I2C_ADDR_10BIT) { + if (flags & I2C_ADDR_10BIT_MODE) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; diff --git a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/i2c/connect_i2c.c index 0b37643af..0933b91ab 100644 --- a/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/i2c/connect_i2c.c +++ b/Ubiquitous/XiZi_IIoT/board/aiit-riscv64-board/third_party_driver/i2c/connect_i2c.c @@ -385,7 +385,7 @@ static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg retries = ignore_nack ? 0 : msg->retries; - if (flags & I2C_ADDR_10BIT) { + if (flags & I2C_ADDR_10BIT_MODE) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/connect_i2c.c index 3a24585a4..e40e804d1 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/connect_i2c.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/i2c/connect_i2c.c @@ -376,7 +376,7 @@ static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg retries = ignore_nack ? 0 : msg->retries; - if (flags & I2C_ADDR_10BIT) { + if (flags & I2C_ADDR_10BIT_MODE) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c index 68473e72e..aea6acb02 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/board.c @@ -34,6 +34,10 @@ Modification: #include #include +#ifdef BSP_USING_GPIO +#include +#endif + #ifdef BSP_USING_SDIO #include #endif @@ -42,6 +46,10 @@ Modification: #include #endif +#ifdef BSP_USING_I2C +#include +#endif + #ifdef BSP_USING_USB #include #endif @@ -145,12 +153,18 @@ void SysTick_Handler(void) struct InitSequenceDesc _board_init[] = { +#ifdef BSP_USING_GPIO + { "hw_pin", HwGpioInit }, +#endif #ifdef BSP_USING_SDIO { "sdio", HwSdioInit }, #endif #ifdef BSP_USING_SPI { "spi", HwSpiInit }, #endif +#ifdef BSP_USING_I2C + { "i2c", HwI2cInit }, +#endif #ifdef BSP_USING_USB { "usb", HwUsbHostInit }, #endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk index 2ba28b404..258d2dca3 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/config.mk @@ -9,4 +9,8 @@ export APPLFLAGS := -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard - export DEFINES := -DHAVE_CCONFIG_H -DHC32F4A0 -DUSE_DDL_DRIVER -DHAVE_SIGINFO +ifeq ($(CONFIG_RESOURCES_LWIP), y) +export LINK_LWIP := $(KERNEL_ROOT)/resources/ethernet/LwIP/liblwip.a +endif + export ARCH = arm diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig index e5462cf8e..53f197836 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Kconfig @@ -6,6 +6,22 @@ menuconfig BSP_USING_UART source "$BSP_DIR/third_party_driver/usart/Kconfig" endif +menuconfig BSP_USING_GPIO + bool "Using GPIO device " + default y + select RESOURCES_PIN + if BSP_USING_GPIO + source "$BSP_DIR/third_party_driver/gpio/Kconfig" + endif + +menuconfig BSP_USING_LWIP + bool "Using LwIP by ethernet device" + default n + select RESOURCES_LWIP + if BSP_USING_LWIP + source "$BSP_DIR/third_party_driver/ethernet/Kconfig" + endif + menuconfig BSP_USING_SPI bool "Using SPI device" default n @@ -14,6 +30,14 @@ menuconfig BSP_USING_SPI source "$BSP_DIR/third_party_driver/spi/Kconfig" endif +menuconfig BSP_USING_I2C + bool "Using I2C device" + default n + select RESOURCES_I2C + if BSP_USING_I2C + source "$BSP_DIR/third_party_driver/i2c/Kconfig" + endif + menuconfig BSP_USING_SDIO bool "Using SD CARD device" default n diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile index b075a1a82..ac78bbe64 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/Makefile @@ -4,10 +4,22 @@ ifeq ($(CONFIG_BSP_USING_UART),y) SRC_DIR += usart endif +ifeq ($(CONFIG_BSP_USING_GPIO),y) + SRC_DIR += gpio +endif + +ifeq ($(CONFIG_BSP_USING_LWIP),y) + SRC_DIR += ethernet +endif + ifeq ($(CONFIG_BSP_USING_SPI),y) SRC_DIR += spi endif +ifeq ($(CONFIG_BSP_USING_I2C),y) + SRC_DIR += i2c +endif + ifeq ($(CONFIG_BSP_USING_SDIO),y) SRC_DIR += sdio endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile index 9a62fee3e..c23f8548a 100644 --- a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/common/hc32_ll_driver/src/Makefile @@ -12,6 +12,14 @@ ifeq ($(CONFIG_BSP_USING_SPI),y) SRC_FILES += hc32_ll_spi.c endif +ifeq ($(CONFIG_BSP_USING_I2C),y) + SRC_FILES += hc32_ll_i2c.c +endif + +ifeq ($(CONFIG_BSP_USING_LWIP),y) + SRC_FILES += hc32_ll_eth.c +endif + ifeq ($(CONFIG_BSP_USING_USB),y) SRC_FILES += hc32_ll_usb.c endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Kconfig new file mode 100755 index 000000000..8b1378917 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Kconfig @@ -0,0 +1 @@ + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Makefile new file mode 100755 index 000000000..c1b8c3ab9 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := ethernetif.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c new file mode 100644 index 000000000..c50831630 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/ethernet/ethernetif.c @@ -0,0 +1,783 @@ +/** + ******************************************************************************* + * @file eth/eth_loopback/source/ethernetif.c + * @brief This file implements Ethernet network interface drivers. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file ethernetif.c +* @brief support hc32f4a0-board ethernetif function and register to Lwip +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +/************************************************* +File name: ethernetif.c +Description: support hc32f4a0-board ethernetif configure and register to Lwip +Others: take projects\ev_hc32f4a0_lqfp176\examples\eth\eth_loopback\source\ethernetif.c for references +History: +1. Date: 2022-12-05 +Author: AIIT XUOS Lab +Modification: +1、include harware_ethernetif.h、hc32_ll_eth.h、hc32_ll_gpio.h、hc32_ll_utility.h、hc32_ll_fcg.h and lwip H files; +2、modify ethernetif_init as err_t; +3、add ETH_RST_PORT and ETH_RST_PIN; +4、add ETH_LINK_LED_PORT and ETH_LINK_LED_PIN; +5、add ethernetif_config_enet_set; +6、add ETHERNET_LOOPBACK_TEST with testnetif and txPbuf. +*************************************************/ + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include + +/** + * @addtogroup HC32F4A0_DDL_Examples + * @{ + */ + +/** + * @addtogroup ETH_Loopback + * @{ + */ + +/******************************************************************************* + * Local type definitions ('typedef') + ******************************************************************************/ + +/******************************************************************************* + * Local pre-processor symbols/macros ('#define') + ******************************************************************************/ +/* Define those to better describe your network interface. */ +#define IFNAME0 'h' +#define IFNAME1 'd' + +/* PHY hardware reset time */ +#define PHY_HW_RST_DELAY (0x40U) + +/* ETH_RST = PH11 */ +#define ETH_RST_PORT (GPIO_PORT_H) +#define ETH_RST_PIN (GPIO_PIN_11) + +/* ETH_LINK_LED = PD00 LED2 */ +#define ETH_LINK_LED_PORT (GPIO_PORT_D) +#define ETH_LINK_LED_PIN (GPIO_PIN_00) + +//#define ETHERNET_LOOPBACK_TEST +#ifdef ETHERNET_LOOPBACK_TEST + +#define USER_KEY_PORT (GPIO_PORT_I) +#define USER_KEY_PIN (GPIO_PIN_07) + +/* ethe global netif */ +static struct netif testnetif; +/* eth tx buffer */ +static struct pbuf txPbuf; +static char txBuf[] = "Ethernet Loop-Back Test"; +#endif + +/******************************************************************************* + * Global variable definitions (declared in header file with 'extern') + ******************************************************************************/ + +/******************************************************************************* + * Local function prototypes ('static') + ******************************************************************************/ + +/******************************************************************************* + * Local variable definitions ('static') + ******************************************************************************/ +/* Global Ethernet handle*/ +static stc_eth_handle_t EthHandle; +/* Ethernet Tx DMA Descriptor */ +__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaTxDscrTab[ETH_TX_BUF_NUM]; +/* Ethernet Rx DMA Descriptor */ +__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaRxDscrTab[ETH_RX_BUF_NUM]; +/* Ethernet Transmit Buffer */ +__ALIGN_BEGIN static uint8_t EthTxBuff[ETH_TX_BUF_NUM][ETH_TX_BUF_SIZE]; +/* Ethernet Receive Buffer */ +__ALIGN_BEGIN static uint8_t EthRxBuff[ETH_RX_BUF_NUM][ETH_RX_BUF_SIZE]; + +/* Ethernet link status */ +static uint8_t u8PhyLinkStatus = 0U, u8EthInitStatus = 0U; + +/******************************************************************************* + * Function implementation - global ('extern') and local ('static') + ******************************************************************************/ +/** + * @defgroup ETH_IF_Global_Functions Ethernet Interface Global Functions + * @{ + */ + +void *ethernetif_config_enet_set(uint8_t enet_port) +{ + return NONE; +} + +void Time_Update_LwIP(void) +{ + //no need to do +} + +/** + * @brief Initializes the Ethernet GPIO. + * @param None + * @retval None + */ +static void Ethernet_GpioInit(void) +{ + /* ETH_RST */ + stc_gpio_init_t stcGpioInit; + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_OUT; + (void)GPIO_Init(ETH_RST_PORT, ETH_RST_PIN, &stcGpioInit); + GPIO_ResetPins(ETH_RST_PORT, ETH_RST_PIN); + + SysTick_Delay(PHY_HW_RST_DELAY); + GPIO_SetPins(ETH_RST_PORT, ETH_RST_PIN); + SysTick_Delay(PHY_HW_RST_DELAY); + + /* ETH_LINK_LED LED2 */ + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_OUT; + (void)GPIO_Init(ETH_LINK_LED_PORT, ETH_LINK_LED_PIN, &stcGpioInit); + GPIO_ResetPins(ETH_LINK_LED_PORT, ETH_LINK_LED_PIN); + + /* Configure MII/RMII selection IO for ETH */ +#ifdef ETH_INTERFACE_RMII + /* Ethernet RMII pins configuration */ + /* + ETH_SMI_MDIO ----------------> PA2 + ETH_SMI_MDC -----------------> PC1 + ETH_RMII_TX_EN --------------> PG11 + ETH_RMII_TXD0 ---------------> PG13 + ETH_RMII_TXD1 ---------------> PG14 + ETH_RMII_REF_CLK ------------> PA1 + ETH_RMII_CRS_DV -------------> PA7 + ETH_RMII_RXD0 ---------------> PC4 + ETH_RMII_RXD1 ---------------> PC5 + ETH_RMII_RX_ER --------------> PI10 + */ + /* Configure PA1, PA2 and PA7 */ + GPIO_SetFunc(GPIO_PORT_A, (GPIO_PIN_01 | GPIO_PIN_02 | GPIO_PIN_07), GPIO_FUNC_11); + /* Configure PC1, PC4 and PC5 */ + GPIO_SetFunc(GPIO_PORT_C, (GPIO_PIN_01 | GPIO_PIN_04 | GPIO_PIN_05), GPIO_FUNC_11); + /* Configure PG11, PG13 and PG14 */ + GPIO_SetFunc(GPIO_PORT_G, (GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14), GPIO_FUNC_11); + /* Configure PI10 */ + GPIO_SetFunc(GPIO_PORT_I, GPIO_PIN_10, GPIO_FUNC_11); +#else + /* Ethernet MII pins configuration */ + /* + ETH_SMI_MDIO ----------------> PA2 + ETH_SMI_MDC -----------------> PC1 + ETH_MII_TX_CLK --------------> PB6 + ETH_MII_TX_EN ---------------> PG11 + ETH_MII_TXD0 ----------------> PG13 + ETH_MII_TXD1 ----------------> PG14 + ETH_MII_TXD2 ----------------> PB9 + ETH_MII_TXD3 ----------------> PB8 + ETH_MII_RX_CLK --------------> PA1 + ETH_MII_RX_DV ---------------> PA7 + ETH_MII_RXD0 ----------------> PC4 + ETH_MII_RXD1 ----------------> PC5 + ETH_MII_RXD2 ----------------> PB0 + ETH_MII_RXD3 ----------------> PB1 + ETH_MII_RX_ER ---------------> PI10 + ETH_MII_CRS -----------------> PH2 + ETH_MII_COL -----------------> PH3 + */ + /* Configure PA1, PA2 and PA7 */ + GPIO_SetFunc(GPIO_PORT_A, (GPIO_PIN_01 | GPIO_PIN_02 | GPIO_PIN_07), GPIO_FUNC_11); + /* Configure PB0, PB1, PB6, PB8 and PB9 */ + GPIO_SetFunc(GPIO_PORT_B, (GPIO_PIN_00 | GPIO_PIN_01 | GPIO_PIN_06 | GPIO_PIN_08 | GPIO_PIN_09), GPIO_FUNC_11); + /* Configure PC1, PC4 and PC5 */ + GPIO_SetFunc(GPIO_PORT_C, (GPIO_PIN_01 | GPIO_PIN_04 | GPIO_PIN_05), GPIO_FUNC_11); + /* Configure PG11, PG13 and PG14 */ + GPIO_SetFunc(GPIO_PORT_G, (GPIO_PIN_11 | GPIO_PIN_13 | GPIO_PIN_14), GPIO_FUNC_11); + /* Configure PH2, PH3 */ + GPIO_SetFunc(GPIO_PORT_H, (GPIO_PIN_02 | GPIO_PIN_03), GPIO_FUNC_11); + /* Configure PI10 */ + GPIO_SetFunc(GPIO_PORT_I, GPIO_PIN_10, GPIO_FUNC_11); +#endif +} + +/** + * @brief In this function, the hardware should be initialized. + * @param netif The already initialized network interface structure for this ethernetif. + * @retval int32_t: + * - LL_OK: Initialize success + * - LL_ERR: Initialize failed + */ +static int32_t low_level_init(struct netif *netif) +{ + int32_t i32Ret = LL_ERR; + stc_eth_init_t stcEthInit; + uint16_t u16RegVal; + + /* Enable ETH clock */ + FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_ETHMAC, ENABLE); + /* Init Ethernet GPIO */ + Ethernet_GpioInit(); + /* Reset ETHERNET */ + (void)ETH_DeInit(); + /* Configure structure initialization */ + (void)ETH_CommStructInit(&EthHandle.stcCommInit); + (void)ETH_StructInit(&stcEthInit); +#ifdef ETH_INTERFACE_RMII + EthHandle.stcCommInit.u32Interface = ETH_MAC_IF_RMII; +#else + EthHandle.stcCommInit.u32Interface = ETH_MAC_IF_MII; +#endif + stcEthInit.stcMacInit.u32ReceiveAll = ETH_MAC_RX_ALL_ENABLE; + + /* Configure ethernet peripheral */ + if (LL_OK == ETH_Init(&EthHandle, &stcEthInit)) { + u8EthInitStatus = 1U; + i32Ret = LL_OK; + } + +#ifdef ETHERNET_LOOPBACK_TEST + /* Enable PHY loopback */ + (void)ETH_PHY_LoopBackCmd(&EthHandle, ENABLE); +#endif + + /* Initialize Tx Descriptors list: Chain Mode */ + (void)ETH_DMA_TxDescListInit(&EthHandle, EthDmaTxDscrTab, &EthTxBuff[0][0], ETH_TX_BUF_NUM); + /* Initialize Rx Descriptors list: Chain Mode */ + (void)ETH_DMA_RxDescListInit(&EthHandle, EthDmaRxDscrTab, &EthRxBuff[0][0], ETH_RX_BUF_NUM); + + /* set MAC hardware address length */ + netif->hwaddr_len = 6U; + /* set MAC hardware address */ + netif->hwaddr[0] = (EthHandle.stcCommInit).au8MacAddr[0]; + netif->hwaddr[1] = (EthHandle.stcCommInit).au8MacAddr[1]; + netif->hwaddr[2] = (EthHandle.stcCommInit).au8MacAddr[2]; + netif->hwaddr[3] = (EthHandle.stcCommInit).au8MacAddr[3]; + netif->hwaddr[4] = (EthHandle.stcCommInit).au8MacAddr[4]; + netif->hwaddr[5] = (EthHandle.stcCommInit).au8MacAddr[5]; + /* maximum transfer unit */ + netif->mtu = 1500U; + /* Enable MAC and DMA transmission and reception */ + (void)ETH_Start(); + + /* Configure PHY LED mode */ + u16RegVal = PHY_PAGE_ADDR_7; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); + (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal); + MODIFY_REG16(u16RegVal, PHY_LED_SELECT, PHY_LED_SELECT_10); + (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal); + u16RegVal = PHY_PAGE_ADDR_0; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); + +#ifdef ETH_INTERFACE_RMII + /* Disable Power Saving Mode */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_PSMR, &u16RegVal); + CLR_REG16_BIT(u16RegVal, PHY_EN_PWR_SAVE); + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSMR, u16RegVal); + + /* Configure PHY to generate an interrupt when Eth Link state changes */ + u16RegVal = PHY_PAGE_ADDR_7; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); + /* Enable Interrupt on change of link status */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal); + SET_REG16_BIT(u16RegVal, PHY_INT_LINK_CHANGE); + (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal); + u16RegVal = PHY_PAGE_ADDR_0; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); +#endif + + return i32Ret; +} + +/** + * @brief This function should do the actual transmission of the packet. + * @param netif The network interface structure for this ethernetif. + * @param p The MAC packet to send. + * @retval int32_t: + * - LL_OK: The packet could be sent + * - LL_ERR: The packet couldn't be sent + */ +int32_t low_level_output(struct netif *netif, struct pbuf *p) +{ + int32_t i32Ret; + struct pbuf *q; + uint8_t *txBuffer; + __IO stc_eth_dma_desc_t *DmaTxDesc; + uint32_t byteCnt; + uint32_t frameLength = 0UL; + uint32_t bufferOffset; + uint32_t payloadOffset; + + DmaTxDesc = EthHandle.stcTxDesc; + txBuffer = (uint8_t *)((EthHandle.stcTxDesc)->u32Buf1Addr); + bufferOffset = 0UL; + /* Copy frame from pbufs to driver buffers */ + for (q = p; q != NULL; q = q->next) { + /* If this buffer isn't available, goto error */ + if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) { + i32Ret = LL_ERR; + goto error; + } + + /* Get bytes in current buffer */ + byteCnt = q->len; + payloadOffset = 0UL; + /* Check if the length of data to copy is bigger than Tx buffer size */ + while ((byteCnt + bufferOffset) > ETH_TX_BUF_SIZE) { + /* Copy data to Tx buffer*/ + (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (ETH_TX_BUF_SIZE - bufferOffset)); + /* Point to next descriptor */ + DmaTxDesc = (stc_eth_dma_desc_t *)(DmaTxDesc->u32Buf2NextDescAddr); + /* Check if the buffer is available */ + if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) { + i32Ret = LL_ERR; + goto error; + } + + txBuffer = (uint8_t *)(DmaTxDesc->u32Buf1Addr); + byteCnt = byteCnt - (ETH_TX_BUF_SIZE - bufferOffset); + payloadOffset = payloadOffset + (ETH_TX_BUF_SIZE - bufferOffset); + frameLength = frameLength + (ETH_TX_BUF_SIZE - bufferOffset); + bufferOffset = 0UL; + } + /* Copy the remaining bytes */ + (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), byteCnt); + bufferOffset = bufferOffset + byteCnt; + frameLength = frameLength + byteCnt; + } + /* Prepare transmit descriptors to give to DMA */ + (void)ETH_DMA_SetTransFrame(&EthHandle, frameLength); + i32Ret = LL_OK; + +error: + /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */ + if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_UNS)) { + /* Clear DMA UNS flag */ + ETH_DMA_ClearStatus(ETH_DMA_FLAG_UNS); + /* Resume DMA transmission */ + WRITE_REG32(CM_ETH->DMA_TXPOLLR, 0UL); + } + + return i32Ret; +} + +/** + * @brief Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf. + * @param netif The network interface structure for this ethernetif. + * @retval A pbuf filled with the received packet (including MAC header) or NULL on memory error. + */ +static struct pbuf *low_level_input(struct netif *netif) +{ + struct pbuf *p = NULL; + struct pbuf *q; + uint32_t len; + uint8_t *rxBuffer; + __IO stc_eth_dma_desc_t *DmaRxDesc; + uint32_t byteCnt; + uint32_t bufferOffset; + uint32_t payloadOffset; + uint32_t i; + + /* Get received frame */ + if (LL_OK != ETH_DMA_GetReceiveFrame(&EthHandle)) { + return NULL; + } + + /* Obtain the size of the packet */ + len = (EthHandle.stcRxFrame).u32Len; + rxBuffer = (uint8_t *)(EthHandle.stcRxFrame).u32Buf; + if (len > 0UL) { + /* Allocate a pbuf chain of pbufs from the buffer */ + p = (struct pbuf *)malloc(sizeof(struct pbuf) + len); + if (NULL != p) { + p->next = NULL; + p->payload = &((uint8_t *)p)[sizeof(struct pbuf)]; + p->len = len; + (void)memset(p->payload, 0, p->len); + } + } + if (p != NULL) { + DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc; + bufferOffset = 0UL; + for (q = p; q != NULL; q = q->next) { + byteCnt = q->len; + payloadOffset = 0UL; + + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */ + while ((byteCnt + bufferOffset) > ETH_RX_BUF_SIZE) { + /* Copy data to pbuf */ + (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), (ETH_RX_BUF_SIZE - bufferOffset)); + /* Point to next descriptor */ + DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr); + rxBuffer = (uint8_t *)(DmaRxDesc->u32Buf1Addr); + byteCnt = byteCnt - (ETH_RX_BUF_SIZE - bufferOffset); + payloadOffset = payloadOffset + (ETH_RX_BUF_SIZE - bufferOffset); + bufferOffset = 0UL; + } + + /* Copy remaining data in pbuf */ + (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), byteCnt); + bufferOffset = bufferOffset + byteCnt; + } + } + /* Release descriptors to DMA */ + DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc; + for (i = 0UL; i < (EthHandle.stcRxFrame).u32SegCount; i++) { + DmaRxDesc->u32ControlStatus |= ETH_DMA_RXDESC_OWN; + DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr); + } + /* Clear Segment_Count */ + (EthHandle.stcRxFrame).u32SegCount = 0UL; + + /* When Rx Buffer unavailable flag is set, clear it and resume reception */ + if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_RUS)) { + /* Clear DMA RUS flag */ + ETH_DMA_ClearStatus(ETH_DMA_FLAG_RUS); + /* Resume DMA reception */ + WRITE_REG32(CM_ETH->DMA_RXPOLLR, 0UL); + } + + return p; +} + +/** + * @brief Should be called at the beginning of the program to set up the network interface. + * @param netif The network interface structure for this ethernetif. + * @retval err_t: + * - LL_OK: The IF is initialized + * - LL_ERR: The IF is uninitialized + */ +err_t ethernetif_init(struct netif *netif) +{ + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* initialize the hardware */ + return low_level_init(netif); +} + +/** + * @brief This function should be called when a packet is ready to be read from the interface. + * @param netif The network interface structure for this ethernetif. + * @retval None + */ +void ethernetif_input(struct netif *netif) +{ + struct pbuf *p; + + /* Move received packet into a new pbuf */ + p = low_level_input(netif); + /* No packet could be read, silently ignore this */ + if (p != NULL) { + EthernetIF_InputCallback(netif, p); + free(p); + } +} + +/** + * @brief Check the netif link status. + * @param netif the network interface + * @retval None + */ +void EthernetIF_CheckLink(struct netif *netif) +{ + uint16_t u16RegVal = 0U; + static uint8_t u8PreStatus = 0U; + + if (1U == u8EthInitStatus) { + u8EthInitStatus = 0U; + u8PhyLinkStatus = ETH_LINK_UP; + u8PreStatus = 1U; + /* Notify link status change */ + EthernetIF_NotifyLinkChange(netif); + } else { + /* Read PHY_BSR */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_BSR, &u16RegVal); + /* Check whether the link is up or down*/ + if ((0x0000U != u16RegVal) && (0xFFFFU != u16RegVal)) { + if ((0U != (u16RegVal & PHY_LINK_STATUS)) && (0U == u8PreStatus)) { + u8PhyLinkStatus = ETH_LINK_UP; + u8PreStatus = 1U; + EthernetIF_LinkCallback(netif); + } + if ((0U == (u16RegVal & PHY_LINK_STATUS)) && (1U == u8PreStatus)) { + u8PhyLinkStatus = ETH_LINK_DOWN; + u8PreStatus = 0U; + EthernetIF_LinkCallback(netif); + } + } + } +} + +/** + * @brief Update the netif link status. + * @param netif The network interface. + * @retval None + */ +void EthernetIF_UpdateLink(struct netif *netif) +{ + uint16_t u16RegVal; + + if (1U == u8EthInitStatus) { + u8EthInitStatus = 0U; + u8PhyLinkStatus = ETH_LINK_UP; + /* Notify link status change */ + EthernetIF_NotifyLinkChange(netif); + } else { + u16RegVal = PHY_PAGE_ADDR_0; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal); + /* Read PHY_IISDR */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_IISDR, &u16RegVal); + /* Check whether the link interrupt has occurred or not */ + if (0U != (u16RegVal & PHY_FLAG_LINK_STATUS_CHANGE)) { + /* Read PHY_BSR */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_BSR, &u16RegVal); + if ((0x0000U != u16RegVal) && (0xFFFFU != u16RegVal)) { + if (ETH_LINK_UP != u8PhyLinkStatus) { + /* Wait until the auto-negotiation will be completed */ + SysTick_Delay(2U); + (void)ETH_PHY_ReadReg(&EthHandle, PHY_BSR, &u16RegVal); + } + /* Check whether the link is up or down*/ + if (0U != (u16RegVal & PHY_LINK_STATUS)) { + u8PhyLinkStatus = ETH_LINK_UP; + } else { + u8PhyLinkStatus = ETH_LINK_DOWN; + } + EthernetIF_LinkCallback(netif); + } + } + } +} + +/** + * @brief Ethernet interface periodic handle + * @param netif The network interface + * @retval None + */ +void EthernetIF_PeriodicHandle(struct netif *netif) +{ +#ifndef ETH_INTERFACE_RMII + uint32_t curTick; + static uint32_t u32LinkTimer = 0UL; + + curTick = SysTick_GetTick(); + /* Check link status periodically */ + if ((curTick - u32LinkTimer) >= LINK_TIMER_INTERVAL) { + u32LinkTimer = curTick; + EthernetIF_CheckLink(netif); + } +#endif /* ETH_INTERFACE_RMII */ +} + +/** + * @brief Link callback function + * @note This function is called on change of link status to update low level driver configuration. + * @param netif The network interface + * @retval None + */ +void EthernetIF_LinkCallback(struct netif *netif) +{ + __IO uint32_t tickStart = 0UL; + uint16_t u16RegVal = 0U; + int32_t i32negoResult = LL_ERR; + + if (ETH_LINK_UP == u8PhyLinkStatus) { + /* Restart the auto-negotiation */ + if (ETH_AUTO_NEGO_DISABLE != (EthHandle.stcCommInit).u16AutoNego) { + /* Enable Auto-Negotiation */ + (void)ETH_PHY_ReadReg(&EthHandle, PHY_BCR, &u16RegVal); + u16RegVal |= PHY_AUTONEGOTIATION; + (void)ETH_PHY_WriteReg(&EthHandle, PHY_BCR, u16RegVal); + + /* Wait until the auto-negotiation will be completed */ + tickStart = SysTick_GetTick(); + do { + (void)ETH_PHY_ReadReg(&EthHandle, PHY_BSR, &u16RegVal); + if (PHY_AUTONEGO_COMPLETE == (u16RegVal & PHY_AUTONEGO_COMPLETE)) { + break; + } + /* Check for the Timeout (3s) */ + } while ((SysTick_GetTick() - tickStart) <= 3000U); + if (PHY_AUTONEGO_COMPLETE == (u16RegVal & PHY_AUTONEGO_COMPLETE)) { + i32negoResult = LL_OK; + /* Configure ETH duplex mode according to the result of automatic negotiation */ + if (0U != (u16RegVal & (PHY_100BASE_TX_FD | PHY_10BASE_T_FD))) { + (EthHandle.stcCommInit).u32DuplexMode = ETH_MAC_DUPLEX_MD_FULL; + } else { + (EthHandle.stcCommInit).u32DuplexMode = ETH_MAC_DUPLEX_MD_HALF; + } + + /* Configure ETH speed according to the result of automatic negotiation */ + if (0U != (u16RegVal & (PHY_100BASE_TX_FD | PHY_100BASE_TX_HD))) { + (EthHandle.stcCommInit).u32Speed = ETH_MAC_SPEED_100M; + } else { + (EthHandle.stcCommInit).u32Speed = ETH_MAC_SPEED_10M; + } + } + } + + /* AutoNegotiation disable or failed*/ + if (LL_ERR == i32negoResult) { + (void)ETH_PHY_ReadReg(&EthHandle, PHY_BCR, &u16RegVal); + CLR_REG16_BIT(u16RegVal, PHY_FULLDUPLEX_100M); + /* Set MAC Speed and Duplex Mode to PHY */ + (void)ETH_PHY_WriteReg(&EthHandle, PHY_BCR, + ((uint16_t)((EthHandle.stcCommInit).u32DuplexMode >> 3U) | + (uint16_t)((EthHandle.stcCommInit).u32Speed >> 1U) | u16RegVal)); + } + /* ETH MAC Re-Configuration */ + ETH_MAC_SetDuplexSpeed((EthHandle.stcCommInit).u32DuplexMode, (EthHandle.stcCommInit).u32Speed); + /* Restart MAC interface */ + (void)ETH_Start(); + } else { + /* Stop MAC interface */ + (void)ETH_Stop(); + } + /* Notify link status change */ + EthernetIF_NotifyLinkChange(netif); +} + +/** + * @brief Ethernet interface periodic handle + * @param netif The network interface + * @retval int32_t: + * - LL_OK: The IF is link up + * - LL_ERR: The IF is link down + */ +int32_t EthernetIF_IsLinkUp(struct netif *netif) +{ + return (0U != u8PhyLinkStatus) ? LL_OK : LL_ERR; +} + +/** + * @brief Notify link status change. + * @param netif The network interface + * @retval None + */ +__WEAKDEF void EthernetIF_NotifyLinkChange(struct netif *netif) +{ + /* This is function could be implemented in user file when the callback is needed */ + if (LL_OK == EthernetIF_IsLinkUp(netif)) { + GPIO_SetPins(ETH_LINK_LED_PORT, ETH_LINK_LED_PIN); + } else { + GPIO_ResetPins(ETH_LINK_LED_PORT, ETH_LINK_LED_PIN); + } +} + +/** + * @brief Input data handle callback. + * @param netif The network interface structure for this ethernetif + * @param p The MAC packet to receive + * @retval None + */ +__WEAKDEF void EthernetIF_InputCallback(struct netif *netif, struct pbuf *p) +{ + /* This is function could be implemented in user file when the callback is needed */ +#ifdef ETHERNET_LOOPBACK_TEST + if ((0 == (memcmp(p->payload, txPbuf.payload, p->len))) && (p->len == txPbuf.len)) { + KPrintf("eth receive data OK! \r\n"); + KPrintf("receive data %d %s\n", p->len, p->payload); + } else { + KPrintf("eth receive data error! \r\n"); + } +#endif +} + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef ETHERNET_LOOPBACK_TEST + +static void EthLoopBackTask(void *parameter) +{ + while (1) { + if (RESET == GPIO_ReadInputPins(USER_KEY_PORT, USER_KEY_PIN)) { + KPrintf("ready to send eth data\n"); + if (LL_OK != low_level_output(&testnetif, &txPbuf)) { + KPrintf("eth send data error! \r\n"); + } + } + + //KPrintf("ready to receive eth loop back data\n"); + /* Read a received packet */ + ethernetif_input(&testnetif); + /* Handle periodic timers */ + EthernetIF_PeriodicHandle(&testnetif); + } +} + +static void EthLoopBackTest(void) +{ + x_err_t ret = EOK; + + stc_gpio_init_t stcGpioInit; + + /* KEY initialize */ + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_IN; + (void)GPIO_Init(USER_KEY_PORT, USER_KEY_PIN, &stcGpioInit); + GPIO_ResetPins(USER_KEY_PORT, USER_KEY_PIN); + + /* Configure the Ethernet */ + (void)ethernetif_init(&testnetif); + + /* fill data to txPbuf */ + txPbuf.next = NULL; + txPbuf.payload = txBuf; + txPbuf.len = strlen(txBuf); + + int eth_loopback_task = 0; + eth_loopback_task = KTaskCreate("eth_loopback", EthLoopBackTask, NONE, + 2048, 8); + if(eth_loopback_task < 0) { + KPrintf("eth_loopback_task create failed ...%s %d.\n", __FUNCTION__,__LINE__); + return; + } + + StartupKTask(eth_loopback_task); + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +EthLoopBackTest, EthLoopBackTest, EthLoopBackTest); + +#endif + +/****************************************************************************** + * EOF (not truncated) + *****************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/Kconfig new file mode 100644 index 000000000..35dce7392 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/Kconfig @@ -0,0 +1,11 @@ +config PIN_BUS_NAME + string "pin bus name" + default "pin" + +config PIN_DRIVER_NAME + string "pin driver name" + default "pin_drv" + +config PIN_DEVICE_NAME + string "pin device name" + default "pin_dev" diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/Makefile new file mode 100644 index 000000000..a38e983e4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_gpio.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/connect_gpio.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/connect_gpio.c new file mode 100644 index 000000000..a6d28e628 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/gpio/connect_gpio.c @@ -0,0 +1,795 @@ +/* + * Copyright (c) 2006-2022, RT-Thread Development Team + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file connect_gpio.c +* @brief support hc32f4a0-board gpio function using bus driver framework +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +/************************************************* +File name: connect_gpio.c +Description: support hc32f4a0-board gpio configure and gpio bus register function +Others: take projects/ev_hc32f4a0_lqfp176/examples/gpio/gpio_output/source/main.c for references +History: +1. Date: 2022-12-05 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board gpio configure, write and read +2. support hc32f4a0-board gpio bus device and driver register +*************************************************/ + +#include + +#define GPIO_PIN_INDEX(pin) ((uint8_t)((pin) & 0x0F)) + +#define ITEM_NUM(items) sizeof(items) / sizeof(items[0]) + +#ifndef HC32_PIN_CONFIG +#define HC32_PIN_CONFIG(pin, callback, config) \ + { \ + .pinbit = pin, \ + .irq_callback = callback, \ + .irq_config = config, \ + } +#endif /* HC32_PIN_CONFIG */ + +#define __HC32_PIN(index, gpio_port, gpio_pin) { 0, GPIO_PORT_##gpio_port, GPIO_PIN_##gpio_pin} +#define __HC32_PIN_DEFAULT {-1, 0, 0} + +struct PinIndex +{ + int index; + uint8_t port; + uint16_t pin; +}; + +static void EXTINT0_IRQHandler(void); +static void EXTINT1_IRQHandler(void); +static void EXTINT2_IRQHandler(void); +static void EXTINT3_IRQHandler(void); +static void EXTINT4_IRQHandler(void); +static void EXTINT5_IRQHandler(void); +static void EXTINT6_IRQHandler(void); +static void EXTINT7_IRQHandler(void); +static void EXTINT8_IRQHandler(void); +static void EXTINT9_IRQHandler(void); +static void EXTINT10_IRQHandler(void); +static void EXTINT11_IRQHandler(void); +static void EXTINT12_IRQHandler(void); +static void EXTINT13_IRQHandler(void); +static void EXTINT14_IRQHandler(void); +static void EXTINT15_IRQHandler(void); + +static struct Hc32PinIrqMap pin_irq_map[] = +{ + HC32_PIN_CONFIG(GPIO_PIN_00, EXTINT0_IRQHandler, EXTINT0_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_01, EXTINT1_IRQHandler, EXTINT1_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_02, EXTINT2_IRQHandler, EXTINT2_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_03, EXTINT3_IRQHandler, EXTINT3_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_04, EXTINT4_IRQHandler, EXTINT4_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_05, EXTINT5_IRQHandler, EXTINT5_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_06, EXTINT6_IRQHandler, EXTINT6_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_07, EXTINT7_IRQHandler, EXTINT7_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_08, EXTINT8_IRQHandler, EXTINT8_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_09, EXTINT9_IRQHandler, EXTINT9_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_10, EXTINT10_IRQHandler, EXTINT10_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_11, EXTINT11_IRQHandler, EXTINT11_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_12, EXTINT12_IRQHandler, EXTINT12_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_13, EXTINT13_IRQHandler, EXTINT13_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_14, EXTINT14_IRQHandler, EXTINT14_IRQ_CONFIG), + HC32_PIN_CONFIG(GPIO_PIN_15, EXTINT15_IRQHandler, EXTINT15_IRQ_CONFIG), +}; + +static const struct PinIndex pins[] = +{ + __HC32_PIN_DEFAULT, + __HC32_PIN(1, E, 02), + __HC32_PIN(2, E, 03), + __HC32_PIN(3, E, 04), + __HC32_PIN(4, E, 05), + __HC32_PIN(5, E, 06), + __HC32_PIN_DEFAULT, + __HC32_PIN(7, I, 08), + __HC32_PIN_DEFAULT, + __HC32_PIN(9, C, 14), + __HC32_PIN(10, C, 15), + __HC32_PIN(11, I, 09), + __HC32_PIN(12, I, 10), + __HC32_PIN(13, I, 11), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(16, F, 00), + __HC32_PIN(17, F, 01), + __HC32_PIN(18, F, 02), + __HC32_PIN(19, F, 03), + __HC32_PIN(20, F, 04), + __HC32_PIN(21, F, 05), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(24, F, 06), + __HC32_PIN(25, F, 07), + __HC32_PIN(26, F, 08), + __HC32_PIN(27, F, 09), + __HC32_PIN(28, F, 10), + __HC32_PIN(29, H, 00), + __HC32_PIN(30, H, 01), + __HC32_PIN_DEFAULT, + __HC32_PIN(32, C, 00), + __HC32_PIN(33, C, 01), + __HC32_PIN(34, C, 02), + __HC32_PIN(35, C, 03), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(40, A, 00), + __HC32_PIN(41, A, 01), + __HC32_PIN(42, A, 02), + __HC32_PIN(43, H, 02), + __HC32_PIN(44, H, 03), + __HC32_PIN(45, H, 04), + __HC32_PIN(46, H, 05), + __HC32_PIN(47, A, 03), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(50, A, 04), + __HC32_PIN(51, A, 05), + __HC32_PIN(52, A, 06), + __HC32_PIN(53, A, 07), + __HC32_PIN(54, C, 04), + __HC32_PIN(55, C, 05), + __HC32_PIN(56, B, 00), + __HC32_PIN(57, B, 01), + __HC32_PIN(58, B, 02), + __HC32_PIN(59, F, 11), + __HC32_PIN(60, F, 12), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(63, F, 13), + __HC32_PIN(64, F, 14), + __HC32_PIN(65, F, 15), + __HC32_PIN(66, G, 00), + __HC32_PIN(67, G, 01), + __HC32_PIN(68, E, 07), + __HC32_PIN(69, E, 08), + __HC32_PIN(70, E, 09), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(73, E, 10), + __HC32_PIN(74, E, 11), + __HC32_PIN(75, E, 12), + __HC32_PIN(76, E, 13), + __HC32_PIN(77, E, 14), + __HC32_PIN(78, E, 15), + __HC32_PIN(79, B, 10), + __HC32_PIN(80, B, 11), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(83, H, 06), + __HC32_PIN(84, H, 07), + __HC32_PIN(85, H, 08), + __HC32_PIN(86, H, 09), + __HC32_PIN(87, H, 10), + __HC32_PIN(88, H, 11), + __HC32_PIN(89, H, 12), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(92, B, 12), + __HC32_PIN(93, B, 13), + __HC32_PIN(94, B, 14), + __HC32_PIN(95, B, 15), + __HC32_PIN(96, D, 08), + __HC32_PIN(97, D, 09), + __HC32_PIN(98, D, 10), + __HC32_PIN(99, D, 11), + __HC32_PIN(100, D, 12), + __HC32_PIN(101, D, 13), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(104, D, 14), + __HC32_PIN(105, D, 15), + __HC32_PIN(106, G, 02), + __HC32_PIN(107, G, 03), + __HC32_PIN(108, G, 04), + __HC32_PIN(109, G, 05), + __HC32_PIN(110, G, 06), + __HC32_PIN(111, G, 07), + __HC32_PIN(112, G, 08), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(115, C, 06), + __HC32_PIN(116, C, 07), + __HC32_PIN(117, C, 08), + __HC32_PIN(118, C, 09), + __HC32_PIN(119, A, 08), + __HC32_PIN(120, A, 09), + __HC32_PIN(121, A, 10), + __HC32_PIN(122, A, 11), + __HC32_PIN(123, A, 12), + __HC32_PIN(124, A, 13), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(128, H, 13), + __HC32_PIN(129, H, 14), + __HC32_PIN(130, H, 15), + __HC32_PIN(131, I, 00), + __HC32_PIN(132, I, 01), + __HC32_PIN(133, I, 02), + __HC32_PIN(134, I, 03), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(137, A, 14), + __HC32_PIN(138, A, 15), + __HC32_PIN(139, C, 10), + __HC32_PIN(140, C, 11), + __HC32_PIN(141, C, 12), + __HC32_PIN(142, D, 00), + __HC32_PIN(143, D, 01), + __HC32_PIN(144, D, 02), + __HC32_PIN(145, D, 03), + __HC32_PIN(146, D, 04), + __HC32_PIN(147, D, 05), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(150, D, 06), + __HC32_PIN(151, D, 07), + __HC32_PIN(152, G, 09), + __HC32_PIN(153, G, 10), + __HC32_PIN(154, G, 11), + __HC32_PIN(155, G, 12), + __HC32_PIN(156, G, 13), + __HC32_PIN(157, G, 14), + __HC32_PIN_DEFAULT, + __HC32_PIN_DEFAULT, + __HC32_PIN(160, G, 15), + __HC32_PIN(161, B, 03), + __HC32_PIN(162, B, 04), + __HC32_PIN(163, B, 05), + __HC32_PIN(164, B, 06), + __HC32_PIN(165, B, 07), + __HC32_PIN(166, I, 13), + __HC32_PIN(167, B, 08), + __HC32_PIN(168, B, 09), + __HC32_PIN(169, E, 00), + __HC32_PIN(170, E, 01), + __HC32_PIN(171, I, 12), + __HC32_PIN_DEFAULT, + __HC32_PIN(173, I, 04), + __HC32_PIN(174, I, 05), + __HC32_PIN(175, I, 06), + __HC32_PIN(176, I, 07), +}; + +struct PinIrqHdr pin_irq_hdr_tab[] = +{ + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE}, + {-1, 0, NONE, NONE} +}; + +static void PinIrqHandler(uint16_t pinbit) +{ + int32_t irqindex = -1; + + if (SET == EXTINT_GetExtIntStatus(pinbit)) + { + EXTINT_ClearExtIntStatus(pinbit); + irqindex = __CLZ(__RBIT(pinbit)); + if (pin_irq_hdr_tab[irqindex].hdr) { + pin_irq_hdr_tab[irqindex].hdr(pin_irq_hdr_tab[irqindex].args); + } + } +} + +static void EXTINT0_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[0].pinbit); +} + +static void EXTINT1_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[1].pinbit); +} + +static void EXTINT2_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[2].pinbit); +} + +static void EXTINT3_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[3].pinbit); +} + +static void EXTINT4_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[4].pinbit); +} + +static void EXTINT5_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[5].pinbit); +} + +static void EXTINT6_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[6].pinbit); +} + +static void EXTINT7_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[7].pinbit); +} + +static void EXTINT8_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[8].pinbit); +} + +static void EXTINT9_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[9].pinbit); +} + +static void EXTINT10_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[10].pinbit); +} + +static void EXTINT11_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[11].pinbit); +} + +static void EXTINT12_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[12].pinbit); +} + +static void EXTINT13_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[13].pinbit); +} + +static void EXTINT14_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[14].pinbit); +} + +static void EXTINT15_IRQHandler(void) +{ + PinIrqHandler(pin_irq_map[15].pinbit); +} + +const struct PinIndex *GetPin(uint8_t pin) +{ + const struct PinIndex *index; + + if (pin < ITEM_NUM(pins)) { + index = &pins[pin]; + if (index->index == -1) + index = NONE; + } else { + index = NONE; + } + + return index; +} + +static int32 GpioConfigMode(int mode, const struct PinIndex* index) +{ + stc_gpio_init_t stcGpioInit; + NULL_PARAM_CHECK(index); + + GPIO_StructInit(&stcGpioInit); + + switch (mode) + { + case GPIO_CFG_OUTPUT: + stcGpioInit.u16PinDir = PIN_DIR_OUT; + stcGpioInit.u16PinOutputType = PIN_OUT_TYPE_CMOS; + break; + case GPIO_CFG_INPUT: + stcGpioInit.u16PinDir = PIN_DIR_IN; + break; + case GPIO_CFG_INPUT_PULLUP: + stcGpioInit.u16PinDir = PIN_DIR_IN; + stcGpioInit.u16PullUp = PIN_PU_ON; + break; + case GPIO_CFG_INPUT_PULLDOWN: + stcGpioInit.u16PinDir = PIN_DIR_IN; + stcGpioInit.u16PullUp = PIN_PU_OFF; + break; + case GPIO_CFG_OUTPUT_OD: + stcGpioInit.u16PinDir = PIN_DIR_OUT; + stcGpioInit.u16PinOutputType = PIN_OUT_TYPE_NMOS; + break; + default: + break; + } + + GPIO_Init(index->pin, index->pin, &stcGpioInit); +} + +static int32 GpioIrqRegister(int32 pin, int32 mode, void (*hdr)(void *args), void *args) +{ + const struct PinIndex *index = GetPin(pin); + int32 irqindex = -1; + + irqindex = GPIO_PIN_INDEX(index->pin); + if (irqindex >= ITEM_NUM(pin_irq_map)) { + return -ENONESYS; + } + + x_base level = CriticalAreaLock(); + if (pin_irq_hdr_tab[irqindex].pin == pin && + pin_irq_hdr_tab[irqindex].hdr == hdr && + pin_irq_hdr_tab[irqindex].mode == mode && + pin_irq_hdr_tab[irqindex].args == args + ) { + CriticalAreaUnLock(level); + return EOK; + } + if (pin_irq_hdr_tab[irqindex].pin != -1) { + CriticalAreaUnLock(level); + return -EDEV_BUSY; + } + pin_irq_hdr_tab[irqindex].pin = pin; + pin_irq_hdr_tab[irqindex].hdr = hdr; + pin_irq_hdr_tab[irqindex].mode = mode; + pin_irq_hdr_tab[irqindex].args = args; + CriticalAreaUnLock(level); + + return EOK; +} + +static uint32 GpioIrqFree(x_base pin) +{ + const struct PinIndex* index = GetPin(pin); + int32 irqindex = -1; + + irqindex = GPIO_PIN_INDEX(index->pin); + if (irqindex >= ITEM_NUM(pin_irq_map)) { + return -ENONESYS; + } + + x_base level = CriticalAreaLock(); + if (pin_irq_hdr_tab[irqindex].pin == -1) { + CriticalAreaUnLock(level); + return EOK; + } + pin_irq_hdr_tab[irqindex].pin = -1; + pin_irq_hdr_tab[irqindex].hdr = NONE; + pin_irq_hdr_tab[irqindex].mode = 0; + pin_irq_hdr_tab[irqindex].args = NONE; + CriticalAreaUnLock(level); + + return EOK; +} + +static void GpioIrqConfig(uint8_t u8Port, uint16_t u16Pin, uint16_t u16ExInt) +{ + __IO uint16_t *PCRx; + uint16_t pin_num; + + pin_num = __CLZ(__RBIT(u16Pin)); + PCRx = (__IO uint16_t *)((uint32_t)(&CM_GPIO->PCRA0) + ((uint32_t)u8Port * 0x40UL) + (pin_num * 4UL)); + MODIFY_REG16(*PCRx, GPIO_PCR_INTE, u16ExInt); +} + +static int32 GpioIrqEnable(x_base pin) +{ + struct Hc32PinIrqMap *irq_map; + const struct PinIndex* index = GetPin(pin); + int32 irqindex = -1; + stc_extint_init_t stcExtIntInit; + + irqindex = GPIO_PIN_INDEX(index->pin); + if (irqindex >= ITEM_NUM(pin_irq_map)) { + return -ENONESYS; + } + + x_base level = CriticalAreaLock(); + if (pin_irq_hdr_tab[irqindex].pin == -1) { + CriticalAreaUnLock(level); + return -ENONESYS; + } + + /* Extint config */ + EXTINT_StructInit(&stcExtIntInit); + switch (pin_irq_hdr_tab[irqindex].mode) + { + case GPIO_IRQ_EDGE_RISING: + stcExtIntInit.u32Edge = EXTINT_TRIG_RISING; + break; + case GPIO_IRQ_EDGE_FALLING: + stcExtIntInit.u32Edge = EXTINT_TRIG_FALLING; + break; + case GPIO_IRQ_EDGE_BOTH: + stcExtIntInit.u32Edge = EXTINT_TRIG_BOTH; + break; + case GPIO_IRQ_LEVEL_LOW: + stcExtIntInit.u32Edge = EXTINT_TRIG_LOW; + break; + } + EXTINT_Init(index->pin, &stcExtIntInit); + NVIC_EnableIRQ(irq_map->irq_config.irq_num); + GpioIrqConfig(index->pin, index->pin, PIN_EXTINT_ON); + + CriticalAreaUnLock(level); + return EOK; +} + +static int32 GpioIrqDisable(x_base pin) +{ + struct Hc32PinIrqMap *irq_map; + const struct PinIndex* index = GetPin(pin); + + x_base level = CriticalAreaLock(); + + GpioIrqConfig(index->pin, index->pin, PIN_EXTINT_OFF); + NVIC_DisableIRQ(irq_map->irq_config.irq_num); + + CriticalAreaUnLock(level); + return EOK; +} + +static uint32 Hc32PinConfigure(struct PinParam *param) +{ + NULL_PARAM_CHECK(param); + uint32 ret = EOK; + + const struct PinIndex *index = GetPin(param->pin); + switch(param->cmd) + { + case GPIO_CONFIG_MODE: + GpioConfigMode(param->mode, index); + break; + case GPIO_IRQ_REGISTER: + ret = GpioIrqRegister(param->pin, param->irq_set.irq_mode, param->irq_set.hdr, param->irq_set.args); + break; + case GPIO_IRQ_FREE: + ret = GpioIrqFree(param->pin); + break; + case GPIO_IRQ_ENABLE: + ret = GpioIrqEnable(param->pin); + break; + case GPIO_IRQ_DISABLE: + ret = GpioIrqDisable(param->pin); + break; + default: + ret = -EINVALED; + break; + } + + return ret; +} + +static uint32 Hc32PinInit(void) +{ + static x_bool pin_init_flag = RET_FALSE; + + if (!pin_init_flag) { + pin_init_flag = RET_TRUE; + } + + return EOK; +} + +static uint32 Hc32GpioDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct PinParam *param; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = Hc32PinInit(); + break; + case OPE_CFG: + param = (struct PinParam *)configure_info->private_data; + ret = Hc32PinConfigure(param); + break; + default: + break; + } + + return ret; +} + +uint32 Hc32PinWrite(void *dev, struct BusBlockWriteParam *write_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(write_param); + + struct PinStat *pinstat = (struct PinStat *)write_param->buffer; + const struct PinIndex* index = GetPin(pinstat->pin); + NULL_PARAM_CHECK(index); + + if (GPIO_LOW == pinstat->val) { + GPIO_ResetPins(index->pin, index->pin); + } else { + GPIO_SetPins(index->pin, index->pin); + } + + return EOK; +} + +uint32 Hc32PinRead(void *dev, struct BusBlockReadParam *read_param) +{ + NULL_PARAM_CHECK(dev); + NULL_PARAM_CHECK(read_param); + struct PinStat *pinstat = (struct PinStat *)read_param->buffer; + const struct PinIndex* index = GetPin(pinstat->pin); + NULL_PARAM_CHECK(index); + + if(GPIO_ReadInputPins(index->pin, index->pin) == PIN_RESET) { + pinstat->val = GPIO_LOW; + } else { + pinstat->val = GPIO_HIGH; + } + return pinstat->val; +} + +static const struct PinDevDone dev_done = +{ + .open = NONE, + .close = NONE, + .write = Hc32PinWrite, + .read = Hc32PinRead, +}; + +int HwGpioInit(void) +{ + x_err_t ret = EOK; + + static struct PinBus pin; + memset(&pin, 0, sizeof(struct PinBus)); + + ret = PinBusInit(&pin, PIN_BUS_NAME); + if (ret != EOK) { + KPrintf("gpio bus init error %d\n", ret); + return ERROR; + } + + static struct PinDriver drv; + memset(&drv, 0, sizeof(struct PinDriver)); + drv.configure = &Hc32GpioDrvConfigure; + + ret = PinDriverInit(&drv, PIN_DRIVER_NAME, NONE); + if (ret != EOK) { + KPrintf("pin driver init error %d\n", ret); + return ERROR; + } + + ret = PinDriverAttachToBus(PIN_DRIVER_NAME, PIN_BUS_NAME); + if (ret != EOK) { + KPrintf("pin driver attach error %d\n", ret); + return ERROR; + } + + static struct PinHardwareDevice dev; + memset(&dev, 0, sizeof(struct PinHardwareDevice)); + dev.dev_done = &dev_done; + + ret = PinDeviceRegister(&dev, NONE, PIN_DEVICE_NAME); + if (ret != EOK) { + KPrintf("pin device register error %d\n", ret); + return ERROR; + } + + ret = PinDeviceAttachToBus(PIN_DEVICE_NAME, PIN_BUS_NAME); + if (ret != EOK) { + KPrintf("pin device register error %d\n", ret); + return ERROR; + } + + return ret; +} + +//#define GPIO_LED_TEST +#ifdef GPIO_LED_TEST + +static void GpioLedDelay(void) +{ + volatile uint32_t i = 0; + for (i = 0; i < 8000000; ++i) + { + __asm("NOP"); /* delay */ + } +} + +void GpioLedTest(void) +{ + BusType pin; + struct BusConfigureInfo configure_info; + struct BusBlockWriteParam write_param; + + int ret = 0; + int pinSet = -1; + + pin = BusFind(PIN_BUS_NAME); + if (!pin) { + KPrintf("find %s failed!\n", PIN_BUS_NAME); + return; + } + pin->owner_driver = BusFindDriver(pin, PIN_DRIVER_NAME); + pin->owner_haldev = BusFindDevice(pin, PIN_DEVICE_NAME); + + configure_info.configure_cmd = OPE_INT; + ret = BusDrvConfigure(pin->owner_driver, &configure_info); + if (ret != EOK) { + KPrintf("initialize %s failed!\n", PIN_BUS_NAME); + return; + } + + struct PinParam led_gpio_param; + struct PinStat led_gpio_stat; + + // 134 -> PortI Pin03 LED3 + x_base pinIndex = 134; + led_gpio_param.cmd = GPIO_CONFIG_MODE; + led_gpio_param.pin = pinIndex; + led_gpio_param.mode = GPIO_CFG_OUTPUT; + + configure_info.configure_cmd = OPE_CFG; + configure_info.private_data = (void *)&led_gpio_param; + ret = BusDrvConfigure(pin->owner_driver, &configure_info); + if (ret != EOK) { + KPrintf("config pin failed!\n"); + return; + } + + while (1) { + GpioLedDelay(); + + if (pinSet) { + /* set led pin as high*/ + led_gpio_stat.pin = pinIndex; + led_gpio_stat.val = GPIO_HIGH; + write_param.buffer = (void *)&led_gpio_stat; + BusDevWriteData(pin->owner_haldev, &write_param); + pinSet = 0; + } else { + /* set led pin as low*/ + led_gpio_stat.pin = pinIndex; + led_gpio_stat.val = GPIO_LOW; + write_param.buffer = (void *)&led_gpio_stat; + BusDevWriteData(pin->owner_haldev, &write_param); + pinSet = 1; + } + } +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + GpioLedTest, GpioLedTest, gpio led test); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/Kconfig b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/Kconfig new file mode 100644 index 000000000..7808c6abb --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/Kconfig @@ -0,0 +1,22 @@ +config I2C_BUS_NAME_1 + string "i2c 1 bus name" + default "i2c1" +config I2C_DRV_NAME_1 + string "i2c bus 1 driver name" + default "i2c1_drv" +config I2C_1_DEVICE_NAME_0 + string "i2c bus 1 device 0 name" + default "i2c1_dev0" +config I2C_DEVICE_MODE + bool "choose i2c device mode as master or slave" + default y + choice + prompt "choose i2c mode" + default I2C_DEVICE_MASTER + + config I2C_DEVICE_MASTER + bool "set i2c master" + + config I2C_DEVICE_SLAVE + bool "set i2c slave" + endchoice diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/Makefile b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/Makefile new file mode 100644 index 000000000..4acf3b676 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/Makefile @@ -0,0 +1,3 @@ +SRC_FILES := connect_i2c.c + +include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/connect_i2c.c new file mode 100644 index 000000000..4285425f4 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/i2c/connect_i2c.c @@ -0,0 +1,485 @@ +/* + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file connect_i2c.c +* @brief support hc32f4a0-board i2c function and register to bus framework +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +/************************************************* +File name: connect_i2c.c +Description: support hc32f4a0-board i2c configure and i2c bus register function +Others: take projects/ev_hc32f4a0_lqfp176/examples/i2c/i2c_master_polling/source/main.c for references +History: +1. Date: 2022-12-05 +Author: AIIT XUOS Lab +Modification: +1. support hc32f4a0-board i2c configure, write and read +2. support hc32f4a0-board i2c bus device and driver register +*************************************************/ + +#include + +#define I2C_UNIT (CM_I2C1) +#define I2C_FCG_USE (FCG1_PERIPH_I2C1) + +#define I2C_TIMEOUT (0x40000UL) +#define I2C_BAUDRATE (400000UL) + +/* Define port and pin for SDA and SCL */ +#define I2C_SCL_PORT (GPIO_PORT_D) +#define I2C_SCL_PIN (GPIO_PIN_03) +#define I2C_SDA_PORT (GPIO_PORT_F) +#define I2C_SDA_PIN (GPIO_PIN_10) +#define I2C_GPIO_SCL_FUNC (GPIO_FUNC_49) +#define I2C_GPIO_SDA_FUNC (GPIO_FUNC_48) + +static x_err_t I2cGpioInit(void) +{ + GPIO_SetFunc(I2C_SDA_PORT, I2C_SDA_PIN, I2C_GPIO_SDA_FUNC); + GPIO_SetFunc(I2C_SCL_PORT, I2C_SCL_PIN, I2C_GPIO_SCL_FUNC); + + return EOK; +} + +static uint32 I2cInit(struct I2cDriver *i2c_drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(i2c_drv); + + struct I2cHardwareDevice *i2c_dev = (struct I2cHardwareDevice *)i2c_drv->driver.owner_bus->owner_haldev; + + stc_i2c_init_t i2c_init; + (void)I2C_StructInit(&i2c_init); + i2c_init.u32Baudrate = I2C_BAUDRATE; + i2c_init.u32SclTime = 3UL; + i2c_init.u32ClockDiv = I2C_CLK_DIV4; + + if (configure_info->private_data) { + i2c_dev->i2c_dev_addr = *((uint16 *)configure_info->private_data); + } else { + KPrintf("I2cInit need set i2c dev addr\n"); + return ERROR; + } + + /* Configure I2C */ + float32_t f32Error; + int32_t i32Ret = LL_ERR; + I2C_DeInit(I2C_UNIT); + i32Ret = I2C_Init(I2C_UNIT, &i2c_init, &f32Error); + +#ifdef I2C_DEVICE_SLAVE + if (LL_OK == i32Ret) { + /* Set slave address */ + I2C_SlaveAddrConfig(I2C_UNIT, I2C_ADDR0, I2C_ADDR_7BIT, i2c_dev->i2c_dev_addr); + } +#endif + + if(i32Ret != LL_OK) { + return ERROR; + } + + I2C_BusWaitCmd(I2C_UNIT, ENABLE); + + return EOK; +} + +static uint32 I2cDrvConfigure(void *drv, struct BusConfigureInfo *configure_info) +{ + NULL_PARAM_CHECK(drv); + NULL_PARAM_CHECK(configure_info); + + x_err_t ret = EOK; + struct I2cDriver *i2c_drv = (struct I2cDriver *)drv; + + switch (configure_info->configure_cmd) + { + case OPE_INT: + ret = I2cInit(i2c_drv, configure_info); + break; + default: + break; + } + + return ret; +} + +static uint32 I2cMasterWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + DDL_DelayMS(20UL); + I2C_SWResetCmd(I2C_UNIT, ENABLE); + I2C_SWResetCmd(I2C_UNIT, DISABLE); + DDL_DelayMS(20UL); + i32Ret = I2C_Start(I2C_UNIT, I2C_TIMEOUT); + if (LL_OK == i32Ret) { + i32Ret = I2C_TransAddr(I2C_UNIT, i2c_dev->i2c_dev_addr, I2C_DIR_TX, I2C_TIMEOUT); + + if (i32Ret == LL_OK) { + i32Ret = I2C_TransData(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Master Send Success!\n"); + } + } + + (void)I2C_Stop(I2C_UNIT, I2C_TIMEOUT); + I2C_Cmd(I2C_UNIT, DISABLE); + + return i32Ret; +} + +static uint32 I2cMasterReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) +{ + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + I2C_SWResetCmd(I2C_UNIT, ENABLE); + I2C_SWResetCmd(I2C_UNIT, DISABLE); + i32Ret = I2C_Start(I2C_UNIT, I2C_TIMEOUT); + if (LL_OK == i32Ret) { + if (msg->len == 1U) { + I2C_AckConfig(I2C_UNIT, I2C_NACK); + } + + i32Ret = I2C_TransAddr(I2C_UNIT, i2c_dev->i2c_dev_addr, I2C_DIR_RX, I2C_TIMEOUT); + + if (LL_OK == i32Ret) { + i32Ret = I2C_MasterReceiveDataAndStop(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Master Receive Success!\n"); + } + + I2C_AckConfig(I2C_UNIT, I2C_ACK); + } + + if (LL_OK != i32Ret) { + (void)I2C_Stop(I2C_UNIT, I2C_TIMEOUT); + } + I2C_Cmd(I2C_UNIT, DISABLE); + return i32Ret; +} + +static uint32 I2cSlaveWriteData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) { + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + + /* Clear status */ + I2C_ClearStatus(I2C_UNIT, I2C_CLR_STOPFCLR | I2C_CLR_NACKFCLR); + + /* Wait slave address matched */ + while (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_MATCH_ADDR0)) { + ; + } + + I2C_ClearStatus(I2C_UNIT, I2C_CLR_SLADDR0FCLR); + + if (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_TRA)) { + i32Ret = LL_ERR; + } else { + i32Ret = I2C_TransData(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Slave send success!\r\n"); + + if ((LL_OK == i32Ret) || (LL_ERR_TIMEOUT == i32Ret)) { + /* Release SCL pin */ + (void)I2C_ReadData(I2C_UNIT); + + /* Wait stop condition */ + i32Ret = I2C_WaitStatus(I2C_UNIT, I2C_FLAG_STOP, SET, I2C_TIMEOUT); + } + } + + I2C_Cmd(I2C_UNIT, DISABLE); + return i32Ret; +} + +static uint32 I2cSlaveReadData(struct I2cHardwareDevice *i2c_dev, struct I2cDataStandard *msg) { + uint32 i32Ret; + + I2C_Cmd(I2C_UNIT, ENABLE); + + /* Clear status */ + I2C_ClearStatus(I2C_UNIT, I2C_CLR_STOPFCLR | I2C_CLR_NACKFCLR); + + /* Wait slave address matched */ + while (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_MATCH_ADDR0)) { + ; + } + + I2C_ClearStatus(I2C_UNIT, I2C_CLR_SLADDR0FCLR); + + if (RESET == I2C_GetStatus(I2C_UNIT, I2C_FLAG_TRA)) { + /* Slave receive data*/ + i32Ret = I2C_ReceiveData(I2C_UNIT, msg->buf, msg->len, I2C_TIMEOUT); + KPrintf("Slave receive success!\r\n"); + + if ((LL_OK == i32Ret) || (LL_ERR_TIMEOUT == i32Ret)) { + /* Wait stop condition */ + i32Ret = I2C_WaitStatus(I2C_UNIT, I2C_FLAG_STOP, SET, I2C_TIMEOUT); + } + } else { + i32Ret = LL_ERR; + } + + I2C_Cmd(I2C_UNIT, DISABLE); + return i32Ret; +} + + +/* manage the i2c device operations*/ +static const struct I2cDevDone i2c_dev_done = +{ + .dev_open = NONE, + .dev_close = NONE, +#ifdef I2C_DEVICE_SLAVE + .dev_write = I2cSlaveWriteData, + .dev_read = I2cSlaveReadData, +#else + .dev_write = I2cMasterWriteData, + .dev_read = I2cMasterReadData, +#endif +}; + +/* Init i2c bus */ +static int BoardI2cBusInit(struct I2cBus *i2c_bus, struct I2cDriver *i2c_driver) +{ + x_err_t ret = EOK; + + /* Init the i2c bus */ + ret = I2cBusInit(i2c_bus, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cBusInit error %d\n", ret); + return ERROR; + } + + /* Init the i2c driver*/ + ret = I2cDriverInit(i2c_driver, I2C_DRV_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDriverInit error %d\n", ret); + return ERROR; + } + + /* Attach the i2c driver to the i2c bus*/ + ret = I2cDriverAttachToBus(I2C_DRV_NAME_1, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDriverAttachToBus error %d\n", ret); + return ERROR; + } + + return ret; +} + +/* Attach the i2c device to the i2c bus*/ +static int BoardI2cDevBend(void) +{ + x_err_t ret = EOK; + static struct I2cHardwareDevice i2c_device0; + memset(&i2c_device0, 0, sizeof(struct I2cHardwareDevice)); + + i2c_device0.i2c_dev_done = &i2c_dev_done; + + ret = I2cDeviceRegister(&i2c_device0, NONE, I2C_1_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDeviceInit device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + ret = I2cDeviceAttachToBus(I2C_1_DEVICE_NAME_0, I2C_BUS_NAME_1); + if (EOK != ret) { + KPrintf("board_i2c_init I2cDeviceAttachToBus device %s error %d\n", I2C_1_DEVICE_NAME_0, ret); + return ERROR; + } + + return ret; +} + +/* HC32F4A0 BOARD I2C INIT*/ +int HwI2cInit(void) +{ + x_err_t ret = EOK; + static struct I2cBus i2c_bus; + memset(&i2c_bus, 0, sizeof(struct I2cBus)); + + static struct I2cDriver i2c_driver; + memset(&i2c_driver, 0, sizeof(struct I2cDriver)); + + I2cGpioInit(); + + /* Enable I2C Peripheral*/ + FCG_Fcg1PeriphClockCmd(I2C_FCG_USE, ENABLE); + + i2c_driver.configure = I2cDrvConfigure; + + ret = BoardI2cBusInit(&i2c_bus, &i2c_driver); + if (ret != EOK) { + KPrintf("board_i2c_init error ret %u\n", ret); + return ERROR; + } + + ret = BoardI2cDevBend(); + if (EOK != ret) { + KPrintf("board_i2c_init error ret %u\n", ret); + return ERROR; + } + + return ret; +} + +//#define I2C_TEST +#ifdef I2C_TEST + +#define USER_KEY_PORT (GPIO_PORT_I) +#define USER_KEY_PIN (GPIO_PIN_07) + +#define DEVICE_ADDR (0x06U) + +static struct Bus *bus1; +static struct I2cDriver *i2c_drv1; + +void I2cInitTest(void) +{ + x_err_t ret = EOK; + + stc_gpio_init_t stcGpioInit; + + /* KEY initialize */ + (void)GPIO_StructInit(&stcGpioInit); + stcGpioInit.u16PinState = PIN_STAT_RST; + stcGpioInit.u16PinDir = PIN_DIR_IN; + (void)GPIO_Init(USER_KEY_PORT, USER_KEY_PIN, &stcGpioInit); + + bus1 = BusFind(I2C_BUS_NAME_1); + bus1->owner_driver = BusFindDriver(bus1, I2C_DRV_NAME_1); + bus1->owner_haldev = BusFindDevice(bus1, I2C_1_DEVICE_NAME_0); + + struct BusConfigureInfo configure_info; + configure_info.configure_cmd = OPE_INT; + configure_info.private_data = (void *)DEVICE_ADDR; + + ret = I2cDrvConfigure(bus1->owner_driver, &configure_info); + if (ret != EOK) { + KPrintf("initialize %s failed!\n", I2C_UNIT); + return; + } + + i2c_drv1 = (struct I2cDriver *)bus1->owner_driver; + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +I2cInitTest, I2cInitTest, i2c init); + +void I2cMasterTest(void) +{ + x_err_t ret = EOK; + + struct I2cHardwareDevice *i2c_dev1 = (struct I2cHardwareDevice *)i2c_drv1->driver.owner_bus->owner_haldev; + + struct I2cDataStandard msg; + uint8 u8TxBuf[256U] = {1, 2, 3, 4, 5}; + uint8 u8RxBuf[256U]; + + (void)memset(u8RxBuf, 0, 256U); + + msg.len = 5; + msg.buf = u8TxBuf; + + while (SET == GPIO_ReadInputPins(USER_KEY_PORT, USER_KEY_PIN)) { + ; + } + + KPrintf("I2C send data\n"); + + ret = I2cMasterWriteData(i2c_dev1, &msg); + if (EOK != ret) { + KPrintf("I2C send failed! ret %d\n", ret); + return; + } + + KPrintf("Master send data: "); + + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + + KPrintf("\n"); + + /* 50mS delay for device*/ + DDL_DelayMS(50UL); + + msg.buf = u8RxBuf; + + (void)I2cMasterReadData(i2c_dev1, &msg); + + KPrintf("Master receive data: "); + + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + + KPrintf("\n"); + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +I2cMasterTest, I2cMasterTest, i2c master send and receive data); + +void I2cSlaveTest(void) +{ + x_err_t ret = EOK; + + struct I2cHardwareDevice *i2c_dev1 = (struct I2cHardwareDevice *)i2c_drv1->driver.owner_bus->owner_haldev; + + struct I2cDataStandard msg; + uint8 u8RxBuf[256U]; + + (void)memset(u8RxBuf, 0, 256U); + + msg.len = 5; + msg.buf = u8RxBuf; + + KPrintf("I2C receive data\n"); + + for (;;) { + ret = I2cSlaveReadData(i2c_dev1, &msg); + if (ret != EOK) { + KPrintf("I2C receive failed!\n"); + break; + } else { + KPrintf("Slave receive data: "); + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + KPrintf("\n"); + } + + ret = I2cSlaveWriteData(i2c_dev1, &msg); + if (ret != EOK) { + KPrintf("I2C send failed!\n"); + break; + } else { + KPrintf("Slave send data: "); + for (uint16 i = 0; i < msg.len; i++) { + KPrintf("%d ", (msg.buf)[i]); + } + KPrintf("\n"); + } + } + + return; +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), +I2cSlaveTest, I2cSlaveTest, i2c slave receive and send data); + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_ethernet.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_ethernet.h new file mode 100644 index 000000000..625c1d815 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_ethernet.h @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2021 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_ethernet.h +* @brief Adapted network software protocol stack and hardware operation functions +* @version 2.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +#ifndef CONNECT_ETHERNET_H +#define CONNECT_ETHERNET_H + +#include "hardware_ethernetif.h" + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_gpio.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_gpio.h new file mode 100644 index 000000000..b6f27b1ce --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_gpio.h @@ -0,0 +1,191 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_gpio.h +* @brief define hc32f4a0-board gpio function and struct +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +#ifndef CONNECT_GPIO_H +#define CONNECT_GPIO_H + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct Hc32PinIrqMap +{ + uint16_t pinbit; + func_ptr_t irq_callback; + struct Hc32IrqConfig irq_config; +}; + +#ifndef EXTINT0_IRQ_CONFIG +#define EXTINT0_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT0_IRQ_NUM, \ + .irq_prio = BSP_EXTINT0_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ0, \ + } +#endif /* EXTINT1_IRQ_CONFIG */ + +#ifndef EXTINT1_IRQ_CONFIG +#define EXTINT1_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT1_IRQ_NUM, \ + .irq_prio = BSP_EXTINT1_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ1, \ + } +#endif /* EXTINT1_IRQ_CONFIG */ + +#ifndef EXTINT2_IRQ_CONFIG +#define EXTINT2_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT2_IRQ_NUM, \ + .irq_prio = BSP_EXTINT2_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ2, \ + } +#endif /* EXTINT2_IRQ_CONFIG */ + +#ifndef EXTINT3_IRQ_CONFIG +#define EXTINT3_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT3_IRQ_NUM, \ + .irq_prio = BSP_EXTINT3_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ3, \ + } +#endif /* EXTINT3_IRQ_CONFIG */ + +#ifndef EXTINT4_IRQ_CONFIG +#define EXTINT4_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT4_IRQ_NUM, \ + .irq_prio = BSP_EXTINT4_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ4, \ + } +#endif /* EXTINT4_IRQ_CONFIG */ + +#ifndef EXTINT5_IRQ_CONFIG +#define EXTINT5_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT5_IRQ_NUM, \ + .irq_prio = BSP_EXTINT5_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ5, \ + } +#endif /* EXTINT5_IRQ_CONFIG */ + +#ifndef EXTINT6_IRQ_CONFIG +#define EXTINT6_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT6_IRQ_NUM, \ + .irq_prio = BSP_EXTINT6_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ6, \ + } +#endif /* EXTINT6_IRQ_CONFIG */ + +#ifndef EXTINT7_IRQ_CONFIG +#define EXTINT7_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT7_IRQ_NUM, \ + .irq_prio = BSP_EXTINT7_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ7, \ + } +#endif /* EXTINT7_IRQ_CONFIG */ + +#ifndef EXTINT8_IRQ_CONFIG +#define EXTINT8_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT8_IRQ_NUM, \ + .irq_prio = BSP_EXTINT8_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ8, \ + } +#endif /* EXTINT8_IRQ_CONFIG */ + +#ifndef EXTINT9_IRQ_CONFIG +#define EXTINT9_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT9_IRQ_NUM, \ + .irq_prio = BSP_EXTINT9_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ9, \ + } +#endif /* EXTINT9_IRQ_CONFIG */ + +#ifndef EXTINT10_IRQ_CONFIG +#define EXTINT10_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT10_IRQ_NUM, \ + .irq_prio = BSP_EXTINT10_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ10, \ + } +#endif /* EXTINT10_IRQ_CONFIG */ + +#ifndef EXTINT11_IRQ_CONFIG +#define EXTINT11_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT11_IRQ_NUM, \ + .irq_prio = BSP_EXTINT11_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ11, \ + } +#endif /* EXTINT11_IRQ_CONFIG */ + +#ifndef EXTINT12_IRQ_CONFIG +#define EXTINT12_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT12_IRQ_NUM, \ + .irq_prio = BSP_EXTINT12_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ12, \ + } +#endif /* EXTINT12_IRQ_CONFIG */ + +#ifndef EXTINT13_IRQ_CONFIG +#define EXTINT13_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT13_IRQ_NUM, \ + .irq_prio = BSP_EXTINT13_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ13, \ + } +#endif /* EXTINT13_IRQ_CONFIG */ + +#ifndef EXTINT14_IRQ_CONFIG +#define EXTINT14_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT14_IRQ_NUM, \ + .irq_prio = BSP_EXTINT14_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ14, \ + } +#endif /* EXTINT14_IRQ_CONFIG */ + +#ifndef EXTINT15_IRQ_CONFIG +#define EXTINT15_IRQ_CONFIG \ + { \ + .irq_num = BSP_EXTINT15_IRQ_NUM, \ + .irq_prio = BSP_EXTINT15_IRQ_PRIO, \ + .int_src = INT_SRC_PORT_EIRQ15, \ + } +#endif /* EXTINT15_IRQ_CONFIG */ + +int HwGpioInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_i2c.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_i2c.h new file mode 100644 index 000000000..2da6b2683 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/connect_i2c.h @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file connect_i2c.h +* @brief define hc32f4a0-board i2c function and struct +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +#ifndef CONNECT_I2C_H +#define CONNECT_I2C_H + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +int HwI2cInit(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h new file mode 100644 index 000000000..0fb839584 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/hc32f4a0/third_party_driver/include/hardware_ethernetif.h @@ -0,0 +1,172 @@ +/** + ******************************************************************************* + * @file eth/eth_loopback/source/ethernetif.h + * @brief Ethernet interface header file. + @verbatim + Change Logs: + Date Author Notes + 2022-03-31 CDT First version + @endverbatim + ******************************************************************************* + * Copyright (C) 2022, Xiaohua Semiconductor Co., Ltd. All rights reserved. + * + * This software component is licensed by XHSC under BSD 3-Clause license + * (the "License"); You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ******************************************************************************* + */ + +/** +* @file hardware_ethernetif.h +* @brief define hc32f4a0-board ethernetif function and struct +* @version 3.0 +* @author AIIT XUOS Lab +* @date 2022-12-05 +*/ + +#ifndef HARDWARE_ETHERNETIF_H +#define HARDWARE_ETHERNETIF_H + +/* C binding of definitions if building with C++ compiler */ +#ifdef __cplusplus +extern "C" +{ +#endif + +/******************************************************************************* + * Include files + ******************************************************************************/ +#include +#include +#include +#include + +/** + * @addtogroup HC32F4A0_DDL_Examples + * @{ + */ + +/** + * @addtogroup ETH_Loopback + * @{ + */ + +/******************************************************************************* + * Global type definitions ('typedef') + ******************************************************************************/ +/** + * @defgroup ETH_IF_Global_Types Ethernet Interface Global Types + * @{ + */ + +/** + * @} + */ + +/******************************************************************************* + * Global pre-processor symbols/macros ('#define') + ******************************************************************************/ +/** + * @defgroup ETH_IF_Global_Macros Ethernet Interface Global Macros + * @{ + */ + +/* Ethernet PHY interface */ +// #define ETH_INTERFACE_RMII + +/* Number of milliseconds when to check for link status from PHY */ +#ifndef LINK_TIMER_INTERVAL +#define LINK_TIMER_INTERVAL (1000U) +#endif + +/* ETH PHY link status */ +#define ETH_LINK_DOWN (0U) +#define ETH_LINK_UP (1U) + +/* Extended PHY Registers */ +#define PHY_PSMR (0x18U) /*!< Power Saving Mode Register */ +#define PHY_IISDR (0x1EU) /*!< Interrupt Indicators and SNR Display Register */ +#define PHY_PSR (0x1FU) /*!< Page Select Register */ +#define PHY_P7_RMSR (0x10U) /*!< RMII Mode Setting Register */ +#define PHY_P7_IWLFR (0x13U) /*!< Interrupt, WOL Enable, and LED Function Registers */ + +/* The following parameters will return to default values after a software reset */ +#define PHY_EN_PWR_SAVE (0x8000U) /*!< Enable Power Saving Mode */ + +#define PHY_FLAG_AUTO_NEGO_ERROR (0x8000U) /*!< Auto-Negotiation Error Interrupt Flag */ +#define PHY_FLAG_SPEED_MODE_CHANGE (0x4000U) /*!< Speed Mode Change Interrupt Flag */ +#define PHY_FLAG_DUPLEX_MODE_CHANGE (0x2000U) /*!< Duplex Mode Change Interrupt Flag */ +#define PHY_FLAG_LINK_STATUS_CHANGE (0x0800U) /*!< Link Status Change Interrupt Flag */ + +#define PHY_PAGE_ADDR_0 (0x0000U) /*!< Page Address 0 (default) */ +#define PHY_PAGE_ADDR_7 (0x0007U) /*!< Page Address 7 */ + +#define PHY_RMII_CLK_DIR (0x1000U) /*!< TXC direction in RMII Mode */ +#define PHY_RMII_MODE (0x0008U) /*!< RMII Mode or MII Mode */ +#define PHY_RMII_RXDV_CRSDV (0x0004U) /*!< CRS_DV or RXDV select */ + +#define PHY_INT_LINK_CHANGE (0x2000U) /*!< Link Change Interrupt Mask */ +#define PHY_INT_DUPLEX_CHANGE (0x1000U) /*!< Duplex Change Interrupt Mask */ +#define PHY_INT_AUTO_NEGO_ERROR (0x0800U) /*!< Auto-Negotiation Error Interrupt Mask */ +#define PHY_LED_WOL_SELECT (0x0400U) /*!< LED and Wake-On-LAN Function Selection */ +#define PHY_LED_SELECT (0x0030U) /*!< Traditional LED Function Selection. */ +#define PHY_LED_SELECT_00 (0x0000U) /*!< LED0: ACT(all) LED1: LINK(100) */ +#define PHY_LED_SELECT_01 (0x0010U) /*!< LED0: LINK(ALL)/ACT(all) LED1: LINK(100) */ +#define PHY_LED_SELECT_10 (0x0020U) /*!< LED0: LINK(10)/ACT(all) LED1: LINK(100) */ +#define PHY_LED_SELECT_11 (0x0030U) /*!< LED0: LINK(10)/ACT(10) LED1: LINK(100)/ACT(100) */ +#define PHY_EN_10M_LED_FUNC (0x0001U) /*!< Enable 10M LPI LED Function */ + +/** + * @} + */ + +/******************************************************************************* + * Global variable definitions ('extern') + ******************************************************************************/ + +/******************************************************************************* + Global function prototypes (definition in C source) + ******************************************************************************/ +/** + * @addtogroup ETH_IF_Global_Functions + * @{ + */ +err_t ethernetif_init(struct netif *netif); +void ethernetif_input(struct netif *netif); +int32_t low_level_output(struct netif *netif, struct pbuf *p); + +void EthernetIF_CheckLink(struct netif *netif); +void EthernetIF_UpdateLink(struct netif *netif); +void EthernetIF_PeriodicHandle(struct netif *netif); +void EthernetIF_LinkCallback(struct netif *netif); +int32_t EthernetIF_IsLinkUp(struct netif *netif); + +void EthernetIF_NotifyLinkChange(struct netif *netif); +void EthernetIF_InputCallback(struct netif *netif, struct pbuf *p); + +void *ethernetif_config_enet_set(uint8_t enet_port); +#define NETIF_ENET0_INIT_FUNC ethernetif_init + +/** + * @} + */ + +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* __ETHERNETIF_H__ */ + +/******************************************************************************* + * EOF (not truncated) + ******************************************************************************/ diff --git a/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/i2c/connect_i2c.c index edede3cdb..ed492af28 100644 --- a/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/i2c/connect_i2c.c +++ b/Ubiquitous/XiZi_IIoT/board/k210-emulator/third_party_driver/i2c/connect_i2c.c @@ -376,7 +376,7 @@ static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg retries = ignore_nack ? 0 : msg->retries; - if (flags & I2C_ADDR_10BIT) { + if (flags & I2C_ADDR_10BIT_MODE) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; diff --git a/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/i2c/connect_i2c.c index acbcf05c0..9eb1e107d 100644 --- a/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/i2c/connect_i2c.c +++ b/Ubiquitous/XiZi_IIoT/board/kd233/third_party_driver/i2c/connect_i2c.c @@ -376,7 +376,7 @@ static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg retries = ignore_nack ? 0 : msg->retries; - if (flags & I2C_ADDR_10BIT) { + if (flags & I2C_ADDR_10BIT_MODE) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; diff --git a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c index c09b6dc27..ef6c2bd71 100644 --- a/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c +++ b/Ubiquitous/XiZi_IIoT/board/ok1052-c/third_party_driver/semc/semc_externsdram_test.c @@ -1,180 +1,180 @@ -/* - * Copyright 2017 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ -#include "board.h" - -#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U) - -#define SEMC_EXAMPLE_DATALEN (0x1000U) - -/******************************************************************************* - * Prototypes - ******************************************************************************/ -static void SEMC_SDRAMReadWrite32Bit(void); -static void SEMC_SDRAMReadWrite16Bit(void); -static void SEMC_SDRAMReadWrite8Bit(void); -/******************************************************************************* - * Variables - ******************************************************************************/ - -uint32_t sdram_writeBuffer[SEMC_EXAMPLE_DATALEN]; -uint32_t sdram_readBuffer[SEMC_EXAMPLE_DATALEN]; - -/*! - * @brief Main function - */ -int semc_externsram_test(void) -{ - KPrintf("\r\n SEMC SDRAM Example Start!\r\n"); - - /* 32Bit data read and write. */ - SEMC_SDRAMReadWrite32Bit(); - /* 16Bit data read and write. */ - SEMC_SDRAMReadWrite16Bit(); - /* 8Bit data read and write. */ - SEMC_SDRAMReadWrite8Bit(); - - KPrintf("\r\n SEMC SDRAM Example End.\r\n"); - -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),semc_externsram_test, semc_externsram_test, semc_externsram_test ); - -void SEMC_SDRAMReadWrite32Bit(void) -{ - uint32_t index; - uint32_t datalen = SEMC_EXAMPLE_DATALEN; - uint32_t *sdram = (uint32_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ - int result = 0; - - KPrintf("\r\n SEMC SDRAM Memory 32 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); - /* Prepare data and write to SDRAM. */ - for (index = 0; index < datalen; index++) - { - sdram_writeBuffer[index] = index; - sdram[index] = sdram_writeBuffer[index]; - } - - KPrintf("\r\n SEMC SDRAM Read 32 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); - /* Read data from the SDRAM. */ - for (index = 0; index < datalen; index++) - { - sdram_readBuffer[index] = sdram[index]; - } - - KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Start!\r\n"); - /* Compare the two buffers. */ - while (datalen--) - { - if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) - { - result = -1; - break; - } - } - - if (result < 0) - { - KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Failed!\r\n"); - } - else - { - KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Succeed!\r\n"); - } -} - -static void SEMC_SDRAMReadWrite16Bit(void) -{ - uint32_t index; - uint32_t datalen = SEMC_EXAMPLE_DATALEN; - uint16_t *sdram = (uint16_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ - int result = 0; - - KPrintf("\r\n SEMC SDRAM Memory 16 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); - - memset(sdram_writeBuffer, 0, sizeof(sdram_writeBuffer)); - memset(sdram_readBuffer, 0, sizeof(sdram_readBuffer)); - - /* Prepare data and write to SDRAM. */ - for (index = 0; index < datalen; index++) - { - sdram_writeBuffer[index] = index % 0xFFFF; - sdram[index] = sdram_writeBuffer[index]; - } - - KPrintf("\r\n SEMC SDRAM Read 16 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); - /* Read data from the SDRAM. */ - for (index = 0; index < datalen; index++) - { - sdram_readBuffer[index] = sdram[index]; - } - - KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Start!\r\n"); - /* Compare the two buffers. */ - while (datalen--) - { - if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) - { - result = -1; - break; - } - } - - if (result < 0) - { - KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Failed!\r\n"); - } - else - { - KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Succeed!\r\n"); - } -} - -static void SEMC_SDRAMReadWrite8Bit(void) -{ - uint32_t index; - uint32_t datalen = SEMC_EXAMPLE_DATALEN; - uint8_t *sdram = (uint8_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ - int result = 0; - - KPrintf("\r\n SEMC SDRAM Memory 8 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); - - memset(sdram_writeBuffer, 0, sizeof(sdram_writeBuffer)); - memset(sdram_readBuffer, 0, sizeof(sdram_readBuffer)); - - /* Prepare data and write to SDRAM. */ - for (index = 0; index < datalen; index++) - { - sdram_writeBuffer[index] = index % 0x100; - sdram[index] = sdram_writeBuffer[index]; - } - - KPrintf("\r\n SEMC SDRAM Read 8 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); - /* Read data from the SDRAM. */ - for (index = 0; index < datalen; index++) - { - sdram_readBuffer[index] = sdram[index]; - } - - KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Start!\r\n"); - /* Compare the two buffers. */ - while (datalen--) - { - if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) - { - result = -1; - break; - } - } - - if (result < 0) - { - KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Failed!\r\n"); - } - else - { - KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Succeed!\r\n"); - } -} +/* + * Copyright 2017 NXP + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "board.h" + +#define EXAMPLE_SEMC_START_ADDRESS (0x80000000U) + +#define SEMC_EXAMPLE_DATALEN (0x1000U) + +/******************************************************************************* + * Prototypes + ******************************************************************************/ +static void SEMC_SDRAMReadWrite32Bit(void); +static void SEMC_SDRAMReadWrite16Bit(void); +static void SEMC_SDRAMReadWrite8Bit(void); +/******************************************************************************* + * Variables + ******************************************************************************/ + +uint32_t sdram_writeBuffer[SEMC_EXAMPLE_DATALEN]; +uint32_t sdram_readBuffer[SEMC_EXAMPLE_DATALEN]; + +/*! + * @brief Main function + */ +int semc_externsram_test(void) +{ + KPrintf("\r\n SEMC SDRAM Example Start!\r\n"); + + /* 32Bit data read and write. */ + SEMC_SDRAMReadWrite32Bit(); + /* 16Bit data read and write. */ + SEMC_SDRAMReadWrite16Bit(); + /* 8Bit data read and write. */ + SEMC_SDRAMReadWrite8Bit(); + + KPrintf("\r\n SEMC SDRAM Example End.\r\n"); + +} +//SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC)|SHELL_CMD_PARAM_NUM(0),semc_externsram_test, semc_externsram_test, semc_externsram_test ); + +void SEMC_SDRAMReadWrite32Bit(void) +{ + uint32_t index; + uint32_t datalen = SEMC_EXAMPLE_DATALEN; + uint32_t *sdram = (uint32_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ + int result = 0; + + KPrintf("\r\n SEMC SDRAM Memory 32 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Prepare data and write to SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_writeBuffer[index] = index; + sdram[index] = sdram_writeBuffer[index]; + } + + KPrintf("\r\n SEMC SDRAM Read 32 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Read data from the SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_readBuffer[index] = sdram[index]; + } + + KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Start!\r\n"); + /* Compare the two buffers. */ + while (datalen--) + { + if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) + { + result = -1; + break; + } + } + + if (result < 0) + { + KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Failed!\r\n"); + } + else + { + KPrintf("\r\n SEMC SDRAM 32 bit Data Write and Read Compare Succeed!\r\n"); + } +} + +static void SEMC_SDRAMReadWrite16Bit(void) +{ + uint32_t index; + uint32_t datalen = SEMC_EXAMPLE_DATALEN; + uint16_t *sdram = (uint16_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ + int result = 0; + + KPrintf("\r\n SEMC SDRAM Memory 16 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + + memset(sdram_writeBuffer, 0, sizeof(sdram_writeBuffer)); + memset(sdram_readBuffer, 0, sizeof(sdram_readBuffer)); + + /* Prepare data and write to SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_writeBuffer[index] = index % 0xFFFF; + sdram[index] = sdram_writeBuffer[index]; + } + + KPrintf("\r\n SEMC SDRAM Read 16 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Read data from the SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_readBuffer[index] = sdram[index]; + } + + KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Start!\r\n"); + /* Compare the two buffers. */ + while (datalen--) + { + if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) + { + result = -1; + break; + } + } + + if (result < 0) + { + KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Failed!\r\n"); + } + else + { + KPrintf("\r\n SEMC SDRAM 16 bit Data Write and Read Compare Succeed!\r\n"); + } +} + +static void SEMC_SDRAMReadWrite8Bit(void) +{ + uint32_t index; + uint32_t datalen = SEMC_EXAMPLE_DATALEN; + uint8_t *sdram = (uint8_t *)EXAMPLE_SEMC_START_ADDRESS; /* SDRAM start address. */ + int result = 0; + + KPrintf("\r\n SEMC SDRAM Memory 8 bit Write Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + + memset(sdram_writeBuffer, 0, sizeof(sdram_writeBuffer)); + memset(sdram_readBuffer, 0, sizeof(sdram_readBuffer)); + + /* Prepare data and write to SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_writeBuffer[index] = index % 0x100; + sdram[index] = sdram_writeBuffer[index]; + } + + KPrintf("\r\n SEMC SDRAM Read 8 bit Data Start, Start Address 0x%x, Data Length %d !\r\n", sdram, datalen); + /* Read data from the SDRAM. */ + for (index = 0; index < datalen; index++) + { + sdram_readBuffer[index] = sdram[index]; + } + + KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Start!\r\n"); + /* Compare the two buffers. */ + while (datalen--) + { + if (sdram_writeBuffer[datalen] != sdram_readBuffer[datalen]) + { + result = -1; + break; + } + } + + if (result < 0) + { + KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Failed!\r\n"); + } + else + { + KPrintf("\r\n SEMC SDRAM 8 bit Data Write and Read Compare Succeed!\r\n"); + } +} diff --git a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/i2c/connect_i2c.c index 7ef31b5d8..b47ac3a08 100644 --- a/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/i2c/connect_i2c.c +++ b/Ubiquitous/XiZi_IIoT/board/stm32f407-st-discovery/third_party_driver/i2c/connect_i2c.c @@ -479,7 +479,7 @@ static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg retries = ignore_nack ? 0 : msg->retries; - if (flags & I2C_ADDR_10BIT) { + if (flags & I2C_ADDR_10BIT_MODE) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link-usb.lds b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link-usb.lds index 79ad714ff..b7245b67c 100755 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link-usb.lds +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-arm32/link-usb.lds @@ -61,6 +61,8 @@ MEMORY m_text (RX) : ORIGIN = 0x60002400, LENGTH = 0x03FFDC00 m_data (RW) : ORIGIN = 0x20000000, LENGTH = 0x00020000 m_data2 (RW) : ORIGIN = 0x20200000, LENGTH = 0x00060000 + m_sdram (RW) : ORIGIN = 0x80000000, LENGTH = 0x01E00000 + m_nocache (RW) : ORIGIN = 0x81E00000, LENGTH = 0x00200000 } /* Define output sections */ diff --git a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/i2c/connect_i2c.c b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/i2c/connect_i2c.c index a17808e29..1835dfcbf 100644 --- a/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/i2c/connect_i2c.c +++ b/Ubiquitous/XiZi_IIoT/board/xidatong-riscv64/third_party_driver/i2c/connect_i2c.c @@ -376,7 +376,7 @@ static x_err_t I2cBitSendAddress(struct I2cBus *bus, struct I2cDataStandard *msg retries = ignore_nack ? 0 : msg->retries; - if (flags & I2C_ADDR_10BIT) { + if (flags & I2C_ADDR_10BIT_MODE) { addr1 = 0xf0 | ((msg->addr >> 7) & 0x06); addr2 = msg->addr & 0xff; diff --git a/Ubiquitous/XiZi_IIoT/path_kernel.mk b/Ubiquitous/XiZi_IIoT/path_kernel.mk index 917d6076c..f3d685d6a 100755 --- a/Ubiquitous/XiZi_IIoT/path_kernel.mk +++ b/Ubiquitous/XiZi_IIoT/path_kernel.mk @@ -407,6 +407,19 @@ KERNELPATHS += \ -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_class/msc \ -I$(BSP_ROOT)/third_party_driver/usb/hc32_usb_driver/usb_host_lib/host_core \ -I$(KERNEL_ROOT)/include # + +ifeq ($(CONFIG_RESOURCES_LWIP),y) +KERNELPATHS += \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/compat \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/netif \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/apps \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/priv \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/include/lwip/prot \ + -I$(KERNEL_ROOT)/resources/ethernet/LwIP/arch +endif endif KERNELPATHS += -I$(KERNEL_ROOT)/arch \ @@ -418,6 +431,12 @@ KERNELPATHS += -I$(KERNEL_ROOT)/fs/devfs \ -I$(KERNEL_ROOT)/fs/shared/include # endif +ifeq ($(CONFIG_APP_USING_WEBNET), y) +KERNELPATHS += -I$(KERNEL_ROOT)/../../APP_Framework/Applications/webnet/WebNet_XiUOS/inc \ + -I$(KERNEL_ROOT)/../../APP_Framework/lib/cJSON \ + -I$(KERNEL_ROOT)/../../Ubiquitous/XiZi/resources/ethernet/netdev/include # +endif + ifeq ($(CONFIG_FS_CH376), y) KERNELPATHS +=-I$(KERNEL_ROOT)/fs/compatibility_ch376 # endif @@ -549,4 +568,3 @@ KERNELPATHS += -I$(KERNEL_ROOT)/kernel/include # # @cp link.mk build/Makefile # @$(MAKE) -C build COMPILE_TYPE="_kernel" TARGET=XiZi-$(BOARD)_kernel.elf LINK_FLAGS=LFLAGS # @rm build/Makefile build/make.obj - diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile index 1c0cdf531..406f26dc2 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/Makefile @@ -7,5 +7,4 @@ LWIP_DIR += api LWIP_DIR += arch LWIP_DIR += core LWIP_DIR += netif - include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c index 68061aea7..c7cb3b07e 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/arch/sys_arch.c @@ -68,7 +68,6 @@ #include "board.h" #include "ethernet.h" #include "connect_ethernet.h" -#include char lwip_ipaddr[20] = {192, 168, 131, 77}; char lwip_netmask[20] = {255, 255, 254, 0}; diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/sockets.h b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/sockets.h index 2edab7be8..14ce7a9b1 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/sockets.h +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/LwIP/include/lwip/sockets.h @@ -663,7 +663,9 @@ int lwip_inet_pton(int af, const char *src, void *dst); #if LWIP_POSIX_SOCKETS_IO_NAMES /** @ingroup socket */ +#ifndef APP_USING_WEBNET #define read(s,mem,len) lwip_read(s,mem,len) +#endif /** @ingroup socket */ #define readv(s,iov,iovcnt) lwip_readv(s,iov,iovcnt) /** @ingroup socket */ diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/resources/ethernet/Makefile index 7de558d34..5954beab4 100644 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/Makefile +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/Makefile @@ -1,4 +1,5 @@ SRC_DIR += cmd_lwip +SRC_DIR += netdev LWIP_DIR := LwIP include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c index 222e0b748..314d3c0a0 100755 --- a/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c +++ b/Ubiquitous/XiZi_IIoT/resources/ethernet/cmd_lwip/lwip_config_demo.c @@ -18,8 +18,8 @@ * @date 2021.12.15 */ -#include "board.h" -#include "sys_arch.h" +#include +#include #include #include #include @@ -73,7 +73,9 @@ SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | void LwipShowIPTask(int argc, char *argv[]) { +#ifdef configMAC_ADDR char mac_addr0[] = configMAC_ADDR; +#endif lw_notice("\r\n************************************************\r\n"); lw_notice(" Network Configuration\r\n"); @@ -84,8 +86,10 @@ void LwipShowIPTask(int argc, char *argv[]) ((u8_t *)&lwip_eth0_netmask)[2], ((u8_t *)&lwip_eth0_netmask)[3]); lw_notice(" ETH0 IPv4 Gateway : %u.%u.%u.%u\r\n", ((u8_t *)&lwip_gwaddr)[0], ((u8_t *)&lwip_eth0_gwaddr)[1], ((u8_t *)&lwip_eth0_gwaddr)[2], ((u8_t *)&lwip_eth0_gwaddr)[3]); +#ifdef configMAC_ADDR lw_notice(" ETH0 MAC Address : %x:%x:%x:%x:%x:%x\r\n", mac_addr0[0], mac_addr0[1], mac_addr0[2], mac_addr0[3], mac_addr0[4], mac_addr0[5]); +#endif #ifdef BOARD_NET_COUNT if(BOARD_NET_COUNT > 1) { diff --git a/Ubiquitous/XiZi_IIoT/resources/include/dev_i2c.h b/Ubiquitous/XiZi_IIoT/resources/include/dev_i2c.h index 9a3a22789..f08fae86a 100644 --- a/Ubiquitous/XiZi_IIoT/resources/include/dev_i2c.h +++ b/Ubiquitous/XiZi_IIoT/resources/include/dev_i2c.h @@ -27,12 +27,12 @@ extern "C" { #endif -#define I2C_WR 0x0000 -#define I2C_RD (1u << 0) -#define I2C_ADDR_10BIT (1u << 2) -#define I2C_NO_START (1u << 4) +#define I2C_WR 0x0000 +#define I2C_RD (1u << 0) +#define I2C_ADDR_10BIT_MODE (1u << 2) +#define I2C_NO_START (1u << 4) #define I2C_IGNORE_NACK (1u << 5) -#define I2C_NO_READ_ACK (1u << 6) +#define I2C_NO_READ_ACK (1u << 6) struct I2cDataStandard {