From 3463c8515f921b09e6523627980e77b17ec31097 Mon Sep 17 00:00:00 2001 From: Liu_Weichao Date: Mon, 29 May 2023 16:58:22 +0800 Subject: [PATCH 1/2] feat add abstruction_mmu for XiZi_AIoT(support MmuInit\MmuSectionMap\MmuSectionUnmap\MmuTtbSwitch\MmuTransform) --- .../XiZi_AIoT/hardkernel/abstraction/Makefile | 2 +- .../hardkernel/abstraction/abstraction_mmu.c | 206 ++++++++++++++++++ .../hardkernel/abstraction/abstraction_mmu.h | 114 ++++++++++ .../XiZi_AIoT/hardkernel/abstraction/cache.c | 19 ++ .../XiZi_AIoT/hardkernel/abstraction/mmu.c | 0 .../memory/multiple-address-spaces/memory.c | 20 ++ 6 files changed, 360 insertions(+), 1 deletion(-) create mode 100755 Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.c create mode 100644 Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.h delete mode 100755 Ubiquitous/XiZi_AIoT/hardkernel/abstraction/mmu.c diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/Makefile b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/Makefile index 262587f9..c794367b 100644 --- a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/Makefile +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := cache.c isr.c mmu.c +SRC_FILES := cache.c isr.c abstraction_mmu.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.c new file mode 100755 index 00000000..6f37b7d6 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.c @@ -0,0 +1,206 @@ +/* +* 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: abstraction_mmu.c +* @brief: the general management of system mmu +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/4/27 +* +*/ + +#include + +AbstractionMmu abstraction_mmu; + +volatile uint32_t global_L1_pte_table[4096]; + +/** + * @description: write cmd to CP15 register + * @param reg_type - CP15 register type + * @param val - ops val pointer + * @return + */ +static void MmuCp15Write(uint8_t reg_type, uint32_t *val) +{ + uint32_t write_val = *val; + switch (reg_type) { + case AM_MMU_CP15_TTBCR: + TTBCR_W(write_val); + AM_ISB; + case AM_MMU_CP15_TTBR0: + TTBR0_W(write_val); + AM_ISB; + default: + break; + } +} + +/** + * @description: read CP15 register from mmu + * @param reg_type - CP15 register type + * @param val - ops val pointer + * @return + */ +static void MmuCp15Read(uint8_t reg_type, uint32_t *val) +{ + uint32_t read_val = 0; + switch (reg_type) { + case AM_MMU_CP15_TTBCR: + TTBCR_R(read_val); + case AM_MMU_CP15_TTBR0: + TTBR0_R(read_val); + default: + break; + } + + *val = read_val; +} + +/** + * @description: write or read CP15 register to set mmu + * @param ops_type - CP15 write or read + * @param reg_type - CP15 register type + * @param val - ops val pointer + * @return + */ +static void MmuRegOps(uint8_t ops_type, uint8_t reg_type, uint32_t *val) +{ + switch (ops_type) { + case AM_MMU_CP15_WRITE: + MmuCp15Write(reg_type, val); + case AM_MMU_CP15_READ: + MmuCp15Read(reg_type, val); + default: + break; + } +} + +/** + * @description: Init abstraction_mmu function + * @param mmu - abstraction mmu pointer + * @param ttb_base - ttb base pointer + * @return success : 0 error : -1 + */ +static int _AbstractionMmuInit(AbstractionMmu *mmu, uint32_t *ttb_base) +{ + mmu_init(); + + return 0; +} + +/** + * @description: map L1 or L2 page table section + * @param mmu - abstraction mmu pointer + * @param section_size - section size + * @return success : 0 error : -1 + */ +static int _AbstractionMmuSectionMap(AbstractionMmu *mmu, uint32_t section_size) +{ + uint32_t vaddr_length = mmu->vaddr_end - mmu->vaddr_start + 1; + + mmu_map_l1_range(mmu->paddr_start, mmu->vaddr_start, vaddr_length, + mmu->mmu_memory_type, mmu->mmu_shareability, mmu->mmu_access); + + mmu->mmu_status = 1; + + return 0; +} + +/** + * @description: unmap L1 or L2 page table section + * @param mmu - abstraction mmu pointer + * @param vaddr_start - virtual address start + * @param vaddr_size - virtual address size + * @return success : 0 error : -1 + */ +static int _AbstractionMmuSectionUnmap(AbstractionMmu *mmu, uint32_t vaddr_start, uint32_t vaddr_size) +{ + uint32_t *l1_umap_ventry = mmu->ttb_vbase + (vaddr_start >> AM_MMU_L1_SECTION_SHIFT); + uint32_t vaddr_end = vaddr_start + vaddr_size - 1; + uint32_t umap_count = (vaddr_end >> AM_MMU_L1_SECTION_SHIFT) - (vaddr_start >> AM_MMU_L1_SECTION_SHIFT) + 1; + + while (umap_count) { + AM_DMB; + *l1_umap_ventry = 0; + AM_DSB; + + umap_count--; + l1_umap_ventry += (1 << AM_MMU_L1_SECTION_SHIFT);//1MB section + } + + AM_DSB; + CLEARTLB(0);//clear TLB data and configure + AM_DSB; + AM_ISB; + mmu->mmu_status = 0; + + return 0; +} + +/** + * @description: switch ttb base by re-write ttbr register + * @param mmu - abstraction mmu pointer + * @return success : 0 error : -1 + */ +static int _AbstractionMmuTtbSwitch(AbstractionMmu *mmu) +{ + uint32_t ttbr, ttbcr; + MmuRegOps(AM_MMU_CP15_READ, AM_MMU_CP15_TTBCR, &ttbcr); + + /* Set TTBR0 with inner/outer write back write allocate and not shareable, [4:3]=01, [1]=0, [6,0]=01 */ + ttbr = ((mmu->ttb_pbase & 0xFFFFC000UL) | 0x9UL); + /* enable TTBR0 */ + ttbcr = 0; + + AM_DSB; + MmuRegOps(AM_MMU_CP15_WRITE, AM_MMU_CP15_TTBR0, &ttbr); + MmuRegOps(AM_MMU_CP15_WRITE, AM_MMU_CP15_TTBCR, &ttbcr); + + return 0; +} + +/** + * @description: get physical address transformed from virtual address + * @param mmu - abstraction mmu pointer + * @param vaddr - virtual address pointer + * @param paddr - physical address pointer + * @return success : 0 error : -1 + */ +static int _AbstracktonMmuTransform(AbstractionMmu *mmu, uint32_t *vaddr, uint32_t *paddr) +{ + uint32_t virtualAddress = *vaddr; + + if (mmu->mmu_status) { + mmu_virtual_to_physical(virtualAddress, paddr); + } + + return 0; +} + +static struct AbstractionMmuDone mmu_done = { + .AbstractionMmuInit = _AbstractionMmuInit, + .AbstractionMmuSectionMap = _AbstractionMmuSectionMap, + .AbstractionMmuSectionUnmap = _AbstractionMmuSectionUnmap, + .AbstractionMmuTtbSwitch = _AbstractionMmuTtbSwitch, + .AbstracktonMmuTransform = _AbstracktonMmuTransform, +}; + +/** + * @description: init abstraciton mmu info when system start + * @return success : 0 error : -1 + */ +int SysInitAbstractionMmu(void) +{ + abstraction_mmu.mmu_done = &mmu_done; +} diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.h b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.h new file mode 100644 index 00000000..ce3c35d0 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/abstraction_mmu.h @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: mmu.h +* @brief: the general management of system mmu +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/5/24 +* +*/ +#include +#include + +#define ARCH_ARM +#ifdef ARCH_ARM +/* ARM System Registers */ +#define AM_DSB __asm__ volatile("dsb" ::: "memory") +#define AM_DMB __asm__ volatile("dmb" ::: "memory") +#define AM_ISB __asm__ volatile("isb" ::: "memory") +#define AM_WFI __asm__ volatile("wfi" ::: "memory") +#define AM_BARRIER __asm__ volatile("":::"memory") +#define AM_WFE __asm__ volatile("wfe" ::: "memory") +#define AM_SEV __asm__ volatile("sev" ::: "memory") + +#define TTBR0_R(val) __asm__ volatile("mrc p15, 0, %0, c2, c0, 0" : "=r"(val)) +#define TTBR0_W(val) __asm__ volatile("mcr p15, 0, %0, c2, c0, 0" ::"r"(val)) + +#define TTBCR_R(val) __asm__ volatile("mrc p15, 0, %0, c2, c0, 2" : "=r"(val)) +#define TTBCR_W(val) __asm__ volatile("mcr p15, 0, %0, c2, c0, 2" ::"r"(val)) + +#define CLEARTLB(val) __asm__ volatile("mcr p15, 0, %0, c8, c7, 0" ::"r"(val)) +#endif + +#define AM_MMU_L1_PAGE_TABLE_SIZE (4 * 4096) +#define AM_MMU_L1_SECTION_SHIFT 20 + +typedef enum +{ + AM_MMU_CP15_WRITE = 0, + AM_MMU_CP15_READ, +}MmuCP15OpsType; + +typedef enum +{ + AM_MMU_CP15_TTBCR = 0, + AM_MMU_CP15_TTBR0, + AM_MMU_CP15_CLEARTLB, +}MmuCP15RegType; + +typedef enum +{ + AM_StronglyOrdered = 0, + AM_Device, + AM_OuterInner_WB_WA, + AM_OuterInner_WT, + AM_Noncacheable, +}MmuMemoryType; + +typedef enum +{ + AM_Noaccess = 0, + AM_Read_Write, + AM_Read, +}MmuAccess; + +typedef enum +{ + AM_Shareable = 1, + AM_Nonshareable = 0 +}MmuShareability; + +struct AbstractionMmuDone +{ + int (*AbstractionMmuInit)(AbstractionMmu *mmu, uint32_t *ttb_base); + int (*AbstractionMmuSectionMap)(AbstractionMmu *mmu, uint32_t section_size); + int (*AbstractionMmuSectionUnmap)(AbstractionMmu *mmu, uint32_t vaddr_start, uint32_t vaddr_size); + int (*AbstractionMmuTtbSwitch)(AbstractionMmu *mmu); + int (*AbstracktonMmuTransform)(AbstractionMmu *mmu, uint32_t *vaddr, uint32_t *paddr); +}; + +typedef struct +{ + uint32_t ttb_vbase; + uint32_t ttb_pbase; + + uint32_t vaddr_start; + uint32_t vaddr_end; + uint32_t paddr_start; + uint32_t paddr_end; + + uint32_t vpaddr_offset; + + uint32_t pte_attr; + uint32_t mmu_status; + + MmuMemoryType mmu_memory_type; + MmuAccess mmu_access; + MmuShareability mmu_shareability; + + struct AbstractionMmuDone *mmu_done; + + int lock; + int link_list; +}AbstractionMmu; \ No newline at end of file diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c index 5af33edc..4a71e6c3 100755 --- a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c +++ b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/cache.c @@ -1,4 +1,23 @@ +/* +* 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: cache.c +* @brief: the general management of system cache +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/4/27 +* +*/ void InvalidInsCache() { diff --git a/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/mmu.c b/Ubiquitous/XiZi_AIoT/hardkernel/abstraction/mmu.c deleted file mode 100755 index e69de29b..00000000 diff --git a/Ubiquitous/XiZi_AIoT/softkernel/memory/multiple-address-spaces/memory.c b/Ubiquitous/XiZi_AIoT/softkernel/memory/multiple-address-spaces/memory.c index e69de29b..eb735195 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/memory/multiple-address-spaces/memory.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/memory/multiple-address-spaces/memory.c @@ -0,0 +1,20 @@ +/* +* 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: memory.c +* @brief: the general management of system memory +* @version: 3.0 +* @author: AIIT XUOS Lab +* @date: 2023/4/27 +* +*/ \ No newline at end of file From 7077cf74c23900521f6867068b88d2aa326d69d7 Mon Sep 17 00:00:00 2001 From: Liu_Weichao Date: Thu, 17 Aug 2023 15:04:48 +0800 Subject: [PATCH 2/2] feat add RS485 using usart4 for edu_arm32 board and fix test_rs485 error --- .../Applications/app_test/test_rs485.c | 118 ++++++++++++++---- .../Framework/control/shared/control_io.c | 2 +- .../third_party_driver/usart/Kconfig | 15 +++ .../third_party_driver/usart/connect_usart.c | 91 ++++++++++++++ .../XiZi_IIoT/resources/serial/dev_serial.c | 14 ++- 5 files changed, 211 insertions(+), 29 deletions(-) diff --git a/APP_Framework/Applications/app_test/test_rs485.c b/APP_Framework/Applications/app_test/test_rs485.c index bbe6f1c4..0b562359 100644 --- a/APP_Framework/Applications/app_test/test_rs485.c +++ b/APP_Framework/Applications/app_test/test_rs485.c @@ -22,26 +22,94 @@ #include #ifdef ADD_XIZI_FEATURES -#define BSP_485_DIR_PIN 24 +//edu-arm board dir pin PG01----no.67 in XiZi_IIoT/board/edu_arm32/third_party_driver/gpio/connect_gpio.c +#define BSP_485_DIR_PIN 67 + +static int pin_fd; +static int uart_fd; +static char write_485_data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; +static char read_485_data[8] = {0}; + +/** + * @description: Set Uart 485 Input + * @return + */ +static void Set485Input(void) +{ + struct PinStat pin_stat; + pin_stat.pin = BSP_485_DIR_PIN; + pin_stat.val = GPIO_LOW; + PrivWrite(pin_fd, &pin_stat, 1); +} + +/** + * @description: Set Uart 485 Output + * @return + */ +static void Set485Output(void) +{ + struct PinStat pin_stat; + pin_stat.pin = BSP_485_DIR_PIN; + pin_stat.val = GPIO_HIGH; + PrivWrite(pin_fd, &pin_stat, 1); +} + +/** + * @description: Control Framework Serial Write + * @param write_data - write data + * @param length - length + * @return + */ +void Rs485Write(uint8_t *write_data, int length) +{ + Set485Output(); + PrivTaskDelay(20); + + PrivWrite(uart_fd, write_data, length); + + PrivTaskDelay(15); + Set485Input(); +} + +/** + * @description: Control Framework Serial Read + * @param read_data - read data + * @param length - length + * @return read data size + */ +int Rs485Read(uint8_t *read_data, int length) +{ + int data_size = 0; + int data_recv_size = 0; + + while (data_size < length) { + data_recv_size = PrivRead(uart_fd, read_data + data_size, length - data_size); + data_size += data_recv_size; + } + + //need to wait 30ms , make sure write cmd again and receive data successfully + PrivTaskDelay(30); + + return data_size; +} void Test485(void) { - int pin_fd = PrivOpen(RS485_PIN_DEV_DRIVER, O_RDWR); - if (pin_fd < 0) - { + int read_data_length = 0; + pin_fd = PrivOpen(RS485_PIN_DEV_DRIVER, O_RDWR); + if (pin_fd < 0) { printf("open pin fd error:%d\n", pin_fd); return; } - int uart_fd = PrivOpen(RS485_UART_DEV_DRIVER, O_RDWR); - if (uart_fd < 0) - { + uart_fd = PrivOpen(RS485_UART_DEV_DRIVER, O_RDWR); + if (uart_fd < 0) { printf("open pin fd error:%d\n", uart_fd); return; } printf("uart and pin fopen success\n"); - //config led pin in board + //config dir pin in board struct PinParam pin_parameter; memset(&pin_parameter, 0, sizeof(struct PinParam)); pin_parameter.cmd = GPIO_CONFIG_MODE; @@ -68,36 +136,34 @@ void Test485(void) uart_cfg.serial_bit_order = BIT_ORDER_LSB; uart_cfg.serial_invert_mode = NRZ_NORMAL; uart_cfg.serial_buffer_size = SERIAL_RB_BUFSZ; - uart_cfg.serial_timeout = 1000; + uart_cfg.serial_timeout = -1; uart_cfg.is_ext_uart = 0; ioctl_cfg.ioctl_driver_type = SERIAL_TYPE; ioctl_cfg.args = (void *)&uart_cfg; - if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg)) - { + if (0 != PrivIoctl(uart_fd, OPE_INT, &ioctl_cfg)) { printf("ioctl uart fd error %d\n", uart_fd); PrivClose(uart_fd); return; } - struct PinStat pin_dir; - pin_dir.pin = BSP_485_DIR_PIN; - while (1) - { - pin_dir.val = GPIO_HIGH; - PrivWrite(pin_fd,&pin_dir,0); - PrivWrite(uart_fd,"Hello world!\n",sizeof("Hello world!\n")); - PrivTaskDelay(100); + Rs485Write(write_485_data, sizeof(write_485_data)); - pin_dir.val = GPIO_LOW; - PrivWrite(pin_fd,&pin_dir,0); - char recv_buff[100]; - memset(recv_buff,0,sizeof(recv_buff)); - PrivRead(uart_fd,recv_buff,20); - printf("%s",recv_buff); - PrivTaskDelay(100); + while(1) { + printf("ready to read data\n"); + + read_data_length = Rs485Read(read_485_data, sizeof(read_485_data)); + printf("%s read data length %d\n", __func__, read_data_length); + for (int i = 0; i < read_data_length; i ++) { + printf("i %d read data 0x%x\n", i, read_485_data[i]); + } + Rs485Write(read_485_data, read_data_length); + memset(read_485_data, 0, sizeof(read_485_data)); + + printf("read data done\n"); } + PrivClose(pin_fd); PrivClose(uart_fd); return; diff --git a/APP_Framework/Framework/control/shared/control_io.c b/APP_Framework/Framework/control/shared/control_io.c index fbb01b7e..5d9e0006 100644 --- a/APP_Framework/Framework/control/shared/control_io.c +++ b/APP_Framework/Framework/control/shared/control_io.c @@ -180,7 +180,7 @@ int SerialRead(uint8_t *read_data, int length) int data_recv_size = 0; while (data_size < length) { - data_recv_size = PrivRead(uart_fd, read_data + data_recv_size, length); + data_recv_size = PrivRead(uart_fd, read_data + data_size, length - data_size); data_size += data_recv_size; } diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/Kconfig index 7f51f8e7..626811be 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/Kconfig @@ -13,6 +13,21 @@ menuconfig BSP_USING_UART3 default "usart3_dev3" endif +menuconfig BSP_USING_UART4 + bool "Enable USART4 for RS485" + default y + if BSP_USING_UART4 + config SERIAL_BUS_NAME_4 + string "serial bus 4 name" + default "usart4" + config SERIAL_DRV_NAME_4 + string "serial bus 4 driver name" + default "usart4_drv" + config SERIAL_4_DEVICE_NAME_0 + string "serial bus 4 device 0 name" + default "usart4_dev4" + endif + menuconfig BSP_USING_UART6 bool "Enable USART6" default n diff --git a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/connect_usart.c b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/connect_usart.c index 47a9ca68..b16c709b 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/connect_usart.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-arm32/third_party_driver/usart/connect_usart.c @@ -50,6 +50,14 @@ Modification: #define USART3_TX_PIN (GPIO_PIN_10) #endif +#if defined(BSP_USING_UART4) +#define USART4_RX_PORT (GPIO_PORT_E) +#define USART4_RX_PIN (GPIO_PIN_07) + +#define USART4_TX_PORT (GPIO_PORT_G) +#define USART4_TX_PIN (GPIO_PIN_00) +#endif + #if defined(BSP_USING_UART6) #define USART6_RX_PORT (GPIO_PORT_H) #define USART6_RX_PIN (GPIO_PIN_06) @@ -72,6 +80,12 @@ static x_err_t UartGpioInit(CM_USART_TypeDef *USARTx) GPIO_SetFunc(USART3_TX_PORT, USART3_TX_PIN, GPIO_FUNC_32); break; #endif +#ifdef BSP_USING_UART4 + case (uint32)CM_USART4: + GPIO_SetFunc(USART4_RX_PORT, USART4_RX_PIN, GPIO_FUNC_33); + GPIO_SetFunc(USART4_TX_PORT, USART4_TX_PIN, GPIO_FUNC_32); + break; +#endif #ifdef BSP_USING_UART6 case (uint32)CM_USART6: GPIO_SetFunc(USART6_RX_PORT, USART6_RX_PIN, GPIO_FUNC_37); @@ -123,6 +137,32 @@ void Uart3RxErrIrqHandler(void) } #endif +#ifdef BSP_USING_UART4 +struct SerialBus serial_bus_4; +struct SerialDriver serial_driver_4; +struct SerialHardwareDevice serial_device_4; + +void Uart4RxIrqHandler(void) +{ + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + + SerialSetIsr(&serial_device_4, SERIAL_EVENT_RX_IND); + + ENABLE_INTERRUPT(lock); +} + +void Uart4RxErrIrqHandler(void) +{ + x_base lock = 0; + lock = DISABLE_INTERRUPT(); + + UartRxErrIsr(&serial_bus_4, &serial_driver_4, &serial_device_4); + + ENABLE_INTERRUPT(lock); +} +#endif + #ifdef BSP_USING_UART6 struct SerialBus serial_bus_6; struct SerialDriver serial_driver_6; @@ -499,6 +539,57 @@ int HwUsartInit(void) } #endif +#ifdef BSP_USING_UART4 + static struct SerialCfgParam serial_cfg_4; + memset(&serial_cfg_4, 0, sizeof(struct SerialCfgParam)); + + static struct SerialDevParam serial_dev_param_4; + memset(&serial_dev_param_4, 0, sizeof(struct SerialDevParam)); + + static struct UsartHwCfg serial_hw_cfg_4; + memset(&serial_hw_cfg_4, 0, sizeof(struct UsartHwCfg)); + + serial_driver_4.drv_done = &drv_done; + serial_driver_4.configure = SerialDrvConfigure; + serial_device_4.hwdev_done = &hwdev_done; + + serial_cfg_4.data_cfg = data_cfg_init; + + //default irq configure + serial_hw_cfg_4.uart_device = CM_USART4; + serial_hw_cfg_4.usart_clock = FCG3_PERIPH_USART4; + serial_hw_cfg_4.rx_err_irq.irq_config.irq_num = BSP_UART4_RXERR_IRQ_NUM; + serial_hw_cfg_4.rx_err_irq.irq_config.irq_prio = BSP_UART4_RXERR_IRQ_PRIO; + serial_hw_cfg_4.rx_err_irq.irq_config.int_src = INT_SRC_USART4_EI; + + serial_hw_cfg_4.rx_irq.irq_config.irq_num = BSP_UART4_RX_IRQ_NUM; + serial_hw_cfg_4.rx_irq.irq_config.irq_prio = BSP_UART4_RX_IRQ_PRIO; + serial_hw_cfg_4.rx_irq.irq_config.int_src = INT_SRC_USART4_RI; + + serial_hw_cfg_4.rx_err_irq.irq_callback = Uart4RxErrIrqHandler; + serial_hw_cfg_4.rx_irq.irq_callback = Uart4RxIrqHandler; + + hc32_install_irq_handler(&serial_hw_cfg_4.rx_err_irq.irq_config, serial_hw_cfg_4.rx_err_irq.irq_callback, 0); + + serial_cfg_4.hw_cfg.private_data = (void *)&serial_hw_cfg_4; + serial_driver_4.private_data = (void *)&serial_cfg_4; + + serial_dev_param_4.serial_work_mode = SIGN_OPER_INT_RX; + serial_device_4.haldev.private_data = (void *)&serial_dev_param_4; + + ret = BoardSerialBusInit(&serial_bus_4, &serial_driver_4, SERIAL_BUS_NAME_4, SERIAL_DRV_NAME_4); + if (EOK != ret) { + KPrintf("HwUartInit uart4 error ret %u\n", ret); + return ERROR; + } + + ret = BoardSerialDevBend(&serial_device_4, (void *)&serial_cfg_4, SERIAL_BUS_NAME_4, SERIAL_4_DEVICE_NAME_0); + if (EOK != ret) { + KPrintf("HwUartInit uart4 error ret %u\n", ret); + return ERROR; + } +#endif + #ifdef BSP_USING_UART6 static struct SerialCfgParam serial_cfg_6; memset(&serial_cfg_6, 0, sizeof(struct SerialCfgParam)); diff --git a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c index 37396e6e..156db4eb 100644 --- a/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c +++ b/Ubiquitous/XiZi_IIoT/resources/serial/dev_serial.c @@ -50,6 +50,7 @@ Modification: #include #include +static int serial_isr_cnt = 0; static DoubleLinklistType serialdev_linklist; static int SerialWorkModeCheck(struct SerialDevParam *serial_dev_param) @@ -138,6 +139,9 @@ static inline int SerialDevIntRead(struct SerialHardwareDevice *serial_dev, stru if (serial_dev->serial_fifo.serial_rx->serial_recv_num == serial_dev->serial_fifo.serial_rx->serial_send_num) { if (RET_FALSE == serial_dev->serial_fifo.serial_rx->serial_rx_full) { CriticalAreaUnLock(lock); + if (0 == serial_isr_cnt) { + KSemaphoreSetValue(serial_dev->haldev.dev_sem, 0); + } break; } } @@ -151,11 +155,13 @@ static inline int SerialDevIntRead(struct SerialHardwareDevice *serial_dev, stru if (RET_TRUE == serial_dev->serial_fifo.serial_rx->serial_rx_full) { serial_dev->serial_fifo.serial_rx->serial_rx_full = RET_FALSE; } + + if (serial_isr_cnt > 0) { + serial_isr_cnt--; + } CriticalAreaUnLock(lock); - //MdelayKTask(20); - *read_data = get_char; read_data++; read_length--; @@ -713,6 +719,10 @@ void SerialSetIsr(struct SerialHardwareDevice *serial_dev, int event) if (serial_dev->haldev.dev_recv_callback) { serial_dev->haldev.dev_recv_callback((void *)serial_dev, serial_rx_length); } + + lock = CriticalAreaLock(); + serial_isr_cnt += 1; + CriticalAreaUnLock(lock); KSemaphoreAbandon(serial_dev->haldev.dev_sem); }