Пример #1
0
void esp_sj_uart_dispatcher(void *arg) {
  int uart_no = (int) arg;
  struct esp_sj_uart_state *us = &sj_us[uart_no];
  cs_rbuf_t *txb = esp_uart_tx_buf(uart_no);
  us->dispatch_pending = 0;
  esp_uart_dispatch_rx_top(uart_no);
  uint16_t tx_used_before = txb->used;

  /* ignore unused because of CS_DISABLE_JS below */
  (void) tx_used_before;

  esp_uart_dispatch_tx_top(uart_no);
#ifndef CS_DISABLE_JS
  cs_rbuf_t *rxb = esp_uart_rx_buf(uart_no);

  if (us->v7 != NULL) {
    /* Detect the edge of TX buffer becoming empty. */
    if (tx_used_before > 0 && txb->used == 0) {
      v7_val_t txcb = v7_get(us->v7, us->obj, "_txcb", 5);
      if (v7_is_callable(us->v7, txcb)) {
        sj_invoke_cb(us->v7, txcb, us->obj, V7_UNDEFINED);
      }
    }
    if (rxb->used > 0) {
      /* Check for JS recv handler. */
      v7_val_t rxcb = esp_sj_uart_get_recv_handler(uart_no);
      if (v7_is_callable(us->v7, rxcb)) {
        if (!us->recv_pending) {
          us->recv_pending = 1;
          sj_invoke_cb(us->v7, rxcb, us->obj, V7_UNDEFINED);
          /* Note: Callback has not run yet, it has been scheduled. */
        }
      } else if (us->prompt) {
        uint8_t *cp;
        while (rxb != NULL && cs_rbuf_get(rxb, 1, &cp) == 1) {
          char c = (char) *cp;
          cs_rbuf_consume(rxb, 1);
          sj_prompt_process_char(c);
          /* UART could've been re-initialized by the command from prompt. */
          rxb = esp_uart_rx_buf(uart_no);
        }
      }
    }
  }
#endif
  esp_uart_dispatch_bottom(uart_no);
}
Пример #2
0
static enum v7_err UART_recv(struct v7 *v7, v7_val_t *res) {
  struct esp_sj_uart_state *us;
  enum v7_err ret = esp_sj_uart_get_state(v7, &us);
  if (ret != V7_OK) return ret;

  cs_rbuf_t *rxb = esp_uart_rx_buf(us->uart_no);
  size_t len = MIN((size_t) v7_to_number(v7_arg(v7, 0)), rxb->used);
  uint8_t *data;
  len = cs_rbuf_get(rxb, len, &data);
  *res = v7_mk_string(v7, (const char *) data, len, 1 /* copy */);
  cs_rbuf_consume(rxb, len);
  us->recv_pending = 0;
  /* This is required to unblock interrupts after buffer has been filled.
   * And won't hurt in general. */
  esp_sj_uart_schedule_dispatcher(us->uart_no);
  return V7_OK;
}
Пример #3
0
IRAM void miot_uart_dev_dispatch_tx_top(struct miot_uart_state *us) {
  int uart_no = us->uart_no;
  cs_rbuf_t *txb = &us->tx_buf;
  uint32_t txn = 0;
  /* TX */
  if (txb->used > 0) {
    while (txb->used > 0) {
      int i;
      uint8_t *data;
      uint16_t len;
      int tx_av = us->cfg->tx_fifo_full_thresh - esp_uart_tx_fifo_len(uart_no);
      if (tx_av <= 0) break;
      len = cs_rbuf_get(txb, tx_av, &data);
      for (i = 0; i < len; i++, data++) {
        tx_byte(uart_no, *data);
      }
      txn += len;
      cs_rbuf_consume(txb, len);
    }
    us->stats.tx_bytes += txn;
  }
}
Пример #4
0
void mgos_uart_hal_dispatch_rx_top(struct mgos_uart_state *us) {
  bool recd;
  struct cc32xx_uart_state *ds = (struct cc32xx_uart_state *) us->dev_data;
  cs_rbuf_t *irxb = &ds->isr_rx_buf;
  MAP_UARTIntDisable(ds->base, UART_RX_INTS);
recv_more:
  recd = false;
  cc32xx_uart_rx_bytes(ds->base, irxb);
  while (irxb->used > 0 && mgos_uart_rxb_free(us) > 0) {
    int num_recd = 0;
    do {
      uint8_t *data;
      int num_to_get = MIN(mgos_uart_rxb_free(us), irxb->used);
      num_recd = cs_rbuf_get(irxb, num_to_get, &data);
      mbuf_append(&us->rx_buf, data, num_recd);
      cs_rbuf_consume(irxb, num_recd);
      us->stats.rx_bytes += num_recd;
      if (num_recd > 0) recd = true;
      cc32xx_uart_rx_bytes(ds->base, irxb);
    } while (num_recd > 0);
  }
  /* If we received something during this cycle and there is buffer space
   * available, "linger" for some more, maybe there's more to come. */
  if (recd && mgos_uart_rxb_free(us) > 0 && us->cfg.rx_linger_micros > 0) {
    /* Magic constants below are tweaked so that the loop takes at most the
     * configured number of microseconds. */
    int ctr = us->cfg.rx_linger_micros * 31 / 12;
    // HWREG(GPIOA1_BASE + GPIO_O_GPIO_DATA + 8) = 0xFF; /* Pin 64 */
    while (ctr-- > 0) {
      if (MAP_UARTCharsAvail(ds->base)) {
        us->stats.rx_linger_conts++;
        goto recv_more;
      }
    }
    // HWREG(GPIOA1_BASE + GPIO_O_GPIO_DATA + 8) = 0; /* Pin 64 */
  }
  MAP_UARTIntClear(ds->base, UART_RX_INTS);
}