SJ_PRIVATE enum v7_err GPIO_setISR(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t pinv = v7_arg(v7, 0); v7_val_t typev = v7_arg(v7, 1); v7_val_t cb = v7_arg(v7, 2); v7_val_t current_cb; char prop_name[15]; int pin, type, len, has_isr, new_isr_provided; if (!v7_is_number(pinv) || !v7_is_number(typev)) { printf("Invalid arguments\n"); *res = v7_mk_boolean(v7, 0); goto clean; } pin = v7_get_double(v7, pinv); type = v7_get_double(v7, typev); len = snprintf(prop_name, sizeof(prop_name), "_ih_%d", (int) pin); current_cb = v7_get(v7, v7_get_global(v7), prop_name, len); has_isr = v7_is_callable(v7, current_cb); new_isr_provided = v7_is_callable(v7, cb); if (!has_isr && !new_isr_provided) { printf("Missing callback\n"); *res = v7_mk_boolean(v7, 0); goto clean; }; if (has_isr && new_isr_provided && current_cb != cb) { printf("Only one interruption handler is allowed for pin\n"); *res = v7_mk_boolean(v7, 0); goto clean; } if (type == 0 && has_isr) { v7_set(v7, v7_get_global(v7), prop_name, len, V7_UNDEFINED); } else if (!has_isr && new_isr_provided) { v7_set(v7, v7_get_global(v7), prop_name, len, cb); } if (type != 0 && !s_gpio_intr_installed) { sj_gpio_intr_init(gpio_intr_handler_proxy, v7); s_isr_cb_proxy_v = v7_mk_cfunction(isr_cb_proxy); v7_own(v7, &s_isr_cb_proxy_v); s_gpio_intr_installed = 1; } *res = v7_mk_boolean(v7, sj_gpio_intr_set(pin, (enum gpio_int_mode) type) == 0); goto clean; clean: return rcode; }
static ub_val_t obj_to_ubj(struct v7 *v7, struct ub_ctx *ctx, v7_val_t obj) { LOG(LL_VERBOSE_DEBUG, ("enter")); if (v7_is_number(obj)) { double n = v7_get_double(v7, obj); LOG(LL_VERBOSE_DEBUG, ("type=number val=%d", (int) n)) return ub_create_number(n); } else if (v7_is_string(obj)) {
SJ_PRIVATE enum v7_err global_clearTimeoutOrInterval(struct v7 *v7, v7_val_t *res) { (void) res; if (v7_is_number(v7_arg(v7, 0))) { sj_clear_timer(v7_get_double(v7, v7_arg(v7, 0))); } return V7_OK; }
/* * Read the content of the UART. It does not block. * Optional `max_len` parameter, defaults to max size_t. */ static enum v7_err UART_read(struct v7 *v7, v7_val_t *res) { v7_val_t this_obj = v7_get_this(v7); v7_val_t dev = v7_get(v7, this_obj, "_dev", ~0), maxv = v7_arg(v7, 0); size_t max = v7_is_number(maxv) ? (size_t) v7_get_double(v7, maxv) : (size_t) ~0; *res = sj_hal_read_uart(v7, v7_get_ptr(v7, dev), max); return V7_OK; }
static enum v7_err esp_sj_uart_get_state(struct v7 *v7, struct esp_sj_uart_state **us) { int uart_no = v7_get_double(v7, v7_get(v7, v7_get_this(v7), "_u", 2)); if (uart_no < 0 || uart_no > 1) { return v7_throwf(v7, "Error", "Invalid UART number"); } *us = &sj_us[uart_no]; return V7_OK; }
SJ_PRIVATE enum v7_err GPIO_setMode(struct v7 *v7, v7_val_t *res) { v7_val_t pinv = v7_arg(v7, 0); v7_val_t modev = v7_arg(v7, 1); v7_val_t pullv = v7_arg(v7, 2); int pin, mode, pull; if (!v7_is_number(pinv) || !v7_is_number(modev) || !v7_is_number(pullv)) { printf("Invalid arguments\n"); *res = V7_UNDEFINED; } else { pin = v7_get_double(v7, pinv); mode = v7_get_double(v7, modev); pull = v7_get_double(v7, pullv); *res = v7_mk_boolean(v7, sj_gpio_set_mode(pin, (enum gpio_mode) mode, (enum gpio_pull_type) pull) == 0); } return V7_OK; }
static enum v7_err UART_get(struct v7 *v7, v7_val_t *res) { enum v7_err ret = V7_OK; v7_val_t arg0 = v7_arg(v7, 0); int uart_no = v7_get_double(v7, arg0); if (v7_is_number(arg0) && (uart_no == 0 || uart_no == 1)) { *res = sj_us[uart_no].obj; } else { ret = v7_throwf(v7, "Error", "Invalid UART number"); } return ret; }
SJ_PRIVATE enum v7_err GPIO_read(struct v7 *v7, v7_val_t *res) { v7_val_t pinv = v7_arg(v7, 0); int pin; if (!v7_is_number(pinv)) { printf("non-numeric pin\n"); *res = V7_UNDEFINED; } else { pin = v7_get_double(v7, pinv); *res = v7_mk_number(v7, sj_gpio_read(pin)); } return V7_OK; }
SJ_PRIVATE enum v7_err global_usleep(struct v7 *v7, v7_val_t *res) { v7_val_t usecsv = v7_arg(v7, 0); int usecs; (void) res; if (!v7_is_number(usecsv)) { printf("usecs is not a double\n\r"); } else { usecs = v7_get_double(v7, usecsv); sj_usleep(usecs); } return V7_OK; }
static enum v7_err Sys_wdtSetTimeout(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t timeoutv = v7_arg(v7, 0); if (!v7_is_number(timeoutv)) { rcode = v7_throwf(v7, "Error", "Timeout should be a number"); } else { sj_wdt_set_timeout(v7_get_double(v7, timeoutv)); } *res = v7_mk_boolean(v7, rcode == V7_OK); return V7_OK; }
static enum v7_err Sys_reboot(struct v7 *v7, v7_val_t *res) { int exit_code = 0; (void) v7; (void) res; v7_val_t code_v = v7_arg(v7, 0); if (v7_is_number(code_v)) { exit_code = v7_get_double(v7, code_v); } sj_system_restart(exit_code); /* Unreachable */ return V7_OK; }
static enum v7_err isr_cb_proxy(struct v7 *v7, v7_val_t *res) { v7_val_t cb = v7_arg(v7, 0); v7_val_t args = v7_arg(v7, 1); v7_own(v7, &cb); v7_own(v7, &args); enum v7_err ret = v7_apply(v7, cb, v7_get_global(v7), args, res); sj_reenable_intr(v7_get_double(v7, v7_array_get(v7, args, 0))); v7_disown(v7, &args); v7_disown(v7, &cb); return ret; }
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_get_double(v7, 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; }
SJ_PRIVATE enum v7_err sj_set_interval_or_timeout(struct v7 *v7, v7_val_t *res, int repeat) { v7_val_t msecsv = v7_arg(v7, 1); int msecs; (void) res; if (!v7_is_callable(v7, v7_arg(v7, 0))) { printf("cb is not a function\n"); } else if (!v7_is_number(msecsv)) { printf("msecs is not a number\n"); } else { v7_val_t cb = v7_arg(v7, 0); msecs = v7_get_double(v7, msecsv); *res = v7_mk_number(v7, sj_set_js_timer(msecs, repeat, v7, cb)); } return V7_OK; }
/* * Regiter a callback to be invoked when there is at least N bytes available. * N defaults to maxint if undefined */ static enum v7_err UART_recv(struct v7 *v7, v7_val_t *res) { v7_val_t this_obj = v7_get_this(v7); v7_val_t cb = v7_arg(v7, 0); v7_val_t wantv = v7_arg(v7, 1); v7_val_t udv = v7_get(v7, this_obj, "_ud", ~0); size_t want = v7_is_number(wantv) ? (size_t) v7_get_double(v7, wantv) : (size_t) ~0; struct user_data *ud = (struct user_data *) v7_get_ptr(v7, udv); ud->cb = cb; v7_own(v7, &ud->cb); ud->want = want; /* TODO(mkm): trigger cb if there is already something in the buffer */ *res = v7_mk_boolean(v7, 1); return V7_OK; }
SJ_PRIVATE enum v7_err Wifi_ip(struct v7 *v7, v7_val_t *res) { v7_val_t arg0 = v7_arg(v7, 0); char *ip = NULL; ip = v7_is_number(arg0) && v7_get_double(v7, arg0) == 1 ? sj_wifi_get_ap_ip() : sj_wifi_get_sta_ip(); if (ip == NULL) { *res = V7_UNDEFINED; goto clean; } *res = v7_mk_string(v7, ip, strlen(ip), 1); clean: if (ip != NULL) { free(ip); } return V7_OK; }
static enum v7_err Sys_setLogLevel(struct v7 *v7, v7_val_t *res) { enum v7_err rcode = V7_OK; v7_val_t llv = v7_arg(v7, 0); int ll; if (!v7_is_number(llv)) { *res = v7_mk_boolean(v7, 0); goto clean; } ll = v7_get_double(v7, llv); if (ll <= _LL_MIN || ll >= _LL_MAX) { *res = v7_mk_boolean(v7, 0); goto clean; } cs_log_set_level((enum cs_log_level) ll); *res = v7_mk_boolean(v7, 1); goto clean; clean: return rcode; }
int v7_example(void) { size_t n; const char *domain_str; struct v7 *v7 = v7_create(); v7_val_t domain, port0, config; /* Load JSON configuration */ if (v7_parse_json_file(v7, "config.json", &config) != V7_OK) { printf("%s\n", "Cannot load JSON config"); return 1; } /* Lookup values in JSON configuration object */ domain = v7_get(v7, config, "domain", 6); port0 = v7_array_get(v7, v7_get(v7, config, "ports", 5), 0); domain_str = v7_get_string(v7, &domain, &n); printf("Domain: [%.*s], port 0: [%d]\n", (int) n, domain_str, (int) v7_get_double(port0)); v7_destroy(v7); return 0; }
SJ_PRIVATE enum v7_err GPIO_write(struct v7 *v7, v7_val_t *res) { v7_val_t pinv = v7_arg(v7, 0); v7_val_t valv = v7_arg(v7, 1); int pin, val; if (!v7_is_number(pinv)) { printf("non-numeric pin\n"); *res = V7_UNDEFINED; } else { pin = v7_get_double(v7, pinv); /* * We assume 0 if the value is "falsy", * and 1 if the value is "truthy" */ val = !!v7_is_truthy(v7, valv); *res = v7_mk_boolean( v7, sj_gpio_write(pin, val ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW) == 0); } return V7_OK; }