From bdf6402277294f12981d06479bf466545693d0c4 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Wed, 13 Aug 2025 13:54:26 +0200 Subject: [PATCH 01/10] Initial work on getting analog read working This will also make the touch sensors work! --- .../Zephyr/boards/stm32l496g_disco.overlay | 87 +++++++++++++++++++ platforms/Zephyr/prj.conf | 1 + src/Primitives/zephyr.cpp | 67 +++++++++++++- 3 files changed, 154 insertions(+), 1 deletion(-) diff --git a/platforms/Zephyr/boards/stm32l496g_disco.overlay b/platforms/Zephyr/boards/stm32l496g_disco.overlay index 884ba80f..b53f616c 100644 --- a/platforms/Zephyr/boards/stm32l496g_disco.overlay +++ b/platforms/Zephyr/boards/stm32l496g_disco.overlay @@ -180,3 +180,90 @@ status = "okay"; pinctrl-names = "default"; }; + +&adc1 { + pinctrl-0 = < &adc1_in5_pa0 >; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@5 { + reg = <5>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@6 { + reg = <6>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@7 { + reg = <7>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@8 { + reg = <8>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; diff --git a/platforms/Zephyr/prj.conf b/platforms/Zephyr/prj.conf index 40ae2945..841702f5 100644 --- a/platforms/Zephyr/prj.conf +++ b/platforms/Zephyr/prj.conf @@ -1,5 +1,6 @@ CONFIG_GPIO=y CONFIG_PWM=y +CONFIG_ADC=y CONFIG_CPP=y CONFIG_STD_CPP17=y CONFIG_REQUIRES_FULL_LIBCPP=y diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 66d1f0cd..2338255c 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -36,7 +37,7 @@ #ifdef CONFIG_BOARD_STM32L496G_DISCO #define OBB_PRIMITIVES 6 #endif -#define ALL_PRIMITIVES OBB_PRIMITIVES + 6 +#define ALL_PRIMITIVES OBB_PRIMITIVES + 7 // Global index for installing primitives int prim_index = 0; @@ -301,6 +302,69 @@ def_prim(chip_digital_read, oneToOneU32) { return true; } +def_prim(chip_analog_read, oneToOneU32) { + printf("chip_analog_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);*/ + + int16_t buf; + //struct adc_sequence seq = { .buffer = &buf, .buffer_size = sizeof(buf) }; + //const int channel = 6; // Port 2 + //const int channel = 7; // Port 3 + //const int channel = 8; // Port 4 + int *channels = new int[4]{ + -1, // Port 1 + 6, // Port 2 + 7, // Port 3 + 8, // Port 4 + }; + int channel = channels[arg0.uint32]; + if (channel < 0) { + printf("Invalid channel for chip_analog_read(%d)\n", arg0.uint32); + return false; + } + struct adc_sequence seq = { + .channels = BIT(channel), // Assuming channel 0 is the one we want to read + .buffer = &buf, + .buffer_size = sizeof(buf), + .resolution = 12, // 12-bit resolution + //.oversampling = 0, + }; + + static const struct device *adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc1)); + static const struct adc_channel_cfg channel_cfgs[] = { + DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc1), ADC_CHANNEL_CFG_DT, (,))}; + + int err = adc_channel_setup(adc_dev, &channel_cfgs[channel]); + if (err < 0) { + printf("Failed to setup ADC channel: %d\n", err); + return false; + } + + err = adc_read(adc_dev, &seq); + if (err < 0) { + printf("Failed to read ADC channel: %d\n", err); + return false; + } + + /*const adc_dt_spec spec = ADC_DT_SPEC_GET(DT_NODELABEL(adc1)); + + //adc_channel_setup(adc_dev, struct adc_channel_cf) + int err = adc_channel_setup_dt(&spec); + if (err < 0) { + printf("Failed to setup ADC channel: %d\n", err); + return false; + } + + adc_read_dt(&spec, &seq);*/ + + printf("ADC read value: %d\n", buf); + + pop_args(1); + pushUInt32(buf); + return true; +} + def_prim(print_int, oneToNoneI32) { printf("%d\n", arg0.int32); pop_args(1); @@ -481,6 +545,7 @@ void install_primitives() { install_primitive(chip_digital_write); install_primitive_reverse(chip_digital_write); install_primitive(chip_digital_read); + install_primitive(chip_analog_read); install_primitive(print_int); install_primitive(abort); From a7b1e62eb7bf7886b18c156bc8a4853622a7ca4e Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Tue, 30 Sep 2025 14:14:12 +0200 Subject: [PATCH 02/10] work in progress adc3 configuration for input 1 --- .../Zephyr/boards/stm32l496g_disco.overlay | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) diff --git a/platforms/Zephyr/boards/stm32l496g_disco.overlay b/platforms/Zephyr/boards/stm32l496g_disco.overlay index b53f616c..84fd9777 100644 --- a/platforms/Zephyr/boards/stm32l496g_disco.overlay +++ b/platforms/Zephyr/boards/stm32l496g_disco.overlay @@ -267,3 +267,136 @@ zephyr,resolution = <12>; }; }; + +&pinctrl { + adc3_test: adc3_test { + pinmux = ; + }; +}; + +&adc3 { + status = "okay"; + st,adc-clock-source = "SYNC"; + st,adc-prescaler = < 0x4 >; + resolutions = < 0x60630c 0x51630c 0x42630c 0x33630c >; + sampling-times = < 0x3 0x7 0xd 0x19 0x30 0x5d 0xf8 0x281 >; + st,adc-sequencer = "FULLY_CONFIGURABLE"; + st,adc-oversampler = "OVERSAMPLER_MINIMAL"; + pinctrl-names = "default"; + pinctrl-0 = < &adc3_test >; + #address-cells = <1>; + #size-cells = <0>; + + channel@0 { + reg = <0>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@1 { + reg = <1>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@2 { + reg = <2>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@3 { + reg = <3>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@4 { + reg = <4>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@5 { + reg = <5>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@6 { + reg = <6>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@7 { + reg = <7>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@8 { + reg = <8>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@9 { + reg = <9>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@10 { + reg = <10>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@11 { + reg = <11>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@12 { + reg = <12>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; +}; From 25b281bde299de8802ee97d5629270bace33a1fa Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Tue, 30 Sep 2025 18:04:15 +0200 Subject: [PATCH 03/10] Switch between adcs for the different ports Currently done with an if, we probably want to do this with an array in the end. --- src/Primitives/zephyr.cpp | 37 +++++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 2338255c..bb8e7a9b 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -313,7 +313,7 @@ def_prim(chip_analog_read, oneToOneU32) { //const int channel = 7; // Port 3 //const int channel = 8; // Port 4 int *channels = new int[4]{ - -1, // Port 1 + 12, // Port 1 6, // Port 2 7, // Port 3 8, // Port 4 @@ -323,6 +323,7 @@ def_prim(chip_analog_read, oneToOneU32) { printf("Invalid channel for chip_analog_read(%d)\n", arg0.uint32); return false; } + printf("Configuring channel %d\n", channel); struct adc_sequence seq = { .channels = BIT(channel), // Assuming channel 0 is the one we want to read .buffer = &buf, @@ -331,33 +332,37 @@ def_prim(chip_analog_read, oneToOneU32) { //.oversampling = 0, }; - static const struct device *adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc1)); - static const struct adc_channel_cfg channel_cfgs[] = { - DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc1), ADC_CHANNEL_CFG_DT, (,))}; + // Modify the adc on both lines here! + const device *adc_dev; + adc_channel_cfg cfg; - int err = adc_channel_setup(adc_dev, &channel_cfgs[channel]); + if (arg0.uint32 == 0) { + adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc3)); + struct adc_channel_cfg channel_cfgs[] = { + DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc3), ADC_CHANNEL_CFG_DT, (,))}; + cfg = channel_cfgs[channel]; + } + else { + adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc1)); + struct adc_channel_cfg channel_cfgs[] = { + DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc1), ADC_CHANNEL_CFG_DT, (,))}; + cfg = channel_cfgs[channel]; + } + + int err = adc_channel_setup(adc_dev, &cfg); if (err < 0) { printf("Failed to setup ADC channel: %d\n", err); + perror("failed to setup ADC channel"); return false; } err = adc_read(adc_dev, &seq); if (err < 0) { printf("Failed to read ADC channel: %d\n", err); + perror("failed to read ADC channel"); return false; } - /*const adc_dt_spec spec = ADC_DT_SPEC_GET(DT_NODELABEL(adc1)); - - //adc_channel_setup(adc_dev, struct adc_channel_cf) - int err = adc_channel_setup_dt(&spec); - if (err < 0) { - printf("Failed to setup ADC channel: %d\n", err); - return false; - } - - adc_read_dt(&spec, &seq);*/ - printf("ADC read value: %d\n", buf); pop_args(1); From 569826dc8897dba9d42e0d5db89af840bca296cb Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Wed, 1 Oct 2025 10:03:37 +0200 Subject: [PATCH 04/10] Add pin 6 channels for ev3 touch sensors --- .../Zephyr/boards/stm32l496g_disco.overlay | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/platforms/Zephyr/boards/stm32l496g_disco.overlay b/platforms/Zephyr/boards/stm32l496g_disco.overlay index 84fd9777..45e42945 100644 --- a/platforms/Zephyr/boards/stm32l496g_disco.overlay +++ b/platforms/Zephyr/boards/stm32l496g_disco.overlay @@ -265,7 +265,25 @@ //zephyr,vref-mv = <8>; zephyr,acquisition-time = ; zephyr,resolution = <12>; - }; + }; + + channel@9 { + reg = <9>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; + + channel@10 { + reg = <10>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + //zephyr,vref-mv = <8>; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; }; &pinctrl { @@ -399,4 +417,12 @@ zephyr,acquisition-time = ; zephyr,resolution = <12>; }; + + channel@13 { + reg = <13>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + zephyr,acquisition-time = ; + zephyr,resolution = <12>; + }; }; From a539c3c9f84df8019338a547ba5204103efcbc5e Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Wed, 1 Oct 2025 11:09:21 +0200 Subject: [PATCH 05/10] EV3 Touch sensor support --- src/Primitives/zephyr.cpp | 65 +++++++++++++++++++++++++++++---------- 1 file changed, 48 insertions(+), 17 deletions(-) diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index bb8e7a9b..1233b01e 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -35,7 +35,7 @@ #define OBB_PRIMITIVES 0 #ifdef CONFIG_BOARD_STM32L496G_DISCO -#define OBB_PRIMITIVES 6 +#define OBB_PRIMITIVES 7 #endif #define ALL_PRIMITIVES OBB_PRIMITIVES + 7 @@ -302,28 +302,32 @@ def_prim(chip_digital_read, oneToOneU32) { return true; } -def_prim(chip_analog_read, oneToOneU32) { - printf("chip_analog_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);*/ +int16_t read_value(int c, int *channels) { + //printf("read_value(%u)\n", c); - int16_t buf; + int16_t buf = -1; //struct adc_sequence seq = { .buffer = &buf, .buffer_size = sizeof(buf) }; //const int channel = 6; // Port 2 //const int channel = 7; // Port 3 //const int channel = 8; // Port 4 - int *channels = new int[4]{ + /*int *channels = new int[4]{ 12, // Port 1 6, // Port 2 7, // Port 3 8, // Port 4 - }; - int channel = channels[arg0.uint32]; + };*/ + /*int *channels = new int[4]{ + 13, // Port 1 + 5, // Port 2 + 9, // Port 3 + 10, // Port 4 + };*/ + int channel = channels[c]; if (channel < 0) { - printf("Invalid channel for chip_analog_read(%d)\n", arg0.uint32); - return false; + printf("Invalid channel for chip_analog_read(%d)\n", channel); + return -1; } - printf("Configuring channel %d\n", channel); + //printf("Configuring channel %d\n", channel); struct adc_sequence seq = { .channels = BIT(channel), // Assuming channel 0 is the one we want to read .buffer = &buf, @@ -336,7 +340,7 @@ def_prim(chip_analog_read, oneToOneU32) { const device *adc_dev; adc_channel_cfg cfg; - if (arg0.uint32 == 0) { + if (c == 0) { adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc3)); struct adc_channel_cfg channel_cfgs[] = { DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc3), ADC_CHANNEL_CFG_DT, (,))}; @@ -353,20 +357,45 @@ def_prim(chip_analog_read, oneToOneU32) { if (err < 0) { printf("Failed to setup ADC channel: %d\n", err); perror("failed to setup ADC channel"); - return false; + return -1; } err = adc_read(adc_dev, &seq); if (err < 0) { printf("Failed to read ADC channel: %d\n", err); perror("failed to read ADC channel"); - return false; + return -1; } - printf("ADC read value: %d\n", buf); + printf("ADC read value(channel = %d): %d\n", channel, buf); + return buf; +} + +def_prim(chip_analog_read, oneToOneU32) { + int channels[4] = { + 12, // Port 1 + 6, // Port 2 + 7, // Port 3 + 8, // Port 4 + }; + int16_t v = read_value(arg0.uint32, channels); + pop_args(1); + pushUInt32(v); + return true; +} + +def_prim(ev3_touch_sensor, oneToOneU32) { + printf("ev3_touch_sensor(%u)\n", arg0.uint32); + int channels[4] = { + 13, // Port 1 + 5, // Port 2 + 9, // Port 3 + 10, // Port 4 + }; + int16_t v = read_value(arg0.uint32, channels); pop_args(1); - pushUInt32(buf); + pushUInt32(v > 3000); return true; } @@ -564,6 +593,8 @@ void install_primitives() { install_primitive(read_uart_sensor); install_primitive(setup_uart_sensor); + install_primitive(ev3_touch_sensor); + k_timer_init(&heartbeat_timer, heartbeat_timer_func, nullptr); k_timer_start(&heartbeat_timer, K_MSEC(500), K_MSEC(500)); #endif From a7d0693b97f23ac3be812a47179e5ef367e24a92 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Wed, 1 Oct 2025 15:02:50 +0200 Subject: [PATCH 06/10] Rename analog_read to nxt_touch_sensor Will add support for generic analog_read later. --- src/Primitives/zephyr.cpp | 202 +++++++++++++++++++------------------- 1 file changed, 102 insertions(+), 100 deletions(-) diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 1233b01e..7e2fdd38 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -35,9 +35,9 @@ #define OBB_PRIMITIVES 0 #ifdef CONFIG_BOARD_STM32L496G_DISCO -#define OBB_PRIMITIVES 7 +#define OBB_PRIMITIVES 8 #endif -#define ALL_PRIMITIVES OBB_PRIMITIVES + 7 +#define ALL_PRIMITIVES OBB_PRIMITIVES + 6 // Global index for installing primitives int prim_index = 0; @@ -302,103 +302,6 @@ def_prim(chip_digital_read, oneToOneU32) { return true; } -int16_t read_value(int c, int *channels) { - //printf("read_value(%u)\n", c); - - int16_t buf = -1; - //struct adc_sequence seq = { .buffer = &buf, .buffer_size = sizeof(buf) }; - //const int channel = 6; // Port 2 - //const int channel = 7; // Port 3 - //const int channel = 8; // Port 4 - /*int *channels = new int[4]{ - 12, // Port 1 - 6, // Port 2 - 7, // Port 3 - 8, // Port 4 - };*/ - /*int *channels = new int[4]{ - 13, // Port 1 - 5, // Port 2 - 9, // Port 3 - 10, // Port 4 - };*/ - int channel = channels[c]; - if (channel < 0) { - printf("Invalid channel for chip_analog_read(%d)\n", channel); - return -1; - } - //printf("Configuring channel %d\n", channel); - struct adc_sequence seq = { - .channels = BIT(channel), // Assuming channel 0 is the one we want to read - .buffer = &buf, - .buffer_size = sizeof(buf), - .resolution = 12, // 12-bit resolution - //.oversampling = 0, - }; - - // Modify the adc on both lines here! - const device *adc_dev; - adc_channel_cfg cfg; - - if (c == 0) { - adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc3)); - struct adc_channel_cfg channel_cfgs[] = { - DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc3), ADC_CHANNEL_CFG_DT, (,))}; - cfg = channel_cfgs[channel]; - } - else { - adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc1)); - struct adc_channel_cfg channel_cfgs[] = { - DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc1), ADC_CHANNEL_CFG_DT, (,))}; - cfg = channel_cfgs[channel]; - } - - int err = adc_channel_setup(adc_dev, &cfg); - if (err < 0) { - printf("Failed to setup ADC channel: %d\n", err); - perror("failed to setup ADC channel"); - return -1; - } - - err = adc_read(adc_dev, &seq); - if (err < 0) { - printf("Failed to read ADC channel: %d\n", err); - perror("failed to read ADC channel"); - return -1; - } - - printf("ADC read value(channel = %d): %d\n", channel, buf); - return buf; -} - -def_prim(chip_analog_read, oneToOneU32) { - int channels[4] = { - 12, // Port 1 - 6, // Port 2 - 7, // Port 3 - 8, // Port 4 - }; - int16_t v = read_value(arg0.uint32, channels); - pop_args(1); - pushUInt32(v); - return true; -} - -def_prim(ev3_touch_sensor, oneToOneU32) { - printf("ev3_touch_sensor(%u)\n", arg0.uint32); - - int channels[4] = { - 13, // Port 1 - 5, // Port 2 - 9, // Port 3 - 10, // Port 4 - }; - int16_t v = read_value(arg0.uint32, channels); - pop_args(1); - pushUInt32(v > 3000); - return true; -} - def_prim(print_int, oneToNoneI32) { printf("%d\n", arg0.int32); pop_args(1); @@ -567,6 +470,105 @@ void heartbeat_timer_func(struct k_timer *timer_id) { uartHeartbeat(&sensors[i]); } } + +int16_t read_value(int c, int *channels) { + //printf("read_value(%u)\n", c); + + int16_t buf = -1; + //struct adc_sequence seq = { .buffer = &buf, .buffer_size = sizeof(buf) }; + //const int channel = 6; // Port 2 + //const int channel = 7; // Port 3 + //const int channel = 8; // Port 4 + /*int *channels = new int[4]{ + 12, // Port 1 + 6, // Port 2 + 7, // Port 3 + 8, // Port 4 + };*/ + /*int *channels = new int[4]{ + 13, // Port 1 + 5, // Port 2 + 9, // Port 3 + 10, // Port 4 + };*/ + int channel = channels[c]; + if (channel < 0) { + printf("Invalid channel for chip_analog_read(%d)\n", channel); + return -1; + } + //printf("Configuring channel %d\n", channel); + struct adc_sequence seq = { + .channels = BIT(channel), // Assuming channel 0 is the one we want to read + .buffer = &buf, + .buffer_size = sizeof(buf), + .resolution = 12, // 12-bit resolution + //.oversampling = 0, + }; + + // Modify the adc on both lines here! + const device *adc_dev; + adc_channel_cfg cfg; + + if (c == 0) { + adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc3)); + struct adc_channel_cfg channel_cfgs[] = { + DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc3), ADC_CHANNEL_CFG_DT, (,))}; + cfg = channel_cfgs[channel]; + } + else { + adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc1)); + struct adc_channel_cfg channel_cfgs[] = { + DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc1), ADC_CHANNEL_CFG_DT, (,))}; + cfg = channel_cfgs[channel]; + } + + int err = adc_channel_setup(adc_dev, &cfg); + if (err < 0) { + printf("Failed to setup ADC channel: %d\n", err); + perror("failed to setup ADC channel"); + return -1; + } + + err = adc_read(adc_dev, &seq); + if (err < 0) { + printf("Failed to read ADC channel: %d\n", err); + perror("failed to read ADC channel"); + return -1; + } + + printf("ADC read value(channel = %d): %d\n", channel, buf); + return buf; +} + +def_prim(nxt_touch_sensor, oneToOneU32) { + int channels[4] = { + 12, // Port 1 + 6, // Port 2 + 7, // Port 3 + 8, // Port 4 + }; + int16_t v = read_value(arg0.uint32, channels); + pop_args(1); + pushUInt32(v < 2000); + return true; +} + +// Currently only works on ports 1, 3, and 4. +def_prim(ev3_touch_sensor, oneToOneU32) { + printf("ev3_touch_sensor(%u)\n", arg0.uint32); + + int channels[4] = { + 13, // Port 1 + 5, // Port 2 + 9, // Port 3 + 10, // Port 4 + }; + int16_t v = read_value(arg0.uint32, channels); + pop_args(1); + pushUInt32(v > 3000); + return true; +} + #endif //------------------------------------------------------ @@ -579,7 +581,6 @@ void install_primitives() { install_primitive(chip_digital_write); install_primitive_reverse(chip_digital_write); install_primitive(chip_digital_read); - install_primitive(chip_analog_read); install_primitive(print_int); install_primitive(abort); @@ -593,6 +594,7 @@ void install_primitives() { install_primitive(read_uart_sensor); install_primitive(setup_uart_sensor); + install_primitive(nxt_touch_sensor); install_primitive(ev3_touch_sensor); k_timer_init(&heartbeat_timer, heartbeat_timer_func, nullptr); From 99038abb8dfb4e959ddc2c877a1442af5f04f4c1 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Wed, 1 Oct 2025 15:04:20 +0200 Subject: [PATCH 07/10] Rename analog_read to nxt_touch_sensor Will add support for generic analog_read later. --- src/Primitives/zephyr.cpp | 29 +++++------------------------ 1 file changed, 5 insertions(+), 24 deletions(-) diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 7e2fdd38..f41f7d9b 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -472,25 +472,7 @@ void heartbeat_timer_func(struct k_timer *timer_id) { } int16_t read_value(int c, int *channels) { - //printf("read_value(%u)\n", c); - int16_t buf = -1; - //struct adc_sequence seq = { .buffer = &buf, .buffer_size = sizeof(buf) }; - //const int channel = 6; // Port 2 - //const int channel = 7; // Port 3 - //const int channel = 8; // Port 4 - /*int *channels = new int[4]{ - 12, // Port 1 - 6, // Port 2 - 7, // Port 3 - 8, // Port 4 - };*/ - /*int *channels = new int[4]{ - 13, // Port 1 - 5, // Port 2 - 9, // Port 3 - 10, // Port 4 - };*/ int channel = channels[c]; if (channel < 0) { printf("Invalid channel for chip_analog_read(%d)\n", channel); @@ -498,17 +480,16 @@ int16_t read_value(int c, int *channels) { } //printf("Configuring channel %d\n", channel); struct adc_sequence seq = { - .channels = BIT(channel), // Assuming channel 0 is the one we want to read + .channels = BIT(channel), .buffer = &buf, .buffer_size = sizeof(buf), - .resolution = 12, // 12-bit resolution - //.oversampling = 0, + .resolution = 12 }; - // Modify the adc on both lines here! const device *adc_dev; adc_channel_cfg cfg; + // Port 0 uses adc3, the other ports use adc1. if (c == 0) { adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc3)); struct adc_channel_cfg channel_cfgs[] = { @@ -559,8 +540,8 @@ def_prim(ev3_touch_sensor, oneToOneU32) { int channels[4] = { 13, // Port 1 - 5, // Port 2 - 9, // Port 3 + 5, // Port 2 + 9, // Port 3 10, // Port 4 }; int16_t v = read_value(arg0.uint32, channels); From 39ec5fa13974e5671410ae73e26ed3b7fd4f66f9 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Wed, 1 Oct 2025 15:06:07 +0200 Subject: [PATCH 08/10] clang-format --- src/Primitives/zephyr.cpp | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index f41f7d9b..08217d76 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -14,9 +14,9 @@ #include #include #include +#include #include #include -#include #include #include @@ -478,13 +478,11 @@ int16_t read_value(int c, int *channels) { printf("Invalid channel for chip_analog_read(%d)\n", channel); return -1; } - //printf("Configuring channel %d\n", channel); - struct adc_sequence seq = { - .channels = BIT(channel), - .buffer = &buf, - .buffer_size = sizeof(buf), - .resolution = 12 - }; + // printf("Configuring channel %d\n", channel); + struct adc_sequence seq = {.channels = BIT(channel), + .buffer = &buf, + .buffer_size = sizeof(buf), + .resolution = 12}; const device *adc_dev; adc_channel_cfg cfg; @@ -493,13 +491,12 @@ int16_t read_value(int c, int *channels) { if (c == 0) { adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc3)); struct adc_channel_cfg channel_cfgs[] = { - DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc3), ADC_CHANNEL_CFG_DT, (,))}; + DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc3), ADC_CHANNEL_CFG_DT, (, ))}; cfg = channel_cfgs[channel]; - } - else { + } else { adc_dev = DEVICE_DT_GET(DT_NODELABEL(adc1)); struct adc_channel_cfg channel_cfgs[] = { - DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc1), ADC_CHANNEL_CFG_DT, (,))}; + DT_FOREACH_CHILD_SEP(DT_NODELABEL(adc1), ADC_CHANNEL_CFG_DT, (, ))}; cfg = channel_cfgs[channel]; } @@ -523,10 +520,10 @@ int16_t read_value(int c, int *channels) { def_prim(nxt_touch_sensor, oneToOneU32) { int channels[4] = { - 12, // Port 1 - 6, // Port 2 - 7, // Port 3 - 8, // Port 4 + 12, // Port 1 + 6, // Port 2 + 7, // Port 3 + 8, // Port 4 }; int16_t v = read_value(arg0.uint32, channels); pop_args(1); @@ -539,10 +536,10 @@ def_prim(ev3_touch_sensor, oneToOneU32) { printf("ev3_touch_sensor(%u)\n", arg0.uint32); int channels[4] = { - 13, // Port 1 - 5, // Port 2 - 9, // Port 3 - 10, // Port 4 + 13, // Port 1 + 5, // Port 2 + 9, // Port 3 + 10, // Port 4 }; int16_t v = read_value(arg0.uint32, channels); pop_args(1); From 7bb496b172f8e5ab871346302468a87f43e0a57b Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Mon, 6 Oct 2025 10:13:45 +0200 Subject: [PATCH 09/10] Minor changes + add print_string to zephyr --- src/Primitives/zephyr.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 08217d76..7e80619e 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -37,7 +37,7 @@ #ifdef CONFIG_BOARD_STM32L496G_DISCO #define OBB_PRIMITIVES 8 #endif -#define ALL_PRIMITIVES OBB_PRIMITIVES + 6 +#define ALL_PRIMITIVES OBB_PRIMITIVES + 7 // Global index for installing primitives int prim_index = 0; @@ -302,6 +302,16 @@ def_prim(chip_digital_read, oneToOneU32) { return true; } +def_prim(print_string, twoToNoneU32) { + uint32_t addr = arg1.uint32; + uint32_t size = arg0.uint32; + std::string text = parse_utf8_string(m->memory.bytes, size, addr); + debug("EMU: print string at %i: ", addr); + printf("%s", text.c_str()); + pop_args(2); + return true; +} + def_prim(print_int, oneToNoneI32) { printf("%d\n", arg0.int32); pop_args(1); @@ -478,7 +488,6 @@ int16_t read_value(int c, int *channels) { printf("Invalid channel for chip_analog_read(%d)\n", channel); return -1; } - // printf("Configuring channel %d\n", channel); struct adc_sequence seq = {.channels = BIT(channel), .buffer = &buf, .buffer_size = sizeof(buf), @@ -510,7 +519,6 @@ int16_t read_value(int c, int *channels) { err = adc_read(adc_dev, &seq); if (err < 0) { printf("Failed to read ADC channel: %d\n", err); - perror("failed to read ADC channel"); return -1; } @@ -559,6 +567,7 @@ void install_primitives() { install_primitive(chip_digital_write); install_primitive_reverse(chip_digital_write); install_primitive(chip_digital_read); + install_primitive(print_string); install_primitive(print_int); install_primitive(abort); From 13d78958a82ff52b58284c1b098001b50bdf4654 Mon Sep 17 00:00:00 2001 From: MaartenS11 Date: Mon, 6 Oct 2025 10:24:02 +0200 Subject: [PATCH 10/10] Added nxt and ev3 touch sensor primitives to the emulator Instead of always returning 1 or 0 they also use a random 12bit number. --- src/Primitives/emulated.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Primitives/emulated.cpp b/src/Primitives/emulated.cpp index 577d4ea6..cfcd171b 100644 --- a/src/Primitives/emulated.cpp +++ b/src/Primitives/emulated.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include #include "../Memory/mem.h" @@ -27,7 +28,7 @@ #include "primitives.h" #define NUM_PRIMITIVES 0 -#define NUM_PRIMITIVES_ARDUINO 35 +#define NUM_PRIMITIVES_ARDUINO 37 #define ALL_PRIMITIVES (NUM_PRIMITIVES + NUM_PRIMITIVES_ARDUINO) @@ -558,6 +559,28 @@ def_prim(read_uart_sensor, oneToOneI32) { return true; } +std::random_device r; +std::default_random_engine e(r()); +std::uniform_int_distribution adc_dist(0, 1 << 12); // 12 bit adc + +def_prim(nxt_touch_sensor, oneToOneU32) { + const uint32_t port = arg0.uint32; + const int16_t v = adc_dist(e); + pop_args(1); + printf("nxt_touch_sensor(%u) = %d\n", port, v < 2000); + pushUInt32(v < 2000); + return true; +} + +def_prim(ev3_touch_sensor, oneToOneU32) { + const uint32_t port = arg0.uint32; + const int16_t v = adc_dist(e); + pop_args(1); + printf("ev3_touch_sensor(%u) = %d\n", port, v > 3000); + pushUInt32(v > 3000); + return true; +} + def_prim(subscribe_interrupt, threeToNoneU32) { uint8_t pin = arg2.uint32; // GPIOPin uint8_t tidx = arg1.uint32; // Table Idx pointing to Callback function @@ -661,6 +684,8 @@ void install_primitives() { install_primitive(stop_motor); install_primitive(setup_uart_sensor); install_primitive(read_uart_sensor); + install_primitive(nxt_touch_sensor); + install_primitive(ev3_touch_sensor); } //------------------------------------------------------