diff --git a/platforms/Zephyr/boards/stm32l496g_disco.overlay b/platforms/Zephyr/boards/stm32l496g_disco.overlay index 884ba80f..45e42945 100644 --- a/platforms/Zephyr/boards/stm32l496g_disco.overlay +++ b/platforms/Zephyr/boards/stm32l496g_disco.overlay @@ -180,3 +180,249 @@ 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>; + }; + + 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 { + 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>; + }; + + channel@13 { + reg = <13>; + zephyr,gain = "ADC_GAIN_1"; + zephyr,reference = "ADC_REF_INTERNAL"; + 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/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); } //------------------------------------------------------ diff --git a/src/Primitives/zephyr.cpp b/src/Primitives/zephyr.cpp index 66d1f0cd..7e80619e 100644 --- a/src/Primitives/zephyr.cpp +++ b/src/Primitives/zephyr.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -34,9 +35,9 @@ #define OBB_PRIMITIVES 0 #ifdef CONFIG_BOARD_STM32L496G_DISCO -#define OBB_PRIMITIVES 6 +#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; @@ -301,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); @@ -469,6 +480,81 @@ void heartbeat_timer_func(struct k_timer *timer_id) { uartHeartbeat(&sensors[i]); } } + +int16_t read_value(int c, int *channels) { + int16_t buf = -1; + int channel = channels[c]; + if (channel < 0) { + printf("Invalid channel for chip_analog_read(%d)\n", channel); + return -1; + } + struct adc_sequence seq = {.channels = BIT(channel), + .buffer = &buf, + .buffer_size = sizeof(buf), + .resolution = 12}; + + 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[] = { + 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); + 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 //------------------------------------------------------ @@ -481,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); @@ -494,6 +581,9 @@ 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); k_timer_start(&heartbeat_timer, K_MSEC(500), K_MSEC(500)); #endif