/* * Copyright (C) 2014 -2019 Espressif System * */ #include "esp_common.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include "uart.h" #include "cfg.h" #include "log.h" #include "freertos/timers.h" static xSemaphoreHandle uart_sema = NULL; static ne_uart_recv_t uart_recv; LOCAL void uart0_rx_intr_handler(void *para); LOCAL STATUS uart_tx_one_char(uint8 uart, uint8 TxChar) { while (true) { uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S); if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) { break; } } WRITE_PERI_REG(UART_FIFO(uart) , TxChar); return OK; } LOCAL void uart1_write_char(char c) { if (c == '\n') { uart_tx_one_char(UART1, '\r'); uart_tx_one_char(UART1, '\n'); } else if (c == '\r') { } else { uart_tx_one_char(UART1, c); } } 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); } } void ICACHE_FLASH_ATTR uart_tx_str(uint8 uart,uint8* str) { if(str == NULL) { return; } while(*str != '\0') { uart_tx_one_char(uart,*str); str++; } } void ICACHE_FLASH_ATTR uart_tx_buf(uint8 uart,uint8* buf,int32 len) { int32 loop = 0; if((buf == NULL) || (len <= 0)) { return; } for(loop = 0;loop < len;loop++) { uart_tx_one_char(uart,buf[loop]); } } 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)); // ���ü��� uint32 value = READ_PERI_REG(UART_CLKDIV(uart_no)); value = UART_CLK_FREQ/value; value = (10*1000000)/value; os_delay_us(value); } 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,NULL); } 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 { _xt_isr_attach(ETS_UART_INUM, uart0_rx_intr_handler,NULL); PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD); PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); 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 IRAM_ATTR uart0_rx_intr_handler(void *para) { uint8 RcvChar; uint8 uart_no = UART0; uint8 fifo_len = 0; uint8 buf_idx = 0; portBASE_TYPE xHigherPriorityTaskWoken; uint32 uart_intr_status = READ_PERI_REG(UART_INT_ST(uart_no)) ; if (UART_FRM_ERR_INT_ST == (uart_intr_status & UART_FRM_ERR_INT_ST)) { WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR); } else if ((UART_RXFIFO_TOUT_INT_ST == (uart_intr_status & UART_RXFIFO_TOUT_INT_ST))|| (UART_RXFIFO_FULL_INT_ST == (uart_intr_status & UART_RXFIFO_FULL_INT_ST))) { fifo_len = (READ_PERI_REG(UART_STATUS(UART0)) >> UART_RXFIFO_CNT_S)&UART_RXFIFO_CNT; buf_idx = 0; // start WRITE_PERI_REG(0x60000914,0x73); for(buf_idx = 0;(buf_idx < fifo_len) && (uart_recv.recv_len < UART_BUF_SIZE);buf_idx++) { uart_recv.uart_buf[uart_recv.recv_len++] = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; } for ( ;buf_idx < fifo_len; buf_idx++) { RcvChar = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF; } WRITE_PERI_REG(0x60000914,0x73); WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR | UART_RXFIFO_TOUT_INT_CLR); } else { WRITE_PERI_REG(UART_INT_CLR(uart_no), uart_intr_status | UART_CTS_CHG_INT_CLR); } } ne_uart_recv_t *ne_get_uart_recv_info(void) { return &uart_recv; } void ne_adjust_recv_info(uint32 pos) { ETS_UART_INTR_DISABLE(); memcpy(uart_recv.uart_buf, uart_recv.uart_buf + pos, uart_recv.recv_len - pos); uart_recv.recv_len -= pos; ETS_UART_INTR_ENABLE(); }