123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /******************************************************************************
- * 2016 ideasX (Tyler Berezowsky)
- *
- * FileName: uart.c
- *
- * Description: Two UART mode configration and interrupt handler.
- * Check your hardware connection while use this mode.
- * Future Work: Modify ISR to handle UART timeout and Errors
- *
- * Modification history:
- * 2014/3/12, v1.0 create this file.
- *******************************************************************************/
- #include "driver/uart.h"
- // UartDev is defined and initialized in rom code.
- extern UartDevice UartDev;
- static void uart0_rx_intr_handler(void *para);
- /******************************************************************************
- * FunctionName : uart_config
- * Description : Internal used function
- * UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
- * UART1 just used for debug output
- * Parameters : uart_no, use UART0 or UART1 defined ahead
- * Returns : NONE
- *******************************************************************************/
- static void ICACHE_FLASH_ATTR
- uart_config(uint8 uart_no)
- {
- if (uart_no == UART1) {
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); // setup gpio2 for UART1
- }
- else {
- ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); // attach uart0_rx_intr_handler ISR
- PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); // disable pullup on TX pin
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); // setup gpio TX pin
- /* setup hardware flow control */
- #if UART_HW_RTS
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); //SETUP HW FLOW CONTROL RTS PIN
- #endif
- #if UART_HW_CTS
- PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); //SETUP HW FLOW CONTROL CTS PIN
- #endif
- }
- uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate)); // setup baudrate
- WRITE_PERI_REG(UART_CONF0(uart_no), ((UartDev.exist_parity & UART_PARITY_EN_M) << UART_PARITY_EN_S) // setup parity
- | ((UartDev.parity & UART_PARITY_M) <<UART_PARITY_S )
- | ((UartDev.stop_bits & UART_STOP_BIT_NUM) << UART_STOP_BIT_NUM_S) // setup stop bits
- | ((UartDev.data_bits & UART_BIT_NUM) << UART_BIT_NUM_S)); // setup data bits
- //clear rx and tx fifo,not ready
- SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); // set clear RX FIFO bits
- CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST); // clear clear RX FIFO bits
- if (uart_no == UART0){
- WRITE_PERI_REG(UART_CONF1(uart_no),
- ((1 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | // set UART0 full interrupt to 1 bytes
- #if UART_HW_RTS
- ((110 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) | // set hardware flow control threshold
- UART_RX_FLOW_EN | // set enable hardware flow control flag
- #endif
- (0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S | // setup timeout interrupt
- UART_RX_TOUT_EN| // setup enable timeout flag
- ((0x10 & UART_TXFIFO_EMPTY_THRHD)<<UART_TXFIFO_EMPTY_THRHD_S)); // setup UART0 empty interrupt threshold to 16 bytes
- #if UART_HW_CTS
- SET_PERI_REG_MASK( UART_CONF0(uart_no),UART_TX_FLOW_EN); //add this sentense to add a tx flow control via MTCK( CTS )
- #endif
- //SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UARben affleck in batman suitT_RXFIFO_TOUT_INT_ENA |UART_FRM_ERR_INT_ENA); // enable interrupts for timeout and byte error
- }
- else{
- WRITE_PERI_REG(UART_CONF1(uart_no),((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));//TrigLvl default val == 1
- }
- WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); //clear all interrupts
- SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA); // enable full RX FIFO interrupt
- }
- /******************************************************************************
- * FunctionName : uart1_tx_one_char
- * Description : Internal used function
- * Use uart1 interface to transfer one char
- * Parameters : uint8 TxChar - character to tx
- * Returns : OK
- *******************************************************************************/
- static STATUS ICACHE_FLASH_ATTR
- uart1_tx_one_char(uint8 TxChar)
- {
- while (true) // dump FIFO until empty
- {
- uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(UART1)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
- if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
- break;
- }
- }
- WRITE_PERI_REG(UART_FIFO(UART1) , TxChar); // add character to FIFO
- return OK;
- }
- /******************************************************************************
- * FunctionName : uart1_write_char
- * Description : Internal used function
- * Do some special deal while tx char is '\r' or '\n'
- * Parameters : char c - character to tx
- * Returns : NONE
- *******************************************************************************/
- static void ICACHE_FLASH_ATTR
- uart1_write_char(char c)
- {
- if (c == '\n') {
- uart1_tx_one_char('\r');
- uart1_tx_one_char('\n');
- } else if (c == '\r') {
- } else {
- uart1_tx_one_char(c);
- }
- }
- /******************************************************************************
- * FunctionName : uart0_rx_intr_handler
- * Description : Internal used function
- * UART0 interrupt handler, add self handle code inside
- * Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg
- * Returns : NONE
- *******************************************************************************/
- extern void process_command(char* str);
- static 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
- */
- RcvMsgBuff *pRxBuff = (RcvMsgBuff *)para;
- uint8 RcvChar;
- // if uart0 fifo isn't full return
- if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(UART0)) & UART_RXFIFO_FULL_INT_ST)){
- WRITE_PERI_REG(UART_INT_CLR(UART0), UART_RXFIFO_FULL_INT_CLR); // clear full FIFO flag
- while (READ_PERI_REG(UART_STATUS(UART0)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
- RcvChar = READ_PERI_REG(UART_FIFO(UART0)) & 0xFF;
- /* you can add your handle code below.*/
- uart_tx_one_char(RcvChar); // echo recieved character
- // NOTE: Lets modify the \r\n sequence to something more american.
- // NOTE: Add hook for backspace character...I need to learn the ASCII code
- // NOTE: Backspace character should also remove the last two stored characters
- // in the buffer. This might be possible by moving the pWritePos back 2 characters?
- // if "\r\n" recieved dump UART buffer into str
- if (RcvChar == '\r') continue;
- if (RcvChar == '\n') {
- int len;
- char *str;
- len = pRxBuff->pWritePos - pRxBuff->pReadPos;
- if (len == 0) continue;
- if (len < 0) len += RX_BUFF_SIZE;
- str = (char*)os_zalloc(len+1);
- if (str) {
- uint8 loop;
- for (loop = 0; loop < len; loop++) str[loop] = uart0_rx_one_char();
- str[len] = '\0';
- process_command(str);
- os_free(str);
- }
- }
- // otherwise add character to buffer
- else {
- *(pRxBuff->pWritePos) = RcvChar;
- pRxBuff->pWritePos++;
- }
- // if we hit the end of the buffer, loop back to the beginning
- if (pRxBuff->pWritePos == (pRxBuff->pRcvMsgBuff + RX_BUFF_SIZE)) {
- // overflow ...we may need more error handle here.
- pRxBuff->pWritePos = pRxBuff->pRcvMsgBuff ;
- }
- }
- }
- }
- ICACHE_FLASH_ATTR int uart0_rx_one_char() {
- if(UartDev.rcv_buff.pReadPos == UartDev.rcv_buff.pWritePos) return -1;
- int ret = *UartDev.rcv_buff.pReadPos;
- UartDev.rcv_buff.pReadPos++;
- if(UartDev.rcv_buff.pReadPos == (UartDev.rcv_buff.pRcvMsgBuff + RX_BUFF_SIZE)) {
- UartDev.rcv_buff.pReadPos = UartDev.rcv_buff.pRcvMsgBuff;
- }
- return ret;
- }
- /******************************************************************************
- * FunctionName : uart0_tx_buffer
- * Description : use uart0 to transfer buffer
- * Parameters : uint8 *buf - point to send buffer
- * uint16 len - buffer len
- * Returns :
- *******************************************************************************/
- // void ICACHE_FLASH_ATTR uart0_tx_buffer(uint8 *buf, uint16 len)
- // {
- // uint16 i;
- //
- // for (i = 0; i < len; i++) {
- // uart_tx_one_char(buf[i]);
- // }
- // }
- void ICACHE_FLASH_ATTR uart0_send(const char *str) {
- uint8 i = 0;
- while (str[i]) {
- uart_tx_one_char(str[i]);
- i++;
- }
- }
- /******************************************************************************
- * FunctionName : uart_init
- * Description : user interface for init uart
- * Parameters : UartBautRate uart0_br - uart0 bautrate
- * UartBautRate uart1_br - uart1 bautrate
- * Returns : NONE
- *******************************************************************************/
- void ICACHE_FLASH_ATTR
- uart_init(UartBautRate uart0_br, UartBautRate uart1_br, bool enable_uart1) {
- // rom use 74880 baut_rate, here reinitialize
- UartDev.baut_rate = uart0_br;
- uart_config(UART0);
- if (enable_uart1) {
- UartDev.baut_rate = uart1_br;
- uart_config(UART1);
- }
- ETS_UART_INTR_ENABLE();
- }
|