|
| 1 | +#include "devs_internal.h" |
| 2 | +#include "services/interfaces/jd_spi.h" |
| 3 | + |
| 4 | +void fun5_DeviceScript_spiConfigure(devs_ctx_t *ctx) { |
| 5 | +#if JD_SPI |
| 6 | + jd_spi_cfg_t cfg = { |
| 7 | + .miso = devs_arg_int(ctx, 0), |
| 8 | + .mosi = devs_arg_int(ctx, 1), |
| 9 | + .sck = devs_arg_int(ctx, 2), |
| 10 | + .mode = devs_arg_int(ctx, 3), |
| 11 | + .hz = devs_arg_int(ctx, 4), |
| 12 | + }; |
| 13 | + |
| 14 | + int r = jd_spi_init(&cfg); |
| 15 | + if (r) |
| 16 | + devs_throw_range_error(ctx, "SPI init failed: %d", r); |
| 17 | +#else |
| 18 | + devs_throw_not_supported_error(ctx, "SPI"); |
| 19 | +#endif |
| 20 | +} |
| 21 | + |
| 22 | +#if JD_SPI |
| 23 | +static uint8_t is_done; |
| 24 | +static void spi_done(void) { |
| 25 | + devs_fiber_await_done(&is_done); |
| 26 | +} |
| 27 | + |
| 28 | +void throw_spi_error(devs_ctx_t *ctx, void *userdata) { |
| 29 | + devs_throw_range_error(ctx, "SPI error: %d", (int)(intptr_t)userdata); |
| 30 | +} |
| 31 | +#endif |
| 32 | + |
| 33 | +void fun2_DeviceScript_spiXfer(devs_ctx_t *ctx) { |
| 34 | +#if JD_SPI |
| 35 | + value_t tx = devs_arg(ctx, 0); |
| 36 | + value_t rx = devs_arg(ctx, 1); |
| 37 | + |
| 38 | + unsigned tx_sz; |
| 39 | + const void *tx_ptr = devs_bufferish_data(ctx, tx, &tx_sz); |
| 40 | + unsigned rx_sz; |
| 41 | + const void *rx_ptr = devs_bufferish_data(ctx, rx, &rx_sz); |
| 42 | + |
| 43 | + if (!jd_spi_is_ready()) |
| 44 | + devs_throw_range_error(ctx, "SPI busy"); |
| 45 | + else if (!tx_ptr && !rx_ptr) |
| 46 | + devs_throw_expecting_error_ext(ctx, "at least one of TX/RX buffers", tx); |
| 47 | + else if (tx_ptr && rx_ptr && tx_sz != rx_sz) |
| 48 | + devs_throw_expecting_error_ext(ctx, "same size TX/RX buffers", tx); |
| 49 | + else if (rx_ptr && !devs_buffer_is_writable(ctx, rx)) |
| 50 | + devs_throw_expecting_error_ext(ctx, "mutable Buffer", rx); |
| 51 | + else { |
| 52 | + if (!tx_sz) |
| 53 | + tx_sz = rx_sz; |
| 54 | + devs_fiber_t *fib = ctx->curr_fiber; |
| 55 | + devs_fiber_await(fib, &is_done); |
| 56 | + int r = jd_spi_xfer(tx_ptr, (void *)rx_ptr, tx_sz, spi_done); |
| 57 | + if (r) { |
| 58 | + // we've been already de-scheduled - arrange for exception on resume |
| 59 | + fib->resume_cb = throw_spi_error; |
| 60 | + fib->resume_data = (void *)r; |
| 61 | + devs_fiber_await_done(&is_done); // schedule resume |
| 62 | + } |
| 63 | + } |
| 64 | + |
| 65 | +#else |
| 66 | + devs_throw_not_supported_error(ctx, "SPI"); |
| 67 | +#endif |
| 68 | +} |
0 commit comments