From 1b837b881ddcb83e17e7a4a5dc3ea06c16aa76cf Mon Sep 17 00:00:00 2001 From: Espressif Systems Date: Mon, 5 Jan 2015 14:22:44 +0800 Subject: [PATCH] update uart driver --- examples/driver_lib/driver/uart.c | 266 ++++++++++++++++++++++++++++- examples/driver_lib/include/uart.h | 176 ++++++++++++------- 2 files changed, 369 insertions(+), 73 deletions(-) diff --git a/examples/driver_lib/driver/uart.c b/examples/driver_lib/driver/uart.c index 4c4872ca..def2be29 100644 --- a/examples/driver_lib/driver/uart.c +++ b/examples/driver_lib/driver/uart.c @@ -21,7 +21,6 @@ typedef struct _os_event_ { uint32 param; } os_event_t; - xTaskHandle xUartTaskHandle; xQueueHandle xQueueUart; @@ -52,7 +51,20 @@ uart1_write_char(char c) } } -LOCAL void uart_rx_intr_handler_ssc(void) +LOCAL void +uart0_write_char(char c) +{ + if (c == '\n') { + uart_tx_one_char(UART0, '\r'); + uart_tx_one_char(UART0, '\n'); + } else if (c == '\r') { + } else { + uart_tx_one_char(UART0, c); + } +} + +LOCAL void +uart_rx_intr_handler_ssc(void) { /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents * uart1 and uart0 respectively @@ -78,6 +90,7 @@ LOCAL void uart_rx_intr_handler_ssc(void) portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } +#if 0 LOCAL void ICACHE_FLASH_ATTR uart_config(uint8 uart_no, UartDevice *uart) { @@ -115,6 +128,7 @@ uart_config(uint8 uart_no, UartDevice *uart) //enable rx_interrupt SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); } +#endif LOCAL void ICACHE_FLASH_ATTR uart_task(void *pvParameters) @@ -137,20 +151,22 @@ uart_task(void *pvParameters) vTaskDelete(NULL); } +#if 0 void ICACHE_FLASH_ATTR uart_init(void) { while (READ_PERI_REG(UART_STATUS(0)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); + while (READ_PERI_REG(UART_STATUS(1)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); - UartDevice uart; + UART_ConfigTypeDef uart; uart.baut_rate = BIT_RATE_74880; - uart.data_bits = EIGHT_BITS; - uart.flow_ctrl = NONE_CTRL; - uart.exist_parity = STICK_PARITY_DIS; - uart.parity = NONE_BITS; - uart.stop_bits = ONE_STOP_BIT; + uart.data_bits = UART_WordLength_8b; + uart.flow_ctrl = USART_HardwareFlowControl_None; + // uart.exist_parity = PARITY_DIS; + uart.parity = USART_Parity_None; + uart.stop_bits = USART_StopBits_1; uart_config(UART0, &uart); uart_config(UART1, &uart); @@ -163,4 +179,238 @@ uart_init(void) xTaskCreate(uart_task, (uint8 const *)"uTask", 512, NULL, tskIDLE_PRIORITY + 2, &xUartTaskHandle); } +#endif +//================================================================= + +void ICACHE_FLASH_ATTR +UART_SetWordLength(UART_Port uart_no, UART_WordLength len) +{ + SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_BIT_NUM, len, UART_BIT_NUM_S); +} + +void ICACHE_FLASH_ATTR +UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num) +{ + SET_PERI_REG_BITS(UART_CONF0(uart_no), UART_STOP_BIT_NUM, bit_num, UART_STOP_BIT_NUM_S); +} + +void ICACHE_FLASH_ATTR +UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) +{ + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_LINE_INV_MASK); + SET_PERI_REG_MASK(UART_CONF0(uart_no), inverse_mask); +} + +void ICACHE_FLASH_ATTR +UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) +{ + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_PARITY | UART_PARITY_EN); + + if (Parity_mode == USART_Parity_None) { + } else { + SET_PERI_REG_MASK(UART_CONF0(uart_no), Parity_mode | UART_PARITY_EN); + } +} + +void ICACHE_FLASH_ATTR +UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate) +{ + uart_div_modify(uart_no, UART_CLK_FREQ / baud_rate); +} + +//only when USART_HardwareFlowControl_RTS is set , will the rx_thresh value be set. +void ICACHE_FLASH_ATTR +UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh) +{ + if (flow_ctrl & USART_HardwareFlowControl_RTS) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); + SET_PERI_REG_BITS(UART_CONF1(uart_no), UART_RX_FLOW_THRHD, rx_thresh, UART_RX_FLOW_THRHD_S); + SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); + } else { + CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); + } + + if (flow_ctrl & USART_HardwareFlowControl_CTS) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_UART0_CTS); + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); + } else { + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_TX_FLOW_EN); + } +} + +void ICACHE_FLASH_ATTR +UART_WaitTxFifoEmpty(UART_Port uart_no) //do not use if tx flow control enabled +{ + while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S)); +} + +void ICACHE_FLASH_ATTR +UART_ResetFifo(UART_Port uart_no) +{ + SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); + CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); +} + +void ICACHE_FLASH_ATTR +UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask) +{ + WRITE_PERI_REG(UART_INT_CLR(uart_no), clr_mask); +} + +void ICACHE_FLASH_ATTR +UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask) +{ + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), ena_mask); +} + +void ICACHE_FLASH_ATTR +UART_intr_handler_register(void *fn) +{ + _xt_isr_attach(ETS_UART_INUM, fn); +} + +void ICACHE_FLASH_ATTR +UART_SetPrintPort(UART_Port uart_no) +{ + if (uart_no == 1) { + os_install_putc1(uart1_write_char); + } else { + os_install_putc1(uart0_write_char); + } +} + +void ICACHE_FLASH_ATTR +UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig) +{ + if (uart_no == UART1) { + PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); + } else { + PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); + PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); + } + + UART_SetFlowCtrl(uart_no, pUARTConfig->flow_ctrl, pUARTConfig->UART_RxFlowThresh); + UART_SetBaudrate(uart_no, pUARTConfig->baud_rate); + + WRITE_PERI_REG(UART_CONF0(uart_no), + ((pUARTConfig->parity == USART_Parity_None) ? 0x0 : (UART_PARITY_EN | pUARTConfig->parity)) + | (pUARTConfig->stop_bits << UART_STOP_BIT_NUM_S) + | (pUARTConfig->data_bits << UART_BIT_NUM_S) + | ((pUARTConfig->flow_ctrl & USART_HardwareFlowControl_CTS) ? UART_TX_FLOW_EN : 0x0) + | pUARTConfig->UART_InverseMask); + + UART_ResetFifo(uart_no); +} + +void ICACHE_FLASH_ATTR +UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf) +{ + + uint32 reg_val = 0; + UART_ClearIntrStatus(uart_no, UART_INTR_MASK); + reg_val = READ_PERI_REG(UART_CONF1(uart_no)) & ~((UART_RX_FLOW_THRHD << UART_RX_FLOW_THRHD_S) | UART_RX_FLOW_EN) ; + + reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_TOUT_INT_ENA) ? + ((((pUARTIntrConf->UART_RX_TimeOutIntrThresh)&UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S) | UART_RX_TOUT_EN) : 0); + + reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_RXFIFO_FULL_INT_ENA) ? + (((pUARTIntrConf->UART_RX_FifoFullIntrThresh)&UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) : 0); + + reg_val |= ((pUARTIntrConf->UART_IntrEnMask & UART_TXFIFO_EMPTY_INT_ENA) ? + (((pUARTIntrConf->UART_TX_FifoEmptyIntrThresh)&UART_TXFIFO_EMPTY_THRHD) << UART_TXFIFO_EMPTY_THRHD_S) : 0); + + WRITE_PERI_REG(UART_CONF1(uart_no), reg_val); + CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_INTR_MASK); + SET_PERI_REG_MASK(UART_INT_ENA(uart_no), pUARTIntrConf->UART_IntrEnMask); +} + +LOCAL void +uart0_rx_intr_handler(void *para) +{ + /* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents + * uart1 and uart0 respectively + */ + uint8 RcvChar; + uint8 uart_no = UART0;//UartDev.buff_uart_no; + uint8 fifo_len = 0; + uint8 buf_idx = 0; + uint8 fifo_tmp[128] = {0}; + + uint32 uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; + + while (uart_intr_status != 0x0) { + if (UART_FRM_ERR_INT_ST == (uart_intr_status & UART_FRM_ERR_INT_ST)) { + //printf("FRM_ERR\r\n"); + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); + } else if (UART_RXFIFO_FULL_INT_ST == (uart_intr_status & UART_RXFIFO_FULL_INT_ST)) { + printf("full\r\n"); + fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; + buf_idx = 0; + + while (buf_idx < fifo_len) { + uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF); + buf_idx++; + } + + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); + } else if (UART_RXFIFO_TOUT_INT_ST == (uart_intr_status & UART_RXFIFO_TOUT_INT_ST)) { + printf("tout\r\n"); + fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; + buf_idx = 0; + + while (buf_idx < fifo_len) { + uart_tx_one_char(UART0, READ_PERI_REG(UART_FIFO(UART0)) & 0xFF); + buf_idx++; + } + + WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_TOUT_INT_CLR); + } else if (UART_TXFIFO_EMPTY_INT_ST == (uart_intr_status & UART_TXFIFO_EMPTY_INT_ST)) { + printf("empty\n\r"); + WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_TXFIFO_EMPTY_INT_CLR); + CLEAR_PERI_REG_MASK(UART_INT_ENA(UART0), UART_TXFIFO_EMPTY_INT_ENA); + } else { + //skip + } + + uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; + } +} + +void ICACHE_FLASH_ATTR +uart_init_new(void) +{ + UART_WaitTxFifoEmpty(UART0); + UART_WaitTxFifoEmpty(UART1); + + UART_ConfigTypeDef uart_config; + uart_config.baud_rate = BIT_RATE_74880; + uart_config.data_bits = UART_WordLength_8b; + uart_config.parity = USART_Parity_None; + uart_config.stop_bits = USART_StopBits_1; + uart_config.flow_ctrl = USART_HardwareFlowControl_None; + uart_config.UART_RxFlowThresh = 120; + uart_config.UART_InverseMask = UART_None_Inverse; + UART_ParamConfig(UART0, &uart_config); + + UART_IntrConfTypeDef uart_intr; + uart_intr.UART_IntrEnMask = UART_RXFIFO_TOUT_INT_ENA | UART_FRM_ERR_INT_ENA | UART_RXFIFO_FULL_INT_ENA | UART_TXFIFO_EMPTY_INT_ENA; + uart_intr.UART_RX_FifoFullIntrThresh = 10; + uart_intr.UART_RX_TimeOutIntrThresh = 2; + uart_intr.UART_TX_FifoEmptyIntrThresh = 20; + UART_IntrConfig(UART0, &uart_intr); + + UART_SetPrintPort(UART0); + UART_intr_handler_register(uart0_rx_intr_handler); + ETS_UART_INTR_ENABLE(); + + /* + UART_SetWordLength(UART0,UART_WordLength_8b); + UART_SetStopBits(UART0,USART_StopBits_1); + UART_SetParity(UART0,USART_Parity_None); + UART_SetBaudrate(UART0,74880); + UART_SetFlowCtrl(UART0,USART_HardwareFlowControl_None,0); + */ + +} diff --git a/examples/driver_lib/include/uart.h b/examples/driver_lib/include/uart.h index ca792189..d6733d43 100644 --- a/examples/driver_lib/include/uart.h +++ b/examples/driver_lib/include/uart.h @@ -1,65 +1,111 @@ -/* - * Copyright (C) 2010 -2011 Espressif System - * - */ - -#ifndef __UART_H__ -#define __UART_H__ - -#define UART0 0 -#define UART1 1 - -typedef enum { - FIVE_BITS = 0x0, - SIX_BITS = 0x1, - SEVEN_BITS = 0x2, - EIGHT_BITS = 0x3 -} UartBitsNum4Char; - -typedef enum { - ONE_STOP_BIT = 0, - ONE_HALF_STOP_BIT = BIT(2), - TWO_STOP_BIT = BIT(2) -} UartStopBitsNum; - -typedef enum { - NONE_BITS = 0, - ODD_BITS = 0, - EVEN_BITS = BIT(4) -} UartParityMode; - -typedef enum { - STICK_PARITY_DIS = 0, - STICK_PARITY_EN = BIT(3) | BIT(5) -} UartExistParity; - -typedef enum { - BIT_RATE_9600 = 9600, - BIT_RATE_19200 = 19200, - BIT_RATE_38400 = 38400, - BIT_RATE_57600 = 57600, - BIT_RATE_74880 = 74880, - BIT_RATE_115200 = 115200, - BIT_RATE_230400 = 230400, - BIT_RATE_460800 = 460800, - BIT_RATE_921600 = 921600 -} UartBautRate; - -typedef enum { - NONE_CTRL, - HARDWARE_CTRL, - XON_XOFF_CTRL -} UartFlowCtrl; - -typedef struct { - UartBautRate baut_rate; - UartBitsNum4Char data_bits; - UartExistParity exist_parity; - UartParityMode parity; // chip size in byte - UartStopBitsNum stop_bits; - UartFlowCtrl flow_ctrl; -} UartDevice; - -void uart_init(); - -#endif +/* + * Copyright (C) 2010 -2011 Espressif System + * + */ + +#ifndef __UART_H__ +#define __UART_H__ + +#define ETS_UART_INTR_ENABLE() _xt_isr_unmask(1 << ETS_UART_INUM) +#define ETS_UART_INTR_DISABLE() _xt_isr_mask(1 << ETS_UART_INUM) +#define UART_INTR_MASK 0x1ff +#define UART_LINE_INV_MASK (0x3f<<19) + +typedef enum { + UART_WordLength_5b = 0x0, + UART_WordLength_6b = 0x1, + UART_WordLength_7b = 0x2, + UART_WordLength_8b = 0x3 +} UART_WordLength; + +typedef enum { + USART_StopBits_1 = 0x1, + USART_StopBits_1_5 = 0x2, + USART_StopBits_2 = 0x3, +} UART_StopBits; + +typedef enum { + UART0 = 0x0, + UART1 = 0x1, +} UART_Port; + +typedef enum { + USART_Parity_None = 0x2, + USART_Parity_Even = 0x0, + USART_Parity_Odd = 0x1 +} UART_ParityMode; + +typedef enum { + PARITY_DIS = 0x0, + PARITY_EN = 0x2 +} UartExistParity; + +typedef enum { + BIT_RATE_300 = 300, + BIT_RATE_600 = 600, + BIT_RATE_1200 = 1200, + BIT_RATE_2400 = 2400, + BIT_RATE_4800 = 4800, + BIT_RATE_9600 = 9600, + BIT_RATE_19200 = 19200, + BIT_RATE_38400 = 38400, + BIT_RATE_57600 = 57600, + BIT_RATE_74880 = 74880, + BIT_RATE_115200 = 115200, + BIT_RATE_230400 = 230400, + BIT_RATE_460800 = 460800, + BIT_RATE_921600 = 921600, + BIT_RATE_1843200 = 1843200, + BIT_RATE_3686400 = 3686400, +} UART_BautRate; //you can add any rate you need in this range + +typedef enum { + USART_HardwareFlowControl_None = 0x0, + USART_HardwareFlowControl_RTS = 0x1, + USART_HardwareFlowControl_CTS = 0x2, + USART_HardwareFlowControl_CTS_RTS = 0x3 +} UART_HwFlowCtrl; + +typedef enum { + UART_None_Inverse = 0x0, + UART_Rxd_Inverse = UART_RXD_INV, + UART_CTS_Inverse = UART_CTS_INV, + UART_Txd_Inverse = UART_TXD_INV, + UART_RTS_Inverse = UART_RTS_INV, +} UART_LineLevelInverse; + +typedef struct { + UART_BautRate baud_rate; + UART_WordLength data_bits; + UART_ParityMode parity; // chip size in byte + UART_StopBits stop_bits; + UART_HwFlowCtrl flow_ctrl; + uint8 UART_RxFlowThresh ; + uint32 UART_InverseMask; +} UART_ConfigTypeDef; + +typedef struct { + uint32 UART_IntrEnMask; + uint8 UART_RX_TimeOutIntrThresh; + uint8 UART_TX_FifoEmptyIntrThresh; + uint8 UART_RX_FifoFullIntrThresh; +} UART_IntrConfTypeDef; + +//======================================= +void UART_WaitTxFifoEmpty(UART_Port uart_no); //do not use if tx flow control enabled +void UART_ResetFifo(UART_Port uart_no); +void UART_ClearIntrStatus(UART_Port uart_no, uint32 clr_mask); +void UART_SetIntrEna(UART_Port uart_no, uint32 ena_mask); +void UART_intr_handler_register(void *fn); +void UART_SetPrintPort(UART_Port uart_no); +void UART_ParamConfig(UART_Port uart_no, UART_ConfigTypeDef *pUARTConfig); +void UART_IntrConfig(UART_Port uart_no, UART_IntrConfTypeDef *pUARTIntrConf); +void UART_SetWordLength(UART_Port uart_no, UART_WordLength len); +void UART_SetStopBits(UART_Port uart_no, UART_StopBits bit_num); +void UART_SetParity(UART_Port uart_no, UART_ParityMode Parity_mode) ; +void UART_SetBaudrate(UART_Port uart_no, uint32 baud_rate); +void UART_SetFlowCtrl(UART_Port uart_no, UART_HwFlowCtrl flow_ctrl, uint8 rx_thresh); +void UART_SetLineInverse(UART_Port uart_no, UART_LineLevelInverse inverse_mask) ; +void uart_init_new(void); + +#endif