Exemplo n.º 1
0
static void cc32xx_int_handler(struct mgos_uart_state *us) {
  if (us == NULL) return;
  struct cc32xx_uart_state *ds = (struct cc32xx_uart_state *) us->dev_data;
  uint32_t int_st = MAP_UARTIntStatus(ds->base, true /* masked */);
  us->stats.ints++;
  uint32_t int_dis = UART_TX_INTS;
  if (int_st & UART_INT_OE) {
    us->stats.rx_overflows++;
    HWREG(ds->base + UART_O_ECR) = 0xff;
  }
  if (int_st & (UART_RX_INTS | UART_TX_INTS)) {
    if (int_st & UART_RX_INTS) {
      us->stats.rx_ints++;
      struct cs_rbuf *irxb = &ds->isr_rx_buf;
      cc32xx_uart_rx_bytes(ds->base, irxb);
      if (us->cfg.rx_fc_type == MGOS_UART_FC_SW &&
          irxb->used >= CC32xx_UART_ISR_RX_BUF_FC_THRESH && !us->xoff_sent) {
        MAP_UARTCharPut(ds->base, MGOS_UART_XOFF_CHAR);
        us->xoff_sent = true;
      }
      /* Do not disable RX ints if we have space in the ISR buffer. */
      if (irxb->avail == 0) int_dis |= UART_RX_INTS;
    }
    if (int_st & UART_TX_INTS) us->stats.tx_ints++;
    mgos_uart_schedule_dispatcher(us->uart_no, true /* from_isr */);
  }
  MAP_UARTIntDisable(ds->base, int_dis);
  MAP_UARTIntClear(ds->base, int_st);
}
Exemplo n.º 2
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);
}