/****************************************************************************** * 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); //PIN_PULLDWN_DIS(PERIPHS_IO_MUX_GPIO2_U); PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); } else { /* rcv_buff size is 0x100 */ ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, &(UartDev.rcv_buff)); PIN_PULLUP_DIS (PERIPHS_IO_MUX_U0TXD_U); //PIN_PULLDWN_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); PIN_PULLUP_DIS (PERIPHS_IO_MUX_U0RXD_U); //PIN_PULLDWN_DIS(PERIPHS_IO_MUX_U0RXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, 0); // FUNC_U0RXD==0 } uart_div_modify(uart_no, UART_CLK_FREQ / UartDev.baut_rate); if (uart_no == UART1) //UART 1 always 8 N 1 WRITE_PERI_REG(UART_CONF0(uart_no), CALC_UARTMODE(EIGHT_BITS, NONE_BITS, ONE_STOP_BIT)); else WRITE_PERI_REG(UART_CONF0(uart_no), CALC_UARTMODE(UartDev.data_bits, UartDev.parity, UartDev.stop_bits)); //clear rx and tx fifo,not ready 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); if (uart_no == UART0) { // Configure RX interrupt conditions as follows: trigger rx-full when there are 80 characters // in the buffer, trigger rx-timeout when the fifo is non-empty and nothing further has been // received for 4 character periods. // Set the hardware flow-control to trigger when the FIFO holds 100 characters, although // we don't really expect the signals to actually be wired up to anything. It doesn't hurt // to set the threshold here... // We do not enable framing error interrupts 'cause they tend to cause an interrupt avalanche // and instead just poll for them when we get a std RX interrupt. WRITE_PERI_REG(UART_CONF1(uart_no), ((80 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) | ((100 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) | UART_RX_FLOW_EN | (4 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S | UART_RX_TOUT_EN); SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA); } else { WRITE_PERI_REG(UART_CONF1(uart_no), ((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S)); } //clear all interrupt WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff); }
IRAM bool adj_rx_fifo_full_thresh(struct mgos_uart_state *us) { int uart_no = us->uart_no; uint8_t thresh = us->cfg.dev.rx_fifo_full_thresh; uint8_t rx_fifo_len = esp_uart_rx_fifo_len(uart_no); if (rx_fifo_len >= thresh && us->cfg.rx_fc_type == MGOS_UART_FC_SW) { thresh = us->cfg.dev.rx_fifo_fc_thresh; } if (get_rx_fifo_full_thresh(uart_no) != thresh) { uint32_t conf1 = READ_PERI_REG(UART_CONF1(uart_no)); conf1 = (conf1 & ~0x7f) | thresh; WRITE_PERI_REG(UART_CONF1(uart_no), conf1); } return (rx_fifo_len < thresh); }
void miot_uart_dev_set_rx_enabled(struct miot_uart_state *us, bool enabled) { int uart_no = us->uart_no; if (enabled) { if (us->cfg->rx_fc_ena) { SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); } SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RX_INTS); } else { if (us->cfg->rx_fc_ena) { /* With UART_SW_RTS = 0 in CONF0 this throttles RX (sets RTS = 1). */ CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); } CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RX_INTS); } }
void mgos_uart_hal_set_rx_enabled(struct mgos_uart_state *us, bool enabled) { int uart_no = us->uart_no; if (enabled) { if (us->cfg.rx_fc_type == MGOS_UART_FC_HW) { SET_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); } SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RX_INTS); } else { if (us->cfg.rx_fc_type == MGOS_UART_FC_HW) { /* With UART_SW_RTS = 0 in CONF0 this throttles RX (sets RTS = 1). */ CLEAR_PERI_REG_MASK(UART_CONF1(uart_no), UART_RX_FLOW_EN); } CLEAR_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RX_INTS); } }
bool miot_uart_dev_init(struct miot_uart_state *us) { struct miot_uart_config *cfg = us->cfg; if (!esp_uart_validate_config(cfg)) return false; ETS_INTR_DISABLE(ETS_UART_INUM); uart_div_modify(us->uart_no, UART_CLK_FREQ / cfg->baud_rate); if (us->uart_no == 0) { PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); if (cfg->swap_rxcts_txrts) { SET_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART0_PIN_SWAP); } else { CLEAR_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART0_PIN_SWAP); } } else { PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); if (cfg->swap_rxcts_txrts) { SET_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART1_PIN_SWAP); } else { CLEAR_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART1_PIN_SWAP); } } unsigned int conf0 = 0b011100; /* 8-N-1 */ if (cfg->tx_fc_ena) { conf0 |= UART_TX_FLOW_EN; PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); } WRITE_PERI_REG(UART_CONF0(us->uart_no), conf0); unsigned int conf1 = cfg->rx_fifo_full_thresh; conf1 |= (cfg->tx_fifo_empty_thresh << 8); if (cfg->rx_fifo_alarm >= 0) { conf1 |= UART_RX_TOUT_EN | ((cfg->rx_fifo_alarm & 0x7f) << 24); } if (cfg->rx_fc_ena && cfg->rx_fifo_fc_thresh > 0) { /* UART_RX_FLOW_EN will be set in uart_start. */ conf1 |= ((cfg->rx_fifo_fc_thresh & 0x7f) << 16); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); } WRITE_PERI_REG(UART_CONF1(us->uart_no), conf1); s_us[us->uart_no] = us; /* Start with TX and RX ints disabled. */ WRITE_PERI_REG(UART_INT_ENA(us->uart_no), UART_INFO_INTS); ETS_UART_INTR_ATTACH(esp_uart_isr, NULL); ETS_INTR_ENABLE(ETS_UART_INUM); return true; }
//only when USART_HardwareFlowControl_RTS is set , will the rx_thresh value be set. void 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 esp_uart_set_rx_enabled(int uart_no, int enabled) { struct esp_uart_state *us = s_us[uart_no]; if (us == NULL) return; struct esp_uart_config *cfg = us->cfg; if (enabled) { if (cfg->rx_fc_ena) { SET_PERI_REG_MASK(UART_CONF1(cfg->uart_no), UART_RX_FLOW_EN); } SET_PERI_REG_MASK(UART_INT_ENA(cfg->uart_no), UART_RX_INTS); us->rx_enabled = 1; } else { if (cfg->rx_fc_ena) { /* With UART_SW_RTS = 0 in CONF0 this throttles RX (sets RTS = 1). */ CLEAR_PERI_REG_MASK(UART_CONF1(cfg->uart_no), UART_RX_FLOW_EN); } CLEAR_PERI_REG_MASK(UART_INT_ENA(cfg->uart_no), UART_RX_INTS); us->rx_enabled = 0; } }
void 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); }
void HardwareSerial::begin(const uint32_t baud/* = 9600*/) { //TODO: Move to params! UartDev.baut_rate = (UartBautRate)baud; UartDev.parity = NONE_BITS; UartDev.exist_parity = STICK_PARITY_DIS; UartDev.stop_bits = ONE_STOP_BIT; UartDev.data_bits = EIGHT_BITS; ETS_UART_INTR_ATTACH((void*)uart0_rx_intr_handler, &(UartDev.rcv_buff)); PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); uart_div_modify(uart, UART_CLK_FREQ / (UartDev.baut_rate)); WRITE_PERI_REG(UART_CONF0(uart), UartDev.exist_parity | UartDev.parity | (UartDev.stop_bits << UART_STOP_BIT_NUM_S) | (UartDev.data_bits << UART_BIT_NUM_S)); //clear rx and tx fifo,not ready SET_PERI_REG_MASK(UART_CONF0(uart), UART_RXFIFO_RST | UART_TXFIFO_RST); CLEAR_PERI_REG_MASK(UART_CONF0(uart), UART_RXFIFO_RST | UART_TXFIFO_RST); //set rx fifo trigger WRITE_PERI_REG(UART_CONF1(uart), (UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S); //clear all interrupt WRITE_PERI_REG(UART_INT_CLR(uart), 0xffff); //enable rx_interrupt SET_PERI_REG_MASK(UART_INT_ENA(uart), UART_RXFIFO_FULL_INT_ENA); ETS_UART_INTR_ENABLE(); delay(10); Serial.println("\r\n"); // after SPAM :) }
int esp_uart_init(struct esp_uart_config *cfg) { if (cfg == NULL || !esp_uart_validate_config(cfg)) return 0; struct esp_uart_state *us = s_us[cfg->uart_no]; if (us != NULL) { s_us[cfg->uart_no] = NULL; esp_uart_deinit(us); } us = calloc(1, sizeof(*us)); us->cfg = cfg; cs_rbuf_init(&us->rx_buf, cfg->rx_buf_size); cs_rbuf_init(&us->tx_buf, cfg->tx_buf_size); ETS_INTR_DISABLE(ETS_UART_INUM); uart_div_modify(cfg->uart_no, UART_CLK_FREQ / cfg->baud_rate); if (cfg->uart_no == 0) { PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); if (cfg->swap_rxtx_ctsrts) { SET_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART0_PIN_SWAP); } else { CLEAR_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART0_PIN_SWAP); } } else { PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); if (cfg->swap_rxtx_ctsrts) { SET_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART1_PIN_SWAP); } else { CLEAR_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART1_PIN_SWAP); } } unsigned int conf0 = 0b011100; /* 8-N-1 */ if (cfg->tx_fc_ena) { conf0 |= UART_TX_FLOW_EN; PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); } WRITE_PERI_REG(UART_CONF0(cfg->uart_no), conf0); unsigned int conf1 = cfg->rx_fifo_full_thresh; conf1 |= (cfg->tx_fifo_empty_thresh << 8); if (cfg->rx_fifo_alarm >= 0) { conf1 |= UART_RX_TOUT_EN | ((cfg->rx_fifo_alarm & 0x7f) << 24); } if (cfg->rx_fc_ena && cfg->rx_fifo_fc_thresh > 0) { /* UART_RX_FLOW_EN will be set in uart_start. */ conf1 |= ((cfg->rx_fifo_fc_thresh & 0x7f) << 16); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); } WRITE_PERI_REG(UART_CONF1(cfg->uart_no), conf1); if (cfg->status_interval_ms > 0) { os_timer_disarm(&us->status_timer); os_timer_setfn(&us->status_timer, esp_uart_print_status, us); os_timer_arm(&us->status_timer, cfg->status_interval_ms, 1 /* repeat */); } s_us[cfg->uart_no] = us; /* Start with TX and RX ints disabled. */ WRITE_PERI_REG(UART_INT_ENA(cfg->uart_no), UART_INFO_INTS); ETS_UART_INTR_ATTACH(esp_uart_isr, NULL); ETS_INTR_ENABLE(ETS_UART_INUM); return 1; }
IRAM uint8_t get_rx_fifo_full_thresh(int uart_no) { return READ_PERI_REG(UART_CONF1(uart_no)) & 0x7f; }
bool mgos_uart_hal_configure(struct mgos_uart_state *us, const struct mgos_uart_config *cfg) { if (!esp_uart_validate_config(cfg)) return false; #ifdef RTOS_SDK _xt_isr_mask(1 << ETS_UART_INUM); #else ETS_INTR_DISABLE(ETS_UART_INUM); #endif uart_div_modify(us->uart_no, UART_CLK_FREQ / cfg->baud_rate); if (us->uart_no == 0) { if (cfg->dev.swap_rxcts_txrts) { PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 4 /* FUNC_U0CTS */); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); SET_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART0_PIN_SWAP); } else { PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD); PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, 0 /* FUNC_U0RXD */); CLEAR_PERI_REG_MASK(PERIPHS_DPORT_BASEADDR + HOST_INF_SEL, PERI_IO_UART0_PIN_SWAP); } } else { if (cfg->dev.swap_rxcts_txrts) { /* Swapping pins of UART1 is not supported, they all conflict with SPI * flash anyway. */ return false; } else { PIN_PULLUP_DIS(PERIPHS_IO_MUX_GPIO2_U); PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK); } } unsigned int conf0 = 0; switch (cfg->num_data_bits) { case 5: break; case 6: conf0 |= 1 << UART_BIT_NUM_S; break; case 7: conf0 |= 2 << UART_BIT_NUM_S; break; case 8: conf0 |= 3 << UART_BIT_NUM_S; break; default: return false; } switch (cfg->parity) { case MGOS_UART_PARITY_NONE: break; case MGOS_UART_PARITY_EVEN: conf0 |= UART_PARITY_EN; break; case MGOS_UART_PARITY_ODD: conf0 |= (UART_PARITY_EN | UART_PARITY_ODD); break; } switch (cfg->stop_bits) { case MGOS_UART_STOP_BITS_1: conf0 |= 1 << UART_STOP_BIT_NUM_S; break; case MGOS_UART_STOP_BITS_1_5: conf0 |= 2 << UART_STOP_BIT_NUM_S; break; case MGOS_UART_STOP_BITS_2: conf0 |= 3 << UART_STOP_BIT_NUM_S; break; } if (cfg->tx_fc_type == MGOS_UART_FC_HW) { conf0 |= UART_TX_FLOW_EN; PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, FUNC_U0CTS); } WRITE_PERI_REG(UART_CONF0(us->uart_no), conf0); unsigned int conf1 = cfg->dev.rx_fifo_full_thresh; conf1 |= (cfg->dev.tx_fifo_empty_thresh << 8); if (cfg->dev.rx_fifo_alarm >= 0) { conf1 |= UART_RX_TOUT_EN | ((cfg->dev.rx_fifo_alarm & 0x7f) << 24); } if (cfg->rx_fc_type == MGOS_UART_FC_HW && cfg->dev.rx_fifo_fc_thresh > 0) { /* UART_RX_FLOW_EN will be set in uart_start. */ conf1 |= ((cfg->dev.rx_fifo_fc_thresh & 0x7f) << 16); PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, FUNC_U0RTS); } WRITE_PERI_REG(UART_CONF1(us->uart_no), conf1); #ifdef RTOS_SDK _xt_isr_unmask(1 << ETS_UART_INUM); #else ETS_INTR_ENABLE(ETS_UART_INUM); #endif return true; }