Exemplo n.º 1
0
IRAM NOINSTR static void esp_handle_uart_int(struct mgos_uart_state *us) {
  if (us == NULL) return;
  const int uart_no = us->uart_no;
  /* Since both UARTs use the same int, we need to apply the mask manually. */
  const unsigned int int_st = READ_PERI_REG(UART_INT_ST(uart_no)) &
                              READ_PERI_REG(UART_INT_ENA(uart_no));
  const struct mgos_uart_config *cfg = &us->cfg;
  if (int_st == 0) return;
  us->stats.ints++;
  if (int_st & UART_RXFIFO_OVF_INT_ST) us->stats.rx_overflows++;
  if (int_st & UART_CTS_CHG_INT_ST) {
    if (esp_uart_cts(uart_no) != 0 && esp_uart_tx_fifo_len(uart_no) > 0) {
      us->stats.tx_throttles++;
    }
  }
  if (int_st & (UART_RX_INTS | UART_TX_INTS)) {
    int int_ena = UART_INFO_INTS;
    if (int_st & UART_RX_INTS) us->stats.rx_ints++;
    if (int_st & UART_TX_INTS) us->stats.tx_ints++;
    if (adj_rx_fifo_full_thresh(us)) {
      int_ena |= UART_RXFIFO_FULL_INT_ENA;
    } else if (cfg->rx_fc_type == MGOS_UART_FC_SW) {
      /* Send XOFF and keep RX ints disabled */
      while (esp_uart_tx_fifo_len(uart_no) >= 127) {
      }
      esp_uart_tx_byte(uart_no, MGOS_UART_XOFF_CHAR);
      us->xoff_sent = true;
    }
    WRITE_PERI_REG(UART_INT_ENA(uart_no), int_ena);
    mgos_uart_schedule_dispatcher(uart_no, true /* from_isr */);
  }
  WRITE_PERI_REG(UART_INT_CLR(uart_no), int_st);
}
Exemplo n.º 2
0
IRAM NOINSTR static void esp_handle_uart_int(struct miot_uart_state *us) {
  const int uart_no = us->uart_no;
  /* Since both UARTs use the same int, we need to apply the mask manually. */
  const unsigned int int_st = READ_PERI_REG(UART_INT_ST(uart_no)) &
                              READ_PERI_REG(UART_INT_ENA(uart_no));
  if (int_st == 0) return;
  us->stats.ints++;
  if (int_st & UART_RXFIFO_OVF_INT_ST) us->stats.rx_overflows++;
  if (int_st & UART_CTS_CHG_INT_ST) {
    if (esp_uart_cts(uart_no) != 0 && esp_uart_tx_fifo_len(uart_no) > 0) {
      us->stats.tx_throttles++;
    }
  }
  if (int_st & (UART_RX_INTS | UART_TX_INTS)) {
    if (int_st & UART_RX_INTS) us->stats.rx_ints++;
    if (int_st & UART_TX_INTS) us->stats.tx_ints++;
    /* Wake up the processor and disable TX and RX ints until it runs. */
    WRITE_PERI_REG(UART_INT_ENA(uart_no), UART_INFO_INTS);
    miot_uart_schedule_dispatcher(uart_no);
  }
  WRITE_PERI_REG(UART_INT_CLR(uart_no), int_st);
}