diff --git a/APP_Framework/Applications/app_test/test_rs485.c b/APP_Framework/Applications/app_test/test_rs485.c index bbe6f1c4d..0b562359c 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 fbb01b7ec..5d9e00060 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 7f51f8e7b..626811be0 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 47a9ca68a..b16c709bd 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 37396e6ea..156db4ebb 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); }