void esp_sj_uart_set_prompt(int uart_no) { sj_us[0].prompt = sj_us[1].prompt = 0; if (uart_no >= 0 && uart_no <= 1) { sj_us[uart_no].prompt = 1; esp_uart_set_rx_enabled(uart_no, 1); esp_sj_uart_schedule_dispatcher(uart_no); } }
static enum v7_err UART_setRXEnabled(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; esp_uart_set_rx_enabled(us->uart_no, v7_is_truthy(v7, v7_arg(v7, 0))); esp_sj_uart_schedule_dispatcher(us->uart_no); *res = v7_mk_undefined(); return V7_OK; }
static enum v7_err UART_onTXEmpty(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_set(v7, us->obj, "_txcb", 5, v7_arg(v7, 0)); if (v7_is_callable(v7, v7_arg(v7, 0))) { esp_sj_uart_schedule_dispatcher(us->uart_no); } *res = v7_mk_undefined(); return V7_OK; }
/* Args: callable, disable_rx */ static enum v7_err UART_onRecv(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_set(v7, us->obj, "_rxcb", 5, v7_arg(v7, 0)); esp_uart_set_rx_enabled(us->uart_no, !v7_is_truthy(v7, v7_arg(v7, 1))); if (v7_is_callable(v7, v7_arg(v7, 0))) { esp_sj_uart_schedule_dispatcher(us->uart_no); } *res = V7_UNDEFINED; return V7_OK; }
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; }
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; }
static enum v7_err UART_configure(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; struct esp_uart_config *cfg = esp_sj_uart_default_config(us->uart_no); v7_val_t cobj = v7_arg(v7, 0); if (v7_is_object(cobj)) { v7_val_t v; #define NUM_PROP(p) \ v = v7_get(v7, cobj, #p, ~0); \ if (v7_is_number(v)) cfg->p = v7_to_number(v); #define BOOL_PROP(p) \ v = v7_get(v7, cobj, #p, ~0); \ if (!v7_is_undefined(v)) cfg->p = v7_to_boolean(v); NUM_PROP(baud_rate); NUM_PROP(rx_buf_size); BOOL_PROP(rx_fc_ena); NUM_PROP(rx_fifo_full_thresh); NUM_PROP(rx_fifo_fc_thresh); NUM_PROP(rx_fifo_alarm); NUM_PROP(rx_linger_micros); NUM_PROP(tx_buf_size); BOOL_PROP(tx_fc_ena); NUM_PROP(tx_fifo_empty_thresh); NUM_PROP(tx_fifo_full_thresh); BOOL_PROP(swap_rxtx_ctsrts); NUM_PROP(status_interval_ms); } if (esp_uart_init(cfg)) { esp_sj_uart_schedule_dispatcher(cfg->uart_no); *res = v7_mk_boolean(1); } else { free(cfg); *res = v7_mk_boolean(0); } return V7_OK; }
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; }
IRAM void esp_uart_dispatch_signal_from_isr(int uart_no) { esp_sj_uart_schedule_dispatcher(uart_no); }