diff --git a/platforms/Zephyr/prj.conf b/platforms/Zephyr/prj.conf index 841702f5..da5f292a 100644 --- a/platforms/Zephyr/prj.conf +++ b/platforms/Zephyr/prj.conf @@ -24,6 +24,8 @@ CONFIG_UART_ASYNC_API=n CONFIG_UART_WIDE_DATA=y CONFIG_UART_USE_RUNTIME_CONFIGURE=y +CONFIG_SPI=y + CONFIG_CONSOLE_SUBSYS=y CONFIG_CONSOLE_GETCHAR=y CONFIG_CONSOLE_GETCHAR_BUFSIZE=4096 diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index ad1df59f..76945c4b 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -63,6 +64,14 @@ def_prim(chip_delay, oneToNoneU32) { return true; } +def_prim(chip_delay_us, oneToNoneU32) { + debug("chip_delay_us(%u)\n", arg0.uint32); + k_yield(); + k_usleep(arg0.uint32); + pop_args(1); + return true; +} + struct gpio_dt_spec specs[] = {DT_FOREACH_PROP_ELEM_SEP( DT_PATH(zephyr_user), warduino_gpios, GPIO_DT_SPEC_GET_BY_IDX, (, ))}; @@ -82,7 +91,7 @@ def_prim(chip_pin_mode, twoToNoneU32) { std::unordered_map io_map; def_prim(chip_digital_write, twoToNoneU32) { - printf("chip_digital_write(%u,%u)\n", arg1.uint32, arg0.uint32); + debug("chip_digital_write(%u,%u)\n", arg1.uint32, arg0.uint32); gpio_dt_spec pin_spec = specs[arg1.uint32]; gpio_pin_set_raw(pin_spec.port, pin_spec.pin, arg0.uint32); io_map[arg1.uint32] = arg0.uint32; @@ -114,7 +123,7 @@ def_prim_reverse(chip_digital_write) { } def_prim(chip_digital_read, oneToOneU32) { - printf("chip_digital_read(%u)\n", arg0.uint32); + debug("chip_digital_read(%u)\n", arg0.uint32); gpio_dt_spec pin_spec = specs[arg0.uint32]; uint8_t res = gpio_pin_get_raw(pin_spec.port, pin_spec.pin); pop_args(1); @@ -377,12 +386,86 @@ def_prim(ev3_touch_sensor, oneToOneU32) { #endif +const struct device *const spi_dev = DEVICE_DT_GET(DT_NODELABEL(spi0)); + +int write_spi_bytes(unsigned char *data, size_t len) { + if (!device_is_ready(spi_dev)) { + printk("%s: device not ready.\n", spi_dev->name); + return -1; + } + + struct spi_buf tx_buf = {.buf = data, .len = len}; + struct spi_buf_set tx_bufs = {.buffers = &tx_buf, .count = 1}; + + // Now write the buffer using SPI. + struct spi_config config; + config.frequency = DT_PROP(DT_NODELABEL(spi0), clock_frequency); + config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(8) | SPI_TRANSFER_MSB; + config.slave = 0; + config.cs = {}; + + return spi_write(spi_dev, &config, &tx_bufs); +} + +int write_spi_bytes_16_prim(int times, unsigned int color) { + unsigned char *data = new unsigned char[times * 2]; + unsigned char colorB = color >> 8; + for (int x = 0; x < times; x++) { + // Most SPI devices expect Big-Endian data, so we first write the most + // significant byte. + data[x * 2 + 1] = color; + data[x * 2] = colorB; + } + + int result = write_spi_bytes(data, times * 2); + delete[] data; + return result; +} + +def_prim(write_spi_byte, oneToNoneU32) { + debug("write_spi_byte(%d)\n", arg0.uint32); + unsigned char data = (char)arg0.uint32; + int result = write_spi_bytes(&data, 1); + pop_args(1); + return result == 0; +} + +def_prim(write_spi_bytes_16, twoToNoneU32) { + debug("write_spi_bytes_16(%d, %d)\n", arg1.uint32, arg0.uint32); + int result = write_spi_bytes_16_prim(arg1.uint32, arg0.uint32); + pop_args(2); + return result == 0; +} + +def_prim(read_spi_byte, NoneToOneU32) { + debug("read_spi_byte(%u)\n", arg0.uint32); + struct spi_config config; + + config.frequency = DT_PROP(DT_NODELABEL(spi0), clock_frequency); + config.operation = SPI_OP_MODE_MASTER | SPI_WORD_SET(9); + config.slave = 0; + config.cs = {}; // TODO: Chip select line, maybe useful or can we do it + // manually not sure + + unsigned char data = 0; + struct spi_buf tx_buf = {.buf = &data, .len = 1}; + struct spi_buf_set tx_bufs = {.buffers = &tx_buf, .count = 1}; + + printf("data= %c\n", data); + + int result = spi_read(spi_dev, &config, &tx_bufs); + printf("result= %d\n", result); + pushInt32(0); + return true; +} + //------------------------------------------------------ // Installing all the primitives //------------------------------------------------------ void install_primitives(Interpreter *interpreter) { dbg_info("INSTALLING PRIMITIVES\n"); install_primitive(chip_delay); + install_primitive(chip_delay_us); install_primitive(chip_pin_mode); install_reversible_primitive(chip_digital_write); install_primitive(chip_digital_read); @@ -405,6 +488,10 @@ void install_primitives(Interpreter *interpreter) { k_timer_init(&heartbeat_timer, heartbeat_timer_func, nullptr); k_timer_start(&heartbeat_timer, K_MSEC(500), K_MSEC(500)); #endif + + install_primitive(write_spi_byte); + install_primitive(write_spi_bytes_16); + install_primitive(read_spi_byte); } Memory external_mem = {0, 0, 0, nullptr};