static enum v7_err UART_sendAvail(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; *res = v7_mk_number(esp_uart_tx_buf(us->uart_no)->avail); return V7_OK; }
IRAM void esp_uart_flush(int uart_no) { cs_rbuf_t *txb = esp_uart_tx_buf(uart_no); while (txb != NULL && txb->used > 0) { esp_uart_dispatch_tx_top(uart_no); } while (tx_fifo_len(uart_no) > 0) { } }
size_t esp_sj_uart_write(int uart_no, const void *buf, size_t len) { size_t n = 0; cs_rbuf_t *txb = esp_uart_tx_buf(uart_no); while (n < len) { while (txb->avail == 0) { esp_uart_dispatch_tx_top(uart_no); } size_t nw = MIN(len - n, txb->avail); cs_rbuf_append(txb, ((uint8_t *) buf) + n, nw); n += nw; } esp_sj_uart_schedule_dispatcher(uart_no); return len; }
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); }
static enum v7_err UART_send(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; v7_val_t arg0 = v7_arg(v7, 0); if (!v7_is_string(arg0)) { return v7_throwf(v7, "Error", "String arg required"); } size_t len = 0; const char *data = v7_get_string_data(v7, &arg0, &len); if (data != NULL && len > 0) { cs_rbuf_t *txb = esp_uart_tx_buf(us->uart_no); len = MIN(len, txb->avail); cs_rbuf_append(txb, (uint8_t *) data, len); esp_sj_uart_schedule_dispatcher(us->uart_no); } *res = v7_mk_number(len); return V7_OK; }