From e372af59c8a30d45a89b87e1542dda06602ede5d Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 23 Apr 2024 22:19:58 -0600 Subject: [PATCH 01/22] stub in more device tree. OLED display is working with this demo: west build -p always -b mellifera_rev1 ../zephyr/samples/subsys/display/cfb --- boards/bh/mellifera_rev1/mellifera_rev1.dts | 79 +++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index f1a9ce4..325e769 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -19,6 +19,7 @@ // zephyr,bt-c2h-uart = &uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; + zephyr,display = &ssd1306; }; example_sensor: example-sensor { @@ -44,8 +45,71 @@ gpios = <&gpio0 13 GPIO_ACTIVE_HIGH>; label = "Yellow LED 3"; }; + led_rx: led_rx { + gpios = <&gpio0 2 GPIO_ACTIVE_HIGH>; + label = "RX LED"; + }; + led_tx: led_tx { + gpios = <&gpio0 3 GPIO_ACTIVE_HIGH>; + label = "TX LED"; + }; + led_rx_ok: led_rx_ok { + gpios = <&gpio0 0 GPIO_ACTIVE_HIGH>; + label = "RX OK LED"; + }; + led_sfd: led_sfd { + gpios = <&gpio0 1 GPIO_ACTIVE_HIGH>; + label = "SFD LED"; + }; }; + buttons { + compatible = "gpio-keys"; + int_drdy: int_drdy { + gpios = <&gpio0 22 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "DRDYM from BMX055 9-DOF"; + zephyr,code = ; + }; + int1: int_1 { + gpios = <&gpio0 12 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Interrupt 1 from BMX055 9-DOF"; + zephyr,code = ; + }; + int2: int_2 { + gpios = <&gpio0 14 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Interrupt 2 from BMX055 9-DOF"; + zephyr,code = ; + }; + int3: int_3 { + gpios = <&gpio0 10 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Interrupt 3 from BMX055 9-DOF"; + zephyr,code = ; + }; + int4: int_4 { + gpios = <&gpio0 9 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Interrupt 4 from BMX055 9-DOF"; + zephyr,code = ; + }; + int5: int_5 { + gpios = <&gpio0 30 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Interrupt 5 from BMX055 9-DOF"; + zephyr,code = ; + }; + + int_baro: int_baro { + gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Interrupt from BMP388 barometer"; + zephyr,code = ; + }; + + int_pow: int_pow { + gpios = <&gpio0 31 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Interrupt from current sensor"; + zephyr,code = ; + }; + }; + + blink_led: blink-led { compatible = "blink-gpio-led"; led-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; @@ -80,6 +144,21 @@ pinctrl-0 = <&i2c0_default>; pinctrl-1 = <&i2c0_sleep>; pinctrl-names = "default", "sleep"; + + + ssd1306: ssd1306@3d { + compatible = "solomon,ssd1306fb"; + reg = <0x3d>; + width = <128>; + height = <64>; + segment-offset = <0>; + page-offset = <0>; + display-offset = <0>; + multiplex-ratio = <63>; + segment-remap; + com-invdir; + prechargep = <0x22>; + }; }; &spi1 { From ef9a35929343a54ee2b2a300fc62352670720c26 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 23 Apr 2024 22:42:45 -0600 Subject: [PATCH 02/22] formatting --- app/src/main.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 2c9c3ab..ade9d9f 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -14,31 +14,34 @@ LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL); #define BLINK_PERIOD_MS_STEP 100U -#define BLINK_PERIOD_MS_MAX 1000U +#define BLINK_PERIOD_MS_MAX 1000U int main(void) { int ret; unsigned int period_ms = BLINK_PERIOD_MS_MAX; const struct device *sensor, *blink; - struct sensor_value last_val = { 0 }, val; + struct sensor_value last_val = {0}, val; printk("Zephyr Example Application %s\n", APP_VERSION_STRING); sensor = DEVICE_DT_GET(DT_NODELABEL(example_sensor)); - if (!device_is_ready(sensor)) { + if (!device_is_ready(sensor)) + { LOG_ERR("Sensor not ready"); return 0; } blink = DEVICE_DT_GET(DT_NODELABEL(blink_led)); - if (!device_is_ready(blink)) { + if (!device_is_ready(blink)) + { LOG_ERR("Blink LED not ready"); return 0; } ret = blink_off(blink); - if (ret < 0) { + if (ret < 0) + { LOG_ERR("Could not turn off LED (%d)", ret); return 0; } @@ -47,23 +50,30 @@ int main(void) printk("Use the sensor to change LED blinking period\n"); - while (1) { + while (1) + { ret = sensor_sample_fetch(sensor); - if (ret < 0) { + if (ret < 0) + { LOG_ERR("Could not fetch sample (%d)", ret); return 0; } ret = sensor_channel_get(sensor, SENSOR_CHAN_PROX, &val); - if (ret < 0) { + if (ret < 0) + { LOG_ERR("Could not get sample (%d)", ret); return 0; } - if ((last_val.val1 == 0) && (val.val1 == 1)) { - if (period_ms == 0U) { + if ((last_val.val1 == 0) && (val.val1 == 1)) + { + if (period_ms == 0U) + { period_ms = BLINK_PERIOD_MS_MAX; - } else { + } + else + { period_ms -= BLINK_PERIOD_MS_STEP; } @@ -79,4 +89,3 @@ int main(void) return 0; } - From 8bf321c11c137eb486a599979d9d7a724a748a7b Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 23 Apr 2024 22:44:03 -0600 Subject: [PATCH 03/22] copy stuff from display example --- app/prj.conf | 11 +++++++ app/src/main.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 96 insertions(+), 1 deletion(-) diff --git a/app/prj.conf b/app/prj.conf index ac51ec3..55461d3 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -5,3 +5,14 @@ CONFIG_SENSOR=y CONFIG_BLINK=y + +CONFIG_STDOUT_CONSOLE=y + +CONFIG_HEAP_MEM_POOL_SIZE=16384 + +CONFIG_DISPLAY=y + +CONFIG_LOG=y + +CONFIG_CFB_LOG_LEVEL_DBG=y +CONFIG_CHARACTER_FRAMEBUFFER=y \ No newline at end of file diff --git a/app/src/main.c b/app/src/main.c index ade9d9f..aea0bb7 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -6,6 +6,7 @@ #include #include #include +#include #include @@ -18,6 +19,89 @@ LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL); int main(void) { + const struct device *dev; + uint16_t x_res; + uint16_t y_res; + uint16_t rows; + uint8_t ppt; + uint8_t font_width; + uint8_t font_height; + + dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); + if (!device_is_ready(dev)) + { + printf("Device %s not ready\n", dev->name); + return 0; + } + + if (display_set_pixel_format(dev, PIXEL_FORMAT_MONO10) != 0) + { + if (display_set_pixel_format(dev, PIXEL_FORMAT_MONO01) != 0) + { + printf("Failed to set required pixel format"); + return 0; + } + } + + printf("Initialized %s\n", dev->name); + + if (cfb_framebuffer_init(dev)) + { + printf("Framebuffer initialization failed!\n"); + return 0; + } + + cfb_framebuffer_clear(dev, true); + + display_blanking_off(dev); + + x_res = cfb_get_display_parameter(dev, CFB_DISPLAY_WIDTH); + y_res = cfb_get_display_parameter(dev, CFB_DISPLAY_HEIGH); + rows = cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS); + ppt = cfb_get_display_parameter(dev, CFB_DISPLAY_PPT); + + for (int idx = 0; idx < 42; idx++) + { + if (cfb_get_font_size(dev, idx, &font_width, &font_height)) + { + break; + } + cfb_framebuffer_set_font(dev, idx); + printf("font width %d, font height %d\n", + font_width, font_height); + } + + printf("x_res %d, y_res %d, ppt %d, rows %d, cols %d\n", + x_res, + y_res, + ppt, + rows, + cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)); + + cfb_framebuffer_invert(dev); + + cfb_set_kerning(dev, 3); + + while (1) + { + for (int i = 0; i < MIN(x_res, y_res); i++) + { + cfb_framebuffer_clear(dev, false); + if (cfb_print(dev, + "0123456789mMgj!\"§$%&/()=", + i, i)) + { + printf("Failed to print a string\n"); + continue; + } + + cfb_framebuffer_finalize(dev); +#if defined(CONFIG_ARCH_POSIX) + k_sleep(K_MSEC(20)); +#endif + } + } + int ret; unsigned int period_ms = BLINK_PERIOD_MS_MAX; const struct device *sensor, *blink; @@ -78,7 +162,7 @@ int main(void) } printk("Proximity detected, setting LED period to %u ms\n", - period_ms); + period_ms); blink_set_period_ms(blink, period_ms); } From e1772508fea911ef60db8515a0893cecc1c5a26c Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 23 Apr 2024 23:25:03 -0600 Subject: [PATCH 04/22] voltage and current sensing --- app/src/main.c | 36 +++++++++++++++++++-- boards/bh/mellifera_rev1/mellifera_rev1.dts | 16 +++++---- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index aea0bb7..89dc302 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -78,14 +78,46 @@ int main(void) rows, cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)); - cfb_framebuffer_invert(dev); - cfb_set_kerning(dev, 3); + const struct device *ina; + + ina = DEVICE_DT_GET(DT_NODELABEL(ina231)); + if (!device_is_ready(dev)) + { + printf("Device %s not ready\n", ina->name); + return 0; + } + while (1) { for (int i = 0; i < MIN(x_res, y_res); i++) { + int ret; + + ret = sensor_sample_fetch(ina); + if (ret < 0) + { + LOG_ERR("Could not fetch sample (%d)", ret); + return 0; + } + + struct sensor_value voltage, current; + ret = sensor_channel_get(ina, SENSOR_CHAN_VOLTAGE, &voltage); + if (ret < 0) + { + LOG_ERR("Could not get sample (%d)", ret); + return 0; + } + ret = sensor_channel_get(ina, SENSOR_CHAN_CURRENT, ¤t); + if (ret < 0) + { + LOG_ERR("Could not get sample (%d)", ret); + return 0; + } + + printf("voltage: %d.%06d\tcurrent: %d.%06d\n", voltage.val1, voltage.val2, current.val1, current.val2); + cfb_framebuffer_clear(dev, false); if (cfb_print(dev, "0123456789mMgj!\"§$%&/()=", diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index 325e769..d44faa1 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -101,12 +101,6 @@ label = "Interrupt from BMP388 barometer"; zephyr,code = ; }; - - int_pow: int_pow { - gpios = <&gpio0 31 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - label = "Interrupt from current sensor"; - zephyr,code = ; - }; }; @@ -145,7 +139,6 @@ pinctrl-1 = <&i2c0_sleep>; pinctrl-names = "default", "sleep"; - ssd1306: ssd1306@3d { compatible = "solomon,ssd1306fb"; reg = <0x3d>; @@ -159,6 +152,15 @@ com-invdir; prechargep = <0x22>; }; + + ina231: ina231@45 { + compatible = "ti,ina230"; + reg = <0x45>; + // irq-gpios = <&gpio0 31 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + current-lsb-microamps = <7>; + rshunt-micro-ohms = <50000>; + adc-mode = "Bus and shunt voltage continuous"; + }; }; &spi1 { From 6d42a445de1ee35e9b2bca1c1f60a981c67b5878 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 23 Apr 2024 23:38:12 -0600 Subject: [PATCH 05/22] real use of the display --- app/src/main.c | 84 +++++++++++++++++++++++++++----------------------- 1 file changed, 45 insertions(+), 39 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 89dc302..133af1b 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -70,6 +70,7 @@ int main(void) printf("font width %d, font height %d\n", font_width, font_height); } + cfb_framebuffer_set_font(dev, 0); printf("x_res %d, y_res %d, ppt %d, rows %d, cols %d\n", x_res, @@ -91,47 +92,52 @@ int main(void) while (1) { - for (int i = 0; i < MIN(x_res, y_res); i++) + int ret; + char str_v[15] = {0}; + char str_i[15] = {0}; + + ret = sensor_sample_fetch(ina); + if (ret < 0) { - int ret; - - ret = sensor_sample_fetch(ina); - if (ret < 0) - { - LOG_ERR("Could not fetch sample (%d)", ret); - return 0; - } - - struct sensor_value voltage, current; - ret = sensor_channel_get(ina, SENSOR_CHAN_VOLTAGE, &voltage); - if (ret < 0) - { - LOG_ERR("Could not get sample (%d)", ret); - return 0; - } - ret = sensor_channel_get(ina, SENSOR_CHAN_CURRENT, ¤t); - if (ret < 0) - { - LOG_ERR("Could not get sample (%d)", ret); - return 0; - } - - printf("voltage: %d.%06d\tcurrent: %d.%06d\n", voltage.val1, voltage.val2, current.val1, current.val2); - - cfb_framebuffer_clear(dev, false); - if (cfb_print(dev, - "0123456789mMgj!\"§$%&/()=", - i, i)) - { - printf("Failed to print a string\n"); - continue; - } - - cfb_framebuffer_finalize(dev); -#if defined(CONFIG_ARCH_POSIX) - k_sleep(K_MSEC(20)); -#endif + LOG_ERR("Could not fetch sample (%d)", ret); + return 0; } + + struct sensor_value voltage, current; + ret = sensor_channel_get(ina, SENSOR_CHAN_VOLTAGE, &voltage); + if (ret < 0) + { + LOG_ERR("Could not get sample (%d)", ret); + return 0; + } + ret = sensor_channel_get(ina, SENSOR_CHAN_CURRENT, ¤t); + if (ret < 0) + { + LOG_ERR("Could not get sample (%d)", ret); + return 0; + } + + sprintf(str_v, "V:%d.%06d", voltage.val1, voltage.val2); + sprintf(str_i, "I:%d.%06d", current.val1, current.val2); + + printf("%s\t%s\n", str_v, str_i); + + cfb_framebuffer_clear(dev, false); + if (cfb_print(dev, str_v, 0, 0)) + { + printf("Failed to print a string\n"); + continue; + } + if (cfb_print(dev, str_i, 0, 16)) + { + printf("Failed to print a string\n"); + continue; + } + + cfb_framebuffer_finalize(dev); +#if defined(CONFIG_ARCH_POSIX) + k_sleep(K_MSEC(20)); +#endif } int ret; From a02a1c2641fab006240220f91f702fc124009288 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 23 Apr 2024 23:55:27 -0600 Subject: [PATCH 06/22] add pressure sensor. Only reading once though --- app/src/main.c | 31 +++++++++++++++++---- boards/bh/mellifera_rev1/mellifera_rev1.dts | 14 ++++++---- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 133af1b..675686b 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -81,7 +81,7 @@ int main(void) cfb_set_kerning(dev, 3); - const struct device *ina; + const struct device *ina, *bmp; ina = DEVICE_DT_GET(DT_NODELABEL(ina231)); if (!device_is_ready(dev)) @@ -90,11 +90,20 @@ int main(void) return 0; } + bmp = DEVICE_DT_GET(DT_NODELABEL(bmp388)); + if (!device_is_ready(dev)) + { + printf("Device %s not ready\n", bmp->name); + return 0; + } + while (1) { int ret; + struct sensor_value voltage, current, pressure; char str_v[15] = {0}; char str_i[15] = {0}; + char str_p[15] = {0}; ret = sensor_sample_fetch(ina); if (ret < 0) @@ -103,7 +112,6 @@ int main(void) return 0; } - struct sensor_value voltage, current; ret = sensor_channel_get(ina, SENSOR_CHAN_VOLTAGE, &voltage); if (ret < 0) { @@ -117,10 +125,18 @@ int main(void) return 0; } - sprintf(str_v, "V:%d.%06d", voltage.val1, voltage.val2); - sprintf(str_i, "I:%d.%06d", current.val1, current.val2); + ret = sensor_sample_fetch(bmp); + if (ret < 0) + { + LOG_ERR("Could not fetch sample (%d)", ret); + return 0; + } - printf("%s\t%s\n", str_v, str_i); + sprintf(str_v, "V:%01d.%06d", voltage.val1, voltage.val2); + sprintf(str_i, "I:%01d.%06d", current.val1, current.val2); + sprintf(str_p, "P:%05d.%02d", pressure.val1, pressure.val2 / 10000); + + printf("%s\t%s\t%s\n", str_v, str_i, str_p); cfb_framebuffer_clear(dev, false); if (cfb_print(dev, str_v, 0, 0)) @@ -133,6 +149,11 @@ int main(void) printf("Failed to print a string\n"); continue; } + if (cfb_print(dev, str_p, 0, 32)) + { + printf("Failed to print a string\n"); + continue; + } cfb_framebuffer_finalize(dev); #if defined(CONFIG_ARCH_POSIX) diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index d44faa1..fda9927 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -95,12 +95,6 @@ label = "Interrupt 5 from BMX055 9-DOF"; zephyr,code = ; }; - - int_baro: int_baro { - gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - label = "Interrupt from BMP388 barometer"; - zephyr,code = ; - }; }; @@ -161,6 +155,14 @@ rshunt-micro-ohms = <50000>; adc-mode = "Bus and shunt voltage continuous"; }; + + bmp388: bmp388@76 { + compatible = "bosch,bmp388"; + reg = <0x76>; + int-gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + odr = "1.563"; + osr-press = <1>; + }; }; &spi1 { From a004d2526a0fc95b56d1e12ce6d35f96967f084d Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Wed, 24 Apr 2024 00:25:40 -0600 Subject: [PATCH 07/22] fix bmp288 and stub in hdc1080 --- app/src/main.c | 68 ++++++++++++++++----- boards/bh/mellifera_rev1/mellifera_rev1.dts | 7 ++- 2 files changed, 60 insertions(+), 15 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 675686b..392a9a1 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -30,7 +30,7 @@ int main(void) dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); if (!device_is_ready(dev)) { - printf("Device %s not ready\n", dev->name); + LOG_ERR("Device %s not ready\n", dev->name); return 0; } @@ -38,7 +38,7 @@ int main(void) { if (display_set_pixel_format(dev, PIXEL_FORMAT_MONO01) != 0) { - printf("Failed to set required pixel format"); + LOG_ERR("Failed to set required pixel format"); return 0; } } @@ -47,7 +47,7 @@ int main(void) if (cfb_framebuffer_init(dev)) { - printf("Framebuffer initialization failed!\n"); + LOG_ERR("Framebuffer initialization failed!\n"); return 0; } @@ -81,29 +81,38 @@ int main(void) cfb_set_kerning(dev, 3); - const struct device *ina, *bmp; + const struct device *ina, *bmp, *hdc; ina = DEVICE_DT_GET(DT_NODELABEL(ina231)); if (!device_is_ready(dev)) { - printf("Device %s not ready\n", ina->name); + LOG_ERR("Device %s not ready\n", ina->name); return 0; } bmp = DEVICE_DT_GET(DT_NODELABEL(bmp388)); if (!device_is_ready(dev)) { - printf("Device %s not ready\n", bmp->name); + LOG_ERR("Device %s not ready\n", bmp->name); return 0; } + // hdc = DEVICE_DT_GET(DT_NODELABEL(hdc1080)); + // if (!device_is_ready(dev)) + // { + // printf("Device %s not ready\n", hdc->name); + // return 0; + // } + while (1) { int ret; - struct sensor_value voltage, current, pressure; + struct sensor_value voltage, current, pressure, temperature, humidity; char str_v[15] = {0}; char str_i[15] = {0}; - char str_p[15] = {0}; + char str_p[16] = {0}; + char str_t[16] = {0}; + char str_h[16] = {0}; ret = sensor_sample_fetch(ina); if (ret < 0) @@ -111,17 +120,16 @@ int main(void) LOG_ERR("Could not fetch sample (%d)", ret); return 0; } - ret = sensor_channel_get(ina, SENSOR_CHAN_VOLTAGE, &voltage); if (ret < 0) { - LOG_ERR("Could not get sample (%d)", ret); + LOG_ERR("Could not get voltage (%d)", ret); return 0; } ret = sensor_channel_get(ina, SENSOR_CHAN_CURRENT, ¤t); if (ret < 0) { - LOG_ERR("Could not get sample (%d)", ret); + LOG_ERR("Could not get current (%d)", ret); return 0; } @@ -131,12 +139,39 @@ int main(void) LOG_ERR("Could not fetch sample (%d)", ret); return 0; } + ret = sensor_channel_get(bmp, SENSOR_CHAN_PRESS, &pressure); + if (ret < 0) + { + LOG_ERR("Could not get pressure (%d)", ret); + return 0; + } + ret = sensor_channel_get(bmp, SENSOR_CHAN_AMBIENT_TEMP, &temperature); + if (ret < 0) + { + LOG_ERR("Could not get temperature (%d)", ret); + return 0; + } + + // ret = sensor_sample_fetch(hdc); + // if (ret < 0) + // { + // LOG_ERR("Could not fetch sample (%d)", ret); + // return 0; + // } + // ret = sensor_channel_get(ina, SENSOR_CHAN_HUMIDITY, &humidity); + // if (ret < 0) + // { + // LOG_ERR("Could not get sample (%d)", ret); + // return 0; + // } sprintf(str_v, "V:%01d.%06d", voltage.val1, voltage.val2); sprintf(str_i, "I:%01d.%06d", current.val1, current.val2); - sprintf(str_p, "P:%05d.%02d", pressure.val1, pressure.val2 / 10000); + sprintf(str_p, "P:%03d.%04d", pressure.val1, pressure.val2 / 100); + sprintf(str_t, "T:%03d.%04d", temperature.val1, temperature.val2 / 100); + sprintf(str_h, "H:%05d.%06d", humidity.val1, humidity.val2); - printf("%s\t%s\t%s\n", str_v, str_i, str_p); + printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); cfb_framebuffer_clear(dev, false); if (cfb_print(dev, str_v, 0, 0)) @@ -149,7 +184,12 @@ int main(void) printf("Failed to print a string\n"); continue; } - if (cfb_print(dev, str_p, 0, 32)) + if (cfb_print(dev, str_p, 0, 16 * 2)) + { + printf("Failed to print a string\n"); + continue; + } + if (cfb_print(dev, str_t, 0, 16 * 3)) { printf("Failed to print a string\n"); continue; diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index fda9927..9ae1da8 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -160,9 +160,14 @@ compatible = "bosch,bmp388"; reg = <0x76>; int-gpios = <&gpio0 27 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; - odr = "1.563"; + // odr = "1.563"; osr-press = <1>; }; + + hdc1080: hdc1080@40 { + compatible = "ti,hdc20xx"; // FIXME: add proper support for this part. Hopefully these parts are close enough + reg = <0x40>; + }; }; &spi1 { From 29be843ad0774eacea2c6a6c56e2e42b2c454478 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sat, 27 Apr 2024 22:46:34 -0600 Subject: [PATCH 08/22] typos and remove unused code --- app/src/main.c | 76 ++++---------------------------------------------- 1 file changed, 5 insertions(+), 71 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 392a9a1..f042d19 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -27,6 +27,9 @@ int main(void) uint8_t font_width; uint8_t font_height; + printk("Starting Mellifera version %s...\n", APP_VERSION_STRING); + // printk("Board: %s\n", BOARD); + dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); if (!device_is_ready(dev)) { @@ -84,14 +87,14 @@ int main(void) const struct device *ina, *bmp, *hdc; ina = DEVICE_DT_GET(DT_NODELABEL(ina231)); - if (!device_is_ready(dev)) + if (!device_is_ready(ina)) { LOG_ERR("Device %s not ready\n", ina->name); return 0; } bmp = DEVICE_DT_GET(DT_NODELABEL(bmp388)); - if (!device_is_ready(dev)) + if (!device_is_ready(bmp)) { LOG_ERR("Device %s not ready\n", bmp->name); return 0; @@ -201,74 +204,5 @@ int main(void) #endif } - int ret; - unsigned int period_ms = BLINK_PERIOD_MS_MAX; - const struct device *sensor, *blink; - struct sensor_value last_val = {0}, val; - - printk("Zephyr Example Application %s\n", APP_VERSION_STRING); - - sensor = DEVICE_DT_GET(DT_NODELABEL(example_sensor)); - if (!device_is_ready(sensor)) - { - LOG_ERR("Sensor not ready"); - return 0; - } - - blink = DEVICE_DT_GET(DT_NODELABEL(blink_led)); - if (!device_is_ready(blink)) - { - LOG_ERR("Blink LED not ready"); - return 0; - } - - ret = blink_off(blink); - if (ret < 0) - { - LOG_ERR("Could not turn off LED (%d)", ret); - return 0; - } - - blink_set_period_ms(blink, BLINK_PERIOD_MS_MAX); - - printk("Use the sensor to change LED blinking period\n"); - - while (1) - { - ret = sensor_sample_fetch(sensor); - if (ret < 0) - { - LOG_ERR("Could not fetch sample (%d)", ret); - return 0; - } - - ret = sensor_channel_get(sensor, SENSOR_CHAN_PROX, &val); - if (ret < 0) - { - LOG_ERR("Could not get sample (%d)", ret); - return 0; - } - - if ((last_val.val1 == 0) && (val.val1 == 1)) - { - if (period_ms == 0U) - { - period_ms = BLINK_PERIOD_MS_MAX; - } - else - { - period_ms -= BLINK_PERIOD_MS_STEP; - } - - printk("Proximity detected, setting LED period to %u ms\n", - period_ms); - blink_set_period_ms(blink, period_ms); - } - - last_val = val; - - k_sleep(K_MSEC(100)); - } - return 0; } From d9acd6b2a89edbfe4a2b50d45dca8eb5ca5bec17 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sat, 27 Apr 2024 23:12:48 -0600 Subject: [PATCH 09/22] minimal communication with BMX055 --- app/src/main.c | 10 +- boards/bh/mellifera_rev1/mellifera_rev1.dts | 5 + drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/bmx055/CMakeLists.txt | 2 + drivers/sensor/bmx055/Kconfig | 17 ++ drivers/sensor/bmx055/bmx055.c | 171 ++++++++++++++++++++ dts/bindings/sensor/bosch,bmx055.yaml | 12 ++ 8 files changed, 218 insertions(+), 1 deletion(-) create mode 100644 drivers/sensor/bmx055/CMakeLists.txt create mode 100644 drivers/sensor/bmx055/Kconfig create mode 100644 drivers/sensor/bmx055/bmx055.c create mode 100644 dts/bindings/sensor/bosch,bmx055.yaml diff --git a/app/src/main.c b/app/src/main.c index f042d19..3cd4c7e 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -84,7 +84,7 @@ int main(void) cfb_set_kerning(dev, 3); - const struct device *ina, *bmp, *hdc; + const struct device *ina, *bmp, *bmx, *hdc; ina = DEVICE_DT_GET(DT_NODELABEL(ina231)); if (!device_is_ready(ina)) @@ -100,6 +100,14 @@ int main(void) return 0; } + bmx = DEVICE_DT_GET(DT_NODELABEL(bmx055)); + if (!device_is_ready(bmx)) + { + LOG_ERR("Device %s not ready\n", bmx->name); + return 0; + } + printf("Initialized %s\n", bmx->name); + // hdc = DEVICE_DT_GET(DT_NODELABEL(hdc1080)); // if (!device_is_ready(dev)) // { diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index 9ae1da8..9b967f0 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -168,6 +168,11 @@ compatible = "ti,hdc20xx"; // FIXME: add proper support for this part. Hopefully these parts are close enough reg = <0x40>; }; + + bmx055: bmx055@18 { + compatible = "bosch,bmx055"; + reg = <0x18>; + }; }; &spi1 { diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 72ed549..1b12c15 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -2,3 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 add_subdirectory_ifdef(CONFIG_EXAMPLE_SENSOR example_sensor) +add_subdirectory_ifdef(CONFIG_BMX055 bmx055) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 07b6c17..52e2f51 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -3,4 +3,5 @@ if SENSOR rsource "example_sensor/Kconfig" +rsource "bmx055/Kconfig" endif # SENSOR diff --git a/drivers/sensor/bmx055/CMakeLists.txt b/drivers/sensor/bmx055/CMakeLists.txt new file mode 100644 index 0000000..ad9d838 --- /dev/null +++ b/drivers/sensor/bmx055/CMakeLists.txt @@ -0,0 +1,2 @@ +zephyr_library() +zephyr_library_sources(bmx055.c) diff --git a/drivers/sensor/bmx055/Kconfig b/drivers/sensor/bmx055/Kconfig new file mode 100644 index 0000000..f384dad --- /dev/null +++ b/drivers/sensor/bmx055/Kconfig @@ -0,0 +1,17 @@ +config BMX055 + bool "BMX055" + default y + depends on DT_HAS_BOSCH_BMX055_ENABLED + help + Enable driver for BMX055. + +if BMX055 + +config BMX055_TRIGGER + bool "BMX055 trigger mode" + depends on BMX055 + help + Set to enable trigger mode using gpio interrupt, where + interrupts are configured to line ALERT PIN. + +endif # BMX055 diff --git a/drivers/sensor/bmx055/bmx055.c b/drivers/sensor/bmx055/bmx055.c new file mode 100644 index 0000000..c2f7141 --- /dev/null +++ b/drivers/sensor/bmx055/bmx055.c @@ -0,0 +1,171 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT bosch_bmx055 + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(bmx055, CONFIG_SENSOR_LOG_LEVEL); + +struct bmx055_data +{ + int state; +}; + +struct bmx055_config +{ + struct i2c_dt_spec bus; +#ifdef CONFIG_INA230_TRIGGER + bool trig_enabled; + uint16_t mask; + const struct gpio_dt_spec alert_gpio; + uint16_t alert_limit; +#endif /* CONFIG_INA230_TRIGGER */ +}; + +// int bmx055_reg_read(const struct i2c_dt_spec *bus, uint8_t reg, uint8_t *val) +// { +// uint8_t data[2]; +// int ret; + +// ret = i2c_burst_read_dt(bus, reg, data, sizeof(data)); +// if (ret < 0) +// { +// return ret; +// } + +// *val = sys_get_be16(data); + +// return ret; +// } + +// int bmx055_reg_write(const struct i2c_dt_spec *bus, uint8_t reg, uint8_t val) +// { +// uint8_t tx_buf[2]; + +// tx_buf[0] = reg; +// tx_buf[1] = val; + +// return i2c_write_dt(bus, tx_buf, sizeof(tx_buf)); +// } + +static int bmx055_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + // const struct bmx055_config *config = dev->config; + struct bmx055_data *data = dev->data; + + // data->state = gpio_pin_get_dt(&config->input); + data->state = 0; + + return 0; +} + +static int bmx055_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct bmx055_data *data = dev->data; + + if (chan != SENSOR_CHAN_PROX) + { + return -ENOTSUP; + } + + val->val1 = data->state; + + return 0; +} + +static const struct sensor_driver_api bmx055_api = { + .sample_fetch = &bmx055_sample_fetch, + .channel_get = &bmx055_channel_get, +}; + +static int bmx055_init(const struct device *dev) +{ + const struct bmx055_config *const config = dev->config; + int ret; + + if (!device_is_ready(config->bus.bus)) + { + LOG_ERR("I2C bus %s is not ready", config->bus.bus->name); + return -ENODEV; + } + + const uint8_t REG_BWG_CHIPID = 0x00; + uint8_t chip_id; + ret = i2c_burst_read_dt(&config->bus, REG_BWG_CHIPID, &chip_id, sizeof(chip_id)); + if (ret < 0) + { + LOG_ERR("Failed to read chip ID register!"); + return ret; + } + const uint8_t CHIP_ID = 0xfa; + if (chip_id != CHIP_ID) + { + LOG_ERR("Chip ID read from %s incorrect. Read 0x%02X, expected 0x%02X", dev->name, chip_id, CHIP_ID); + } + + // ret = ina23x_reg_write(&config->bus, INA230_REG_CONFIG, config->config); + // if (ret < 0) + // { + // LOG_ERR("Failed to write configuration register!"); + // return ret; + // } + + // ret = ina230_calibrate(dev); + // if (ret < 0) + // { + // LOG_ERR("Failed to write calibration register!"); + // return ret; + // } + + // #ifdef CONFIG_INA230_TRIGGER + // if (config->trig_enabled) + // { + // ret = ina230_trigger_mode_init(dev); + // if (ret < 0) + // { + // LOG_ERR("Failed to init trigger mode\n"); + // return ret; + // } + + // ret = ina23x_reg_write(&config->bus, INA230_REG_ALERT, config->alert_limit); + // if (ret < 0) + // { + // LOG_ERR("Failed to write alert register!"); + // return ret; + // } + + // ret = ina23x_reg_write(&config->bus, INA230_REG_MASK, config->mask); + // if (ret < 0) + // { + // LOG_ERR("Failed to write mask register!"); + // return ret; + // } + // } + // #endif /* CONFIG_INA230_TRIGGER */ + + return 0; +} + +#define BMX055_INIT(i) \ + static struct bmx055_data bmx055_data_##i; \ + \ + static const struct bmx055_config bmx055_config_##i = { \ + .bus = I2C_DT_SPEC_INST_GET(i), \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(i, &bmx055_init, NULL, \ + &bmx055_data_##i, \ + &bmx055_config_##i, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &bmx055_api); + +DT_INST_FOREACH_STATUS_OKAY(BMX055_INIT) diff --git a/dts/bindings/sensor/bosch,bmx055.yaml b/dts/bindings/sensor/bosch,bmx055.yaml new file mode 100644 index 0000000..37a2cfb --- /dev/null +++ b/dts/bindings/sensor/bosch,bmx055.yaml @@ -0,0 +1,12 @@ +description: | + TODO: add a description + +compatible: "bosch,bmx055" + +include: [sensor-device.yaml, i2c-device.yaml] + +# properties: +# input-gpios: +# type: phandle-array +# required: true +# description: Input GPIO to be sensed. From 0aae853cf7533b66670587815d67191db8597fcf Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sat, 27 Apr 2024 23:37:30 -0600 Subject: [PATCH 10/22] successfully reading temperature from BMX --- app/src/main.c | 21 ++++-- drivers/sensor/bmx055/bmx055.c | 113 +++++++++++++++++++++++---------- 2 files changed, 96 insertions(+), 38 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 3cd4c7e..90540ac 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -46,7 +46,7 @@ int main(void) } } - printf("Initialized %s\n", dev->name); + LOG_INF("Initialized %s\n", dev->name); if (cfb_framebuffer_init(dev)) { @@ -106,7 +106,7 @@ int main(void) LOG_ERR("Device %s not ready\n", bmx->name); return 0; } - printf("Initialized %s\n", bmx->name); + LOG_INF("Initialized %s\n", bmx->name); // hdc = DEVICE_DT_GET(DT_NODELABEL(hdc1080)); // if (!device_is_ready(dev)) @@ -156,7 +156,20 @@ int main(void) LOG_ERR("Could not get pressure (%d)", ret); return 0; } - ret = sensor_channel_get(bmp, SENSOR_CHAN_AMBIENT_TEMP, &temperature); + // ret = sensor_channel_get(bmp, SENSOR_CHAN_AMBIENT_TEMP, &temperature); + // if (ret < 0) + // { + // LOG_ERR("Could not get temperature (%d)", ret); + // return 0; + // } + + ret = sensor_sample_fetch(bmx); + if (ret < 0) + { + LOG_ERR("Could not fetch sample (%d)", ret); + return 0; + } + ret = sensor_channel_get(bmx, SENSOR_CHAN_DIE_TEMP, &temperature); if (ret < 0) { LOG_ERR("Could not get temperature (%d)", ret); @@ -182,7 +195,7 @@ int main(void) sprintf(str_t, "T:%03d.%04d", temperature.val1, temperature.val2 / 100); sprintf(str_h, "H:%05d.%06d", humidity.val1, humidity.val2); - printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); + // printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); cfb_framebuffer_clear(dev, false); if (cfb_print(dev, str_v, 0, 0)) diff --git a/drivers/sensor/bmx055/bmx055.c b/drivers/sensor/bmx055/bmx055.c index c2f7141..1c18093 100644 --- a/drivers/sensor/bmx055/bmx055.c +++ b/drivers/sensor/bmx055/bmx055.c @@ -13,9 +13,72 @@ #include LOG_MODULE_REGISTER(bmx055, CONFIG_SENSOR_LOG_LEVEL); +// Accelerometer registers +const uint8_t REG_BWG_CHIPID = 0x00; +const uint8_t REG_ACCD_X_LSB = 0x02; +const uint8_t REG_ACCD_X_MSB = 0x03; +const uint8_t REG_ACCD_Y_LSB = 0x04; +const uint8_t REG_ACCD_Y_MSB = 0x05; +const uint8_t REG_ACCD_Z_LSB = 0x06; +const uint8_t REG_ACCD_Z_MSB = 0x07; +const uint8_t REG_ACCD_TEMP = 0x08; +const uint8_t REG_INT_STATUS_0 = 0x09; +const uint8_t REG_INT_STATUS_1 = 0x0A; +const uint8_t REG_INT_STATUS_2 = 0x0B; +const uint8_t REG_INT_STATUS_3 = 0x0C; +const uint8_t REG_FIFO_STATUS = 0x0E; +const uint8_t REG_PMU_RANGE = 0x0F; +const uint8_t REG_PMU_BW = 0x10; +const uint8_t REG_PMU_LPW = 0x11; +const uint8_t REG_PMU_LOW_POWER = 0x12; +const uint8_t REG_ACCD_HBW = 0x13; +const uint8_t REG_BGW_SOFTRESET = 0x14; +const uint8_t REG_INT_EN_0 = 0x16; +const uint8_t REG_INT_EN_1 = 0x17; +const uint8_t REG_INT_EN_2 = 0x18; +const uint8_t REG_INT_MAP_0 = 0x19; +const uint8_t REG_INT_MAP_1 = 0x1A; +const uint8_t REG_INT_MAP_2 = 0x1B; +const uint8_t REG_INT_SRC = 0x1E; +const uint8_t REG_INT_OUT_CTRL = 0x20; +const uint8_t REG_INT_RST_LATCH = 0x21; +const uint8_t REG_INT_0 = 0x22; +const uint8_t REG_INT_1 = 0x23; +const uint8_t REG_INT_2 = 0x24; +const uint8_t REG_INT_3 = 0x25; +const uint8_t REG_INT_4 = 0x26; +const uint8_t REG_INT_5 = 0x27; +const uint8_t REG_INT_6 = 0x28; +const uint8_t REG_INT_7 = 0x29; +const uint8_t REG_INT_8 = 0x2A; +const uint8_t REG_INT_9 = 0x2B; +const uint8_t REG_INT_A = 0x2C; +const uint8_t REG_INT_B = 0x2D; +const uint8_t REG_INT_C = 0x2E; +const uint8_t REG_INT_D = 0x2F; +const uint8_t REG_FIFO_CONFIG_0 = 0x30; +const uint8_t REG_PMU_SELF_TEST = 0x32; +const uint8_t REG_TRIM_NVM_CTRL = 0x33; +const uint8_t REG_BGW_SPI3_WDT = 0x34; +const uint8_t REG_OFC_CTRL = 0x36; +const uint8_t REG_OFC_SETTING = 0x37; +const uint8_t REG_OFC_OFFSET_X = 0x38; +const uint8_t REG_OFC_OFFSET_Y = 0x39; +const uint8_t REG_OFC_OFFSET_Z = 0x3A; +const uint8_t REG_TRIM_GP0 = 0x3B; +const uint8_t REG_TRIM_GP1 = 0x3C; +const uint8_t REG_FIFO_CONFIG_1 = 0x3E; +const uint8_t REG_FIFO_DATA = 0x3F; + struct bmx055_data { - int state; + int16_t accel_x; + int16_t accel_y; + int16_t accel_z; + int16_t gyro_x; + int16_t gyro_y; + int16_t gyro_z; + int8_t temperature; }; struct bmx055_config @@ -29,40 +92,19 @@ struct bmx055_config #endif /* CONFIG_INA230_TRIGGER */ }; -// int bmx055_reg_read(const struct i2c_dt_spec *bus, uint8_t reg, uint8_t *val) -// { -// uint8_t data[2]; -// int ret; - -// ret = i2c_burst_read_dt(bus, reg, data, sizeof(data)); -// if (ret < 0) -// { -// return ret; -// } - -// *val = sys_get_be16(data); - -// return ret; -// } - -// int bmx055_reg_write(const struct i2c_dt_spec *bus, uint8_t reg, uint8_t val) -// { -// uint8_t tx_buf[2]; - -// tx_buf[0] = reg; -// tx_buf[1] = val; - -// return i2c_write_dt(bus, tx_buf, sizeof(tx_buf)); -// } - static int bmx055_sample_fetch(const struct device *dev, enum sensor_channel chan) { - // const struct bmx055_config *config = dev->config; + const struct bmx055_config *config = dev->config; struct bmx055_data *data = dev->data; + int ret; - // data->state = gpio_pin_get_dt(&config->input); - data->state = 0; + ret = i2c_burst_read_dt(&config->bus, REG_ACCD_TEMP, &data->temperature, sizeof(data->temperature)); + if (ret < 0) + { + LOG_ERR("Failed to read temperature register!"); + return ret; + } return 0; } @@ -73,13 +115,17 @@ static int bmx055_channel_get(const struct device *dev, { struct bmx055_data *data = dev->data; - if (chan != SENSOR_CHAN_PROX) + switch (chan) { + case SENSOR_CHAN_DIE_TEMP: + // 0.5K/LSB, center temperature is 23C + val->val1 = 23 + data->temperature / 2; + val->val2 = 0; // TODO: don't throw out LSB + break; + default: return -ENOTSUP; } - val->val1 = data->state; - return 0; } @@ -99,7 +145,6 @@ static int bmx055_init(const struct device *dev) return -ENODEV; } - const uint8_t REG_BWG_CHIPID = 0x00; uint8_t chip_id; ret = i2c_burst_read_dt(&config->bus, REG_BWG_CHIPID, &chip_id, sizeof(chip_id)); if (ret < 0) From da8f165451da33945ae7d72f2c3a2f57a2233d68 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 00:23:01 -0600 Subject: [PATCH 11/22] acceleration isn't quite working yet --- app/src/main.c | 12 ++++- drivers/sensor/bmx055/bmx055.c | 98 +++++++++++++++++++++------------- 2 files changed, 72 insertions(+), 38 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 90540ac..228ec5b 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -118,11 +118,12 @@ int main(void) while (1) { int ret; - struct sensor_value voltage, current, pressure, temperature, humidity; + struct sensor_value voltage, current, pressure, temperature, accel_x, humidity; char str_v[15] = {0}; char str_i[15] = {0}; char str_p[16] = {0}; char str_t[16] = {0}; + char str_ax[16] = {0}; char str_h[16] = {0}; ret = sensor_sample_fetch(ina); @@ -175,6 +176,12 @@ int main(void) LOG_ERR("Could not get temperature (%d)", ret); return 0; } + ret = sensor_channel_get(bmx, SENSOR_CHAN_ACCEL_X, &accel_x); + if (ret < 0) + { + LOG_ERR("Could not get acceleration (%d)", ret); + return 0; + } // ret = sensor_sample_fetch(hdc); // if (ret < 0) @@ -193,6 +200,7 @@ int main(void) sprintf(str_i, "I:%01d.%06d", current.val1, current.val2); sprintf(str_p, "P:%03d.%04d", pressure.val1, pressure.val2 / 100); sprintf(str_t, "T:%03d.%04d", temperature.val1, temperature.val2 / 100); + sprintf(str_ax, "X:%03d.%04d", accel_x.val1, accel_x.val2 / 100); sprintf(str_h, "H:%05d.%06d", humidity.val1, humidity.val2); // printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); @@ -208,7 +216,7 @@ int main(void) printf("Failed to print a string\n"); continue; } - if (cfb_print(dev, str_p, 0, 16 * 2)) + if (cfb_print(dev, str_ax, 0, 16 * 2)) { printf("Failed to print a string\n"); continue; diff --git a/drivers/sensor/bmx055/bmx055.c b/drivers/sensor/bmx055/bmx055.c index 1c18093..24e499c 100644 --- a/drivers/sensor/bmx055/bmx055.c +++ b/drivers/sensor/bmx055/bmx055.c @@ -9,6 +9,7 @@ #include #include #include +#include #include LOG_MODULE_REGISTER(bmx055, CONFIG_SENSOR_LOG_LEVEL); @@ -28,11 +29,30 @@ const uint8_t REG_INT_STATUS_2 = 0x0B; const uint8_t REG_INT_STATUS_3 = 0x0C; const uint8_t REG_FIFO_STATUS = 0x0E; const uint8_t REG_PMU_RANGE = 0x0F; +typedef enum pmu_range_t +{ + PMU_RANGE_2G = 0b0011, ///< DEFAULT + PMU_RANGE_4G = 0b0101, + PMU_RANGE_8G = 0b1000, + PMU_RANGE_16G = 0b1100, +} pmu_range_t; const uint8_t REG_PMU_BW = 0x10; +typedef enum pmu_bw_t +{ + PMU_BW_8HZ = 0b01000, + PMU_BW_16HZ = 0b01001, + PMU_BW_31HZ = 0b01010, + PMU_BW_63HZ = 0b01011, + PMU_BW_125HZ = 0b01100, + PMU_BW_250HZ = 0b01101, + PMU_BW_500HZ = 0b01110, + PMU_BW_1000HZ = 0b01111, +} pmu_bw_t; const uint8_t REG_PMU_LPW = 0x11; const uint8_t REG_PMU_LOW_POWER = 0x12; const uint8_t REG_ACCD_HBW = 0x13; const uint8_t REG_BGW_SOFTRESET = 0x14; +const uint8_t BGW_SOFTRESET = 0xB6; ///< Soft reset occurs when this value is written to REG_BGW_SOFTRESET const uint8_t REG_INT_EN_0 = 0x16; const uint8_t REG_INT_EN_1 = 0x17; const uint8_t REG_INT_EN_2 = 0x18; @@ -99,6 +119,17 @@ static int bmx055_sample_fetch(const struct device *dev, struct bmx055_data *data = dev->data; int ret; + uint8_t accel[6]; + ret = i2c_burst_read_dt(&config->bus, REG_ACCD_X_LSB, accel, sizeof(accel)); + if (ret < 0) + { + LOG_ERR("Failed to read acceleration registers!"); + return ret; + } + data->accel_x = sys_get_be16(&accel[0]) >> 4; + data->accel_y = sys_get_be16(&accel[2]) >> 4; + data->accel_z = sys_get_be16(&accel[4]) >> 4; + ret = i2c_burst_read_dt(&config->bus, REG_ACCD_TEMP, &data->temperature, sizeof(data->temperature)); if (ret < 0) { @@ -122,6 +153,28 @@ static int bmx055_channel_get(const struct device *dev, val->val1 = 23 + data->temperature / 2; val->val2 = 0; // TODO: don't throw out LSB break; + case SENSOR_CHAN_ACCEL_X: + // For now assume 2g since that's the default value + // 2g 0.98mg/LSB + // 4g 1.95mg/LSB + // 8g 3.91mg/LSB + // 16g 7.81mg/LSB + // 1 g = 9.80665 m/s^2 + float accel = data->accel_x * 0.00098 * 9.80665; // to gees, to m/s^2 + val->val1 = accel; + val->val2 = (accel - val->val1) * 1000000; + break; + case SENSOR_CHAN_ACCEL_Y: + case SENSOR_CHAN_ACCEL_Z: + return -ENOTSUP; + case SENSOR_CHAN_GYRO_X: + case SENSOR_CHAN_GYRO_Y: + case SENSOR_CHAN_GYRO_Z: + return -ENOTSUP; + case SENSOR_CHAN_MAGN_X: + case SENSOR_CHAN_MAGN_Y: + case SENSOR_CHAN_MAGN_Z: + return -ENOTSUP; default: return -ENOTSUP; } @@ -158,45 +211,18 @@ static int bmx055_init(const struct device *dev) LOG_ERR("Chip ID read from %s incorrect. Read 0x%02X, expected 0x%02X", dev->name, chip_id, CHIP_ID); } - // ret = ina23x_reg_write(&config->bus, INA230_REG_CONFIG, config->config); - // if (ret < 0) - // { - // LOG_ERR("Failed to write configuration register!"); - // return ret; - // } + // Reset the sensor + uint8_t reset_val = BGW_SOFTRESET; + i2c_burst_write_dt(&config->bus, REG_BGW_SOFTRESET, &reset_val, sizeof(reset_val)); - // ret = ina230_calibrate(dev); - // if (ret < 0) - // { - // LOG_ERR("Failed to write calibration register!"); - // return ret; - // } + // Wait for device to reset - // #ifdef CONFIG_INA230_TRIGGER - // if (config->trig_enabled) - // { - // ret = ina230_trigger_mode_init(dev); - // if (ret < 0) - // { - // LOG_ERR("Failed to init trigger mode\n"); - // return ret; - // } + // Write configuration + uint8_t accel_range = PMU_RANGE_2G; + i2c_burst_write_dt(&config->bus, REG_PMU_RANGE, &accel_range, sizeof(accel_range)); - // ret = ina23x_reg_write(&config->bus, INA230_REG_ALERT, config->alert_limit); - // if (ret < 0) - // { - // LOG_ERR("Failed to write alert register!"); - // return ret; - // } - - // ret = ina23x_reg_write(&config->bus, INA230_REG_MASK, config->mask); - // if (ret < 0) - // { - // LOG_ERR("Failed to write mask register!"); - // return ret; - // } - // } - // #endif /* CONFIG_INA230_TRIGGER */ + uint8_t accel_bw = PMU_BW_8HZ; + i2c_burst_write_dt(&config->bus, REG_PMU_BW, &accel_bw, sizeof(accel_bw)); return 0; } From 7fddc21eee15552abe2f14b0c22dc8444a8b4569 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 00:35:57 -0600 Subject: [PATCH 12/22] add second accelerometer for comparison --- app/src/main.c | 37 +++++++++++++++++---- boards/bh/mellifera_rev1/mellifera_rev1.dts | 6 ++++ drivers/sensor/bmx055/bmx055.c | 8 ++--- 3 files changed, 40 insertions(+), 11 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 228ec5b..1b939ee 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -84,7 +84,7 @@ int main(void) cfb_set_kerning(dev, 3); - const struct device *ina, *bmp, *bmx, *hdc; + const struct device *ina, *bmp, *bmx, *lis, *hdc; ina = DEVICE_DT_GET(DT_NODELABEL(ina231)); if (!device_is_ready(ina)) @@ -108,6 +108,14 @@ int main(void) } LOG_INF("Initialized %s\n", bmx->name); + lis = DEVICE_DT_GET(DT_NODELABEL(lis2dh)); + if (!device_is_ready(lis)) + { + LOG_ERR("Device %s not ready\n", lis->name); + return 0; + } + LOG_INF("Initialized %s\n", lis->name); + // hdc = DEVICE_DT_GET(DT_NODELABEL(hdc1080)); // if (!device_is_ready(dev)) // { @@ -118,12 +126,13 @@ int main(void) while (1) { int ret; - struct sensor_value voltage, current, pressure, temperature, accel_x, humidity; + struct sensor_value voltage, current, pressure, temperature, accel_z, accel_z_ref, humidity; char str_v[15] = {0}; char str_i[15] = {0}; char str_p[16] = {0}; char str_t[16] = {0}; - char str_ax[16] = {0}; + char str_az[16] = {0}; + char str_az_ref[16] = {0}; char str_h[16] = {0}; ret = sensor_sample_fetch(ina); @@ -176,7 +185,20 @@ int main(void) LOG_ERR("Could not get temperature (%d)", ret); return 0; } - ret = sensor_channel_get(bmx, SENSOR_CHAN_ACCEL_X, &accel_x); + ret = sensor_channel_get(bmx, SENSOR_CHAN_ACCEL_Z, &accel_z); + if (ret < 0) + { + LOG_ERR("Could not get acceleration (%d)", ret); + return 0; + } + + ret = sensor_sample_fetch(lis); + if (ret < 0) + { + LOG_ERR("Could not fetch sample (%d)", ret); + return 0; + } + ret = sensor_channel_get(lis, SENSOR_CHAN_ACCEL_Z, &accel_z_ref); if (ret < 0) { LOG_ERR("Could not get acceleration (%d)", ret); @@ -200,7 +222,8 @@ int main(void) sprintf(str_i, "I:%01d.%06d", current.val1, current.val2); sprintf(str_p, "P:%03d.%04d", pressure.val1, pressure.val2 / 100); sprintf(str_t, "T:%03d.%04d", temperature.val1, temperature.val2 / 100); - sprintf(str_ax, "X:%03d.%04d", accel_x.val1, accel_x.val2 / 100); + sprintf(str_az, "Z:%03d.%04d", accel_z.val1, accel_z.val2 / 100); + sprintf(str_az_ref, "Z:%03d.%04d", accel_z_ref.val1, accel_z_ref.val2 / 100); sprintf(str_h, "H:%05d.%06d", humidity.val1, humidity.val2); // printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); @@ -216,12 +239,12 @@ int main(void) printf("Failed to print a string\n"); continue; } - if (cfb_print(dev, str_ax, 0, 16 * 2)) + if (cfb_print(dev, str_az, 0, 16 * 2)) { printf("Failed to print a string\n"); continue; } - if (cfb_print(dev, str_t, 0, 16 * 3)) + if (cfb_print(dev, str_az_ref, 0, 16 * 3)) { printf("Failed to print a string\n"); continue; diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index 9b967f0..b3f6697 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -173,6 +173,12 @@ compatible = "bosch,bmx055"; reg = <0x18>; }; + + lis2dh: lis2dh@19 { + // This is built into the DWM1001 module + compatible = "st,lis2dh"; + reg = <0x19>; + }; }; &spi1 { diff --git a/drivers/sensor/bmx055/bmx055.c b/drivers/sensor/bmx055/bmx055.c index 24e499c..c4061e3 100644 --- a/drivers/sensor/bmx055/bmx055.c +++ b/drivers/sensor/bmx055/bmx055.c @@ -154,19 +154,19 @@ static int bmx055_channel_get(const struct device *dev, val->val2 = 0; // TODO: don't throw out LSB break; case SENSOR_CHAN_ACCEL_X: + case SENSOR_CHAN_ACCEL_Y: + return -ENOTSUP; + case SENSOR_CHAN_ACCEL_Z: // For now assume 2g since that's the default value // 2g 0.98mg/LSB // 4g 1.95mg/LSB // 8g 3.91mg/LSB // 16g 7.81mg/LSB // 1 g = 9.80665 m/s^2 - float accel = data->accel_x * 0.00098 * 9.80665; // to gees, to m/s^2 + float accel = data->accel_z * 0.00098 * 9.80665; // to gees, to m/s^2 val->val1 = accel; val->val2 = (accel - val->val1) * 1000000; break; - case SENSOR_CHAN_ACCEL_Y: - case SENSOR_CHAN_ACCEL_Z: - return -ENOTSUP; case SENSOR_CHAN_GYRO_X: case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: From ac56bb6ee031c8f2df6455382d26adbfa70617ac Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 00:49:05 -0600 Subject: [PATCH 13/22] floats are nice --- app/prj.conf | 3 ++- app/src/main.c | 38 +++++++++++++++++++------------------- 2 files changed, 21 insertions(+), 20 deletions(-) diff --git a/app/prj.conf b/app/prj.conf index 55461d3..5a9a618 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -15,4 +15,5 @@ CONFIG_DISPLAY=y CONFIG_LOG=y CONFIG_CFB_LOG_LEVEL_DBG=y -CONFIG_CHARACTER_FRAMEBUFFER=y \ No newline at end of file +CONFIG_CHARACTER_FRAMEBUFFER=y +CONFIG_CBPRINTF_FP_SUPPORT=y \ No newline at end of file diff --git a/app/src/main.c b/app/src/main.c index 1b939ee..5b5d644 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -218,37 +218,37 @@ int main(void) // return 0; // } - sprintf(str_v, "V:%01d.%06d", voltage.val1, voltage.val2); - sprintf(str_i, "I:%01d.%06d", current.val1, current.val2); - sprintf(str_p, "P:%03d.%04d", pressure.val1, pressure.val2 / 100); - sprintf(str_t, "T:%03d.%04d", temperature.val1, temperature.val2 / 100); - sprintf(str_az, "Z:%03d.%04d", accel_z.val1, accel_z.val2 / 100); - sprintf(str_az_ref, "Z:%03d.%04d", accel_z_ref.val1, accel_z_ref.val2 / 100); - sprintf(str_h, "H:%05d.%06d", humidity.val1, humidity.val2); + sprintf(str_v, "V :%7.5f", voltage.val1 + voltage.val2 * 1e-6); + sprintf(str_i, "I :%7.5f", current.val1 + current.val2 * 1e-6); + sprintf(str_p, "P :%7.4f", pressure.val1 + pressure.val2 * 1e-6); + sprintf(str_t, "T :%7.4f", temperature.val1 + temperature.val2 * 1e-6); + sprintf(str_az, "Z :%7.4f", accel_z.val1 + accel_z.val2 * 1e-6); + sprintf(str_az_ref, "Zr:%7.4f", accel_z_ref.val1 + accel_z_ref.val2 * 1e-6); + sprintf(str_h, "H :%7.5f", humidity.val1 + humidity.val2 * 1e-6); // printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); cfb_framebuffer_clear(dev, false); - if (cfb_print(dev, str_v, 0, 0)) + if (cfb_print(dev, str_az, 0, 0)) { printf("Failed to print a string\n"); continue; } - if (cfb_print(dev, str_i, 0, 16)) - { - printf("Failed to print a string\n"); - continue; - } - if (cfb_print(dev, str_az, 0, 16 * 2)) - { - printf("Failed to print a string\n"); - continue; - } - if (cfb_print(dev, str_az_ref, 0, 16 * 3)) + if (cfb_print(dev, str_az_ref, 0, 16)) { printf("Failed to print a string\n"); continue; } + // if (cfb_print(dev, str_az, 0, 16 * 2)) + // { + // printf("Failed to print a string\n"); + // continue; + // } + // if (cfb_print(dev, str_az_ref, 0, 16 * 3)) + // { + // printf("Failed to print a string\n"); + // continue; + // } cfb_framebuffer_finalize(dev); #if defined(CONFIG_ARCH_POSIX) From 60a93c378b2f3f1a4d155842c0d81a11f8300893 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 01:14:00 -0600 Subject: [PATCH 14/22] sign extension is a pain --- drivers/sensor/bmx055/bmx055.c | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/drivers/sensor/bmx055/bmx055.c b/drivers/sensor/bmx055/bmx055.c index c4061e3..f821346 100644 --- a/drivers/sensor/bmx055/bmx055.c +++ b/drivers/sensor/bmx055/bmx055.c @@ -126,9 +126,9 @@ static int bmx055_sample_fetch(const struct device *dev, LOG_ERR("Failed to read acceleration registers!"); return ret; } - data->accel_x = sys_get_be16(&accel[0]) >> 4; - data->accel_y = sys_get_be16(&accel[2]) >> 4; - data->accel_z = sys_get_be16(&accel[4]) >> 4; + data->accel_x = ((int16_t)sys_get_le16(&accel[0])) >> 4; + data->accel_y = ((int16_t)sys_get_le16(&accel[2])) >> 4; + data->accel_z = ((int16_t)sys_get_le16(&accel[4])) >> 4; ret = i2c_burst_read_dt(&config->bus, REG_ACCD_TEMP, &data->temperature, sizeof(data->temperature)); if (ret < 0) @@ -211,11 +211,20 @@ static int bmx055_init(const struct device *dev) LOG_ERR("Chip ID read from %s incorrect. Read 0x%02X, expected 0x%02X", dev->name, chip_id, CHIP_ID); } - // Reset the sensor - uint8_t reset_val = BGW_SOFTRESET; - i2c_burst_write_dt(&config->bus, REG_BGW_SOFTRESET, &reset_val, sizeof(reset_val)); + // // Reset the sensor + // uint8_t reset_val = BGW_SOFTRESET; + // i2c_burst_write_dt(&config->bus, REG_BGW_SOFTRESET, &reset_val, sizeof(reset_val)); - // Wait for device to reset + // // Wait for device to reset + + uint8_t lpw; + ret = i2c_burst_read_dt(&config->bus, REG_PMU_LPW, &lpw, sizeof(lpw)); + if (ret < 0) + { + LOG_ERR("Failed to read LPW register!"); + return ret; + } + LOG_INF("LPW register: 0x%02X", lpw); // Write configuration uint8_t accel_range = PMU_RANGE_2G; @@ -224,6 +233,9 @@ static int bmx055_init(const struct device *dev) uint8_t accel_bw = PMU_BW_8HZ; i2c_burst_write_dt(&config->bus, REG_PMU_BW, &accel_bw, sizeof(accel_bw)); + uint8_t hbw = (1 << 7); // data_high_bw (read filtered data) and enable lsb/msb shadowing + i2c_burst_write_dt(&config->bus, REG_ACCD_HBW, &hbw, sizeof(hbw)); + return 0; } From 9fc352115f0d958b1e767dfb3950577e9b874ce9 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 03:03:19 -0600 Subject: [PATCH 15/22] working xyz accel --- app/src/main.c | 36 ++++++++++++++++++++++++---------- drivers/sensor/bmx055/bmx055.c | 15 +++++++++++++- 2 files changed, 40 insertions(+), 11 deletions(-) diff --git a/app/src/main.c b/app/src/main.c index 5b5d644..df7e5cd 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -126,11 +126,13 @@ int main(void) while (1) { int ret; - struct sensor_value voltage, current, pressure, temperature, accel_z, accel_z_ref, humidity; + struct sensor_value voltage, current, pressure, temperature, accel_x, accel_y, accel_z, accel_z_ref, humidity; char str_v[15] = {0}; char str_i[15] = {0}; char str_p[16] = {0}; char str_t[16] = {0}; + char str_ax[16] = {0}; + char str_ay[16] = {0}; char str_az[16] = {0}; char str_az_ref[16] = {0}; char str_h[16] = {0}; @@ -185,6 +187,18 @@ int main(void) LOG_ERR("Could not get temperature (%d)", ret); return 0; } + ret = sensor_channel_get(bmx, SENSOR_CHAN_ACCEL_X, &accel_x); + if (ret < 0) + { + LOG_ERR("Could not get acceleration (%d)", ret); + return 0; + } + ret = sensor_channel_get(bmx, SENSOR_CHAN_ACCEL_Y, &accel_y); + if (ret < 0) + { + LOG_ERR("Could not get acceleration (%d)", ret); + return 0; + } ret = sensor_channel_get(bmx, SENSOR_CHAN_ACCEL_Z, &accel_z); if (ret < 0) { @@ -222,28 +236,30 @@ int main(void) sprintf(str_i, "I :%7.5f", current.val1 + current.val2 * 1e-6); sprintf(str_p, "P :%7.4f", pressure.val1 + pressure.val2 * 1e-6); sprintf(str_t, "T :%7.4f", temperature.val1 + temperature.val2 * 1e-6); - sprintf(str_az, "Z :%7.4f", accel_z.val1 + accel_z.val2 * 1e-6); - sprintf(str_az_ref, "Zr:%7.4f", accel_z_ref.val1 + accel_z_ref.val2 * 1e-6); + sprintf(str_ax, "X :%+7.3f", accel_x.val1 + accel_x.val2 * 1e-6); + sprintf(str_ay, "Y :%+7.3f", accel_y.val1 + accel_y.val2 * 1e-6); + sprintf(str_az, "Z :%+7.3f", accel_z.val1 + accel_z.val2 * 1e-6); + sprintf(str_az_ref, "Zr:%+7.3f", accel_z_ref.val1 + accel_z_ref.val2 * 1e-6); sprintf(str_h, "H :%7.5f", humidity.val1 + humidity.val2 * 1e-6); // printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); cfb_framebuffer_clear(dev, false); - if (cfb_print(dev, str_az, 0, 0)) + if (cfb_print(dev, str_ax, 0, 0)) { printf("Failed to print a string\n"); continue; } - if (cfb_print(dev, str_az_ref, 0, 16)) + if (cfb_print(dev, str_ay, 0, 16)) + { + printf("Failed to print a string\n"); + continue; + } + if (cfb_print(dev, str_az, 0, 16 * 2)) { printf("Failed to print a string\n"); continue; } - // if (cfb_print(dev, str_az, 0, 16 * 2)) - // { - // printf("Failed to print a string\n"); - // continue; - // } // if (cfb_print(dev, str_az_ref, 0, 16 * 3)) // { // printf("Failed to print a string\n"); diff --git a/drivers/sensor/bmx055/bmx055.c b/drivers/sensor/bmx055/bmx055.c index f821346..2ae878f 100644 --- a/drivers/sensor/bmx055/bmx055.c +++ b/drivers/sensor/bmx055/bmx055.c @@ -154,9 +154,21 @@ static int bmx055_channel_get(const struct device *dev, val->val2 = 0; // TODO: don't throw out LSB break; case SENSOR_CHAN_ACCEL_X: + { + float accel = data->accel_x * 0.00098 * 9.80665; // to gees, to m/s^2 + val->val1 = accel; + val->val2 = (accel - val->val1) * 1000000; + break; + } case SENSOR_CHAN_ACCEL_Y: - return -ENOTSUP; + { + float accel = data->accel_y * 0.00098 * 9.80665; // to gees, to m/s^2 + val->val1 = accel; + val->val2 = (accel - val->val1) * 1000000; + break; + } case SENSOR_CHAN_ACCEL_Z: + { // For now assume 2g since that's the default value // 2g 0.98mg/LSB // 4g 1.95mg/LSB @@ -167,6 +179,7 @@ static int bmx055_channel_get(const struct device *dev, val->val1 = accel; val->val2 = (accel - val->val1) * 1000000; break; + } case SENSOR_CHAN_GYRO_X: case SENSOR_CHAN_GYRO_Y: case SENSOR_CHAN_GYRO_Z: From e82df2fec422ce15f551ba03e6d72fec4dc4fe1f Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 04:18:39 -0600 Subject: [PATCH 16/22] first pass at ti hdc1080. Temperature works, humidity doesn't --- app/src/main.c | 56 ++--- boards/bh/mellifera_rev1/mellifera_rev1.dts | 2 +- drivers/sensor/CMakeLists.txt | 1 + drivers/sensor/Kconfig | 1 + drivers/sensor/hdc1080/CMakeLists.txt | 2 + drivers/sensor/hdc1080/Kconfig | 6 + drivers/sensor/hdc1080/hdc1080.c | 227 ++++++++++++++++++++ dts/bindings/sensor/ti,hdc1080.yaml | 7 + 8 files changed, 276 insertions(+), 26 deletions(-) create mode 100644 drivers/sensor/hdc1080/CMakeLists.txt create mode 100644 drivers/sensor/hdc1080/Kconfig create mode 100644 drivers/sensor/hdc1080/hdc1080.c create mode 100644 dts/bindings/sensor/ti,hdc1080.yaml diff --git a/app/src/main.c b/app/src/main.c index df7e5cd..221a545 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -116,12 +116,12 @@ int main(void) } LOG_INF("Initialized %s\n", lis->name); - // hdc = DEVICE_DT_GET(DT_NODELABEL(hdc1080)); - // if (!device_is_ready(dev)) - // { - // printf("Device %s not ready\n", hdc->name); - // return 0; - // } + hdc = DEVICE_DT_GET(DT_NODELABEL(hdc1080)); + if (!device_is_ready(hdc)) + { + printf("Device %s not ready\n", hdc->name); + return 0; + } while (1) { @@ -219,18 +219,24 @@ int main(void) return 0; } - // ret = sensor_sample_fetch(hdc); - // if (ret < 0) - // { - // LOG_ERR("Could not fetch sample (%d)", ret); - // return 0; - // } - // ret = sensor_channel_get(ina, SENSOR_CHAN_HUMIDITY, &humidity); - // if (ret < 0) - // { - // LOG_ERR("Could not get sample (%d)", ret); - // return 0; - // } + ret = sensor_sample_fetch(hdc); + if (ret < 0) + { + LOG_ERR("Could not fetch sample (%d)", ret); + return 0; + } + ret = sensor_channel_get(hdc, SENSOR_CHAN_AMBIENT_TEMP, &temperature); + if (ret < 0) + { + LOG_ERR("Could not get sample (%d)", ret); + return 0; + } + ret = sensor_channel_get(hdc, SENSOR_CHAN_HUMIDITY, &humidity); + if (ret < 0) + { + LOG_ERR("Could not get sample (%d)", ret); + return 0; + } sprintf(str_v, "V :%7.5f", voltage.val1 + voltage.val2 * 1e-6); sprintf(str_i, "I :%7.5f", current.val1 + current.val2 * 1e-6); @@ -245,21 +251,21 @@ int main(void) // printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); cfb_framebuffer_clear(dev, false); - if (cfb_print(dev, str_ax, 0, 0)) + if (cfb_print(dev, str_t, 0, 0)) { printf("Failed to print a string\n"); continue; } - if (cfb_print(dev, str_ay, 0, 16)) - { - printf("Failed to print a string\n"); - continue; - } - if (cfb_print(dev, str_az, 0, 16 * 2)) + if (cfb_print(dev, str_h, 0, 16)) { printf("Failed to print a string\n"); continue; } + // if (cfb_print(dev, str_az, 0, 16 * 2)) + // { + // printf("Failed to print a string\n"); + // continue; + // } // if (cfb_print(dev, str_az_ref, 0, 16 * 3)) // { // printf("Failed to print a string\n"); diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index b3f6697..2bcba69 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -165,7 +165,7 @@ }; hdc1080: hdc1080@40 { - compatible = "ti,hdc20xx"; // FIXME: add proper support for this part. Hopefully these parts are close enough + compatible = "ti,hdc1080"; reg = <0x40>; }; diff --git a/drivers/sensor/CMakeLists.txt b/drivers/sensor/CMakeLists.txt index 1b12c15..dde47f6 100644 --- a/drivers/sensor/CMakeLists.txt +++ b/drivers/sensor/CMakeLists.txt @@ -3,3 +3,4 @@ add_subdirectory_ifdef(CONFIG_EXAMPLE_SENSOR example_sensor) add_subdirectory_ifdef(CONFIG_BMX055 bmx055) +add_subdirectory_ifdef(CONFIG_HDC1080 hdc1080) diff --git a/drivers/sensor/Kconfig b/drivers/sensor/Kconfig index 52e2f51..60499d0 100644 --- a/drivers/sensor/Kconfig +++ b/drivers/sensor/Kconfig @@ -4,4 +4,5 @@ if SENSOR rsource "example_sensor/Kconfig" rsource "bmx055/Kconfig" +rsource "hdc1080/Kconfig" endif # SENSOR diff --git a/drivers/sensor/hdc1080/CMakeLists.txt b/drivers/sensor/hdc1080/CMakeLists.txt new file mode 100644 index 0000000..cafff00 --- /dev/null +++ b/drivers/sensor/hdc1080/CMakeLists.txt @@ -0,0 +1,2 @@ +zephyr_library() +zephyr_library_sources(hdc1080.c) diff --git a/drivers/sensor/hdc1080/Kconfig b/drivers/sensor/hdc1080/Kconfig new file mode 100644 index 0000000..6e337a7 --- /dev/null +++ b/drivers/sensor/hdc1080/Kconfig @@ -0,0 +1,6 @@ +config HDC1080 + bool "HDC1080" + default y + depends on DT_HAS_TI_HDC1080_ENABLED + help + Enable driver for HDC1080. diff --git a/drivers/sensor/hdc1080/hdc1080.c b/drivers/sensor/hdc1080/hdc1080.c new file mode 100644 index 0000000..747ee3c --- /dev/null +++ b/drivers/sensor/hdc1080/hdc1080.c @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2021 Nordic Semiconductor ASA + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT ti_hdc1080 + +#include +#include +#include +#include + +#include +LOG_MODULE_REGISTER(hdc1080, CONFIG_SENSOR_LOG_LEVEL); + +const uint8_t REG_TEMPERATURE = 0x00; +const uint8_t REG_HUMIDITY = 0x01; +const uint8_t REG_CONFIGURATION = 0x02; +const uint8_t REG_SERIAL_ID_0 = 0xFB; +const uint8_t REG_SERIAL_ID_1 = 0xFC; +const uint8_t REG_SERIAL_ID_2 = 0xFD; +const uint8_t REG_MANUFACTURER_ID = 0xFE; +const uint8_t REG_DEVICE_ID = 0xFF; + +#define CONFIG_RST (1 << 15) ///< Software reset. This bit self clears +#define CONFIG_HEAT (1 << 13) ///< Enable heater +#define CONFIG_MODE_SEQUENTIAL (1 << 12) ///< Temperature and humidity measured in sequence, temperature first +#define CONFIG_BTST (1 << 11) ///< 1 = battery voltage < 2.8V +#define CONFIG_TRES_14BIT (0 << 10) ///< Temperature resolution +#define CONFIG_TRES_11BIT (1 << 10) ///< Temperature resolution +#define CONFIG_HRES_14BIT (0b00 << 8) ///< Humidity resolution +#define CONFIG_HRES_11BIT (0b01 << 8) ///< Humidity resolution +#define CONFIG_HRES_8BIT (0b10 << 8) ///< Humidity resolution + +struct hdc1080_data +{ + int16_t temperature; + uint16_t humidity; +}; + +struct hdc1080_config +{ + struct i2c_dt_spec bus; + uint8_t temperature_bits; + uint8_t humidity_bits; +}; + +static int hdc1080_sample_fetch(const struct device *dev, + enum sensor_channel chan) +{ + const struct hdc1080_config *config = dev->config; + struct hdc1080_data *data = dev->data; + int ret; + + // Trigger measurement + uint8_t reg_addr = REG_TEMPERATURE; + i2c_write_dt(&config->bus, ®_addr, 1); + + // Wait for conversion + float temperature_conversion_time; ///< microseconds + switch (config->temperature_bits) + { + case 11: + temperature_conversion_time = 3650; + break; + case 14: + temperature_conversion_time = 6350; + break; + default: + temperature_conversion_time = 0; + break; + } + float humidity_conversion_time; ///< microseconds + switch (config->humidity_bits) + { + case 8: + humidity_conversion_time = 2500; + break; + case 11: + humidity_conversion_time = 3850; + break; + case 14: + humidity_conversion_time = 6500; + break; + default: + humidity_conversion_time = 0; + break; + } + k_busy_wait(temperature_conversion_time + humidity_conversion_time); + + // Read data + uint8_t rdata[4]; + ret = i2c_read_dt(&config->bus, rdata, sizeof(rdata)); + if (ret < 0) + { + LOG_ERR("Failed to read temperature and humidity!"); + return ret; + } + data->temperature = sys_get_be16(&rdata[0]); + data->humidity = sys_get_be16(&rdata[2]); + + return 0; +} + +static int hdc1080_channel_get(const struct device *dev, + enum sensor_channel chan, + struct sensor_value *val) +{ + struct hdc1080_data *data = dev->data; + + switch (chan) + { + case SENSOR_CHAN_AMBIENT_TEMP: + { + double temperature = data->temperature * 160.0 / (1 << 16) - 40; + val->val1 = temperature; + val->val2 = (temperature - val->val1) * 1e6; + break; + } + case SENSOR_CHAN_HUMIDITY: + { + double humidity = data->humidity * 100.0 / (1 << 16); + val->val1 = humidity; + val->val2 = (humidity - val->val1) * 1e6; + break; + } + default: + return -ENOTSUP; + } + + return 0; +} + +static const struct sensor_driver_api hdc1080_api = { + .sample_fetch = &hdc1080_sample_fetch, + .channel_get = &hdc1080_channel_get, +}; + +static int hdc1080_init(const struct device *dev) +{ + const struct hdc1080_config *const config = dev->config; + int ret; + + if (!device_is_ready(config->bus.bus)) + { + LOG_ERR("I2C bus %s is not ready", config->bus.bus->name); + return -ENODEV; + } + + uint8_t id[2]; + ret = i2c_burst_read_dt(&config->bus, REG_MANUFACTURER_ID, id, sizeof(id)); + if (ret < 0) + { + LOG_ERR("Failed to read manufacturer/device ID registers"); + return ret; + } + uint16_t manufacturer_id = sys_get_be16(&id[0]); + const uint16_t MANUFACTURER_ID = 0x5449; + if (manufacturer_id != MANUFACTURER_ID) + { + LOG_ERR("Manufacturer ID read from %s incorrect. Read 0x%02X, expected 0x%02X", dev->name, manufacturer_id, MANUFACTURER_ID); + } + + ret = i2c_burst_read_dt(&config->bus, REG_DEVICE_ID, id, sizeof(id)); + if (ret < 0) + { + LOG_ERR("Failed to read manufacturer/device ID registers"); + return ret; + } + uint16_t device_id = sys_get_be16(&id[2]); + const uint16_t DEVICE_ID = 0x1050; + if (device_id != DEVICE_ID) + { + LOG_ERR("Device ID read from %s incorrect. Read 0x%02X, expected 0x%02X", dev->name, device_id, DEVICE_ID); + } + + // Write configuration + uint16_t cfg = 0; + switch (config->temperature_bits) + { + case 14: + cfg |= CONFIG_TRES_14BIT; + break; + case 11: + cfg |= CONFIG_TRES_11BIT; + break; + default: + LOG_ERR("Invalid temperature resolution: %d bits", config->temperature_bits); + return -1; + } + switch (config->humidity_bits) + { + case 14: + cfg |= CONFIG_HRES_14BIT; + break; + case 11: + cfg |= CONFIG_HRES_11BIT; + break; + case 8: + cfg |= CONFIG_HRES_8BIT; + break; + default: + LOG_ERR("Invalid humidity resolution: %d bits", config->humidity_bits); + return -1; + } + uint8_t wdata[2]; + sys_put_be16(cfg, wdata); + i2c_burst_write_dt(&config->bus, REG_CONFIGURATION, wdata, sizeof(wdata)); + + return 0; +} + +#define HDC1080_INIT(i) \ + static struct hdc1080_data hdc1080_data_##i; \ + \ + static const struct hdc1080_config hdc1080_config_##i = { \ + .bus = I2C_DT_SPEC_INST_GET(i), \ + .temperature_bits = 14, \ + .humidity_bits = 14, \ + }; \ + \ + SENSOR_DEVICE_DT_INST_DEFINE(i, &hdc1080_init, NULL, \ + &hdc1080_data_##i, \ + &hdc1080_config_##i, POST_KERNEL, \ + CONFIG_SENSOR_INIT_PRIORITY, &hdc1080_api); + +DT_INST_FOREACH_STATUS_OKAY(HDC1080_INIT) diff --git a/dts/bindings/sensor/ti,hdc1080.yaml b/dts/bindings/sensor/ti,hdc1080.yaml new file mode 100644 index 0000000..c3ee95b --- /dev/null +++ b/dts/bindings/sensor/ti,hdc1080.yaml @@ -0,0 +1,7 @@ +description: | + TODO: add a description + +compatible: "ti,hdc1080" + +include: [sensor-device.yaml, i2c-device.yaml] + From 95e4bb5cc2ecb6d21ccc168aca9f6e5829db414b Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 23:23:24 -0600 Subject: [PATCH 17/22] indexing issue --- drivers/sensor/hdc1080/hdc1080.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/sensor/hdc1080/hdc1080.c b/drivers/sensor/hdc1080/hdc1080.c index 747ee3c..aaa9557 100644 --- a/drivers/sensor/hdc1080/hdc1080.c +++ b/drivers/sensor/hdc1080/hdc1080.c @@ -167,7 +167,7 @@ static int hdc1080_init(const struct device *dev) LOG_ERR("Failed to read manufacturer/device ID registers"); return ret; } - uint16_t device_id = sys_get_be16(&id[2]); + uint16_t device_id = sys_get_be16(&id[0]); const uint16_t DEVICE_ID = 0x1050; if (device_id != DEVICE_ID) { From f9302615fd2bd7a45c1c9173dd1fd63369d0bd29 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Sun, 28 Apr 2024 23:23:38 -0600 Subject: [PATCH 18/22] add bluetooth support --- app/prj.conf | 5 +- app/src/main.c | 97 ++++++++++++++++++--- boards/bh/mellifera_rev1/mellifera_rev1.dts | 26 ++++++ 3 files changed, 116 insertions(+), 12 deletions(-) diff --git a/app/prj.conf b/app/prj.conf index 5a9a618..39523c0 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -16,4 +16,7 @@ CONFIG_LOG=y CONFIG_CFB_LOG_LEVEL_DBG=y CONFIG_CHARACTER_FRAMEBUFFER=y -CONFIG_CBPRINTF_FP_SUPPORT=y \ No newline at end of file +CONFIG_CBPRINTF_FP_SUPPORT=y + +CONFIG_BT=y +CONFIG_BT_DEVICE_NAME="Mellifera" \ No newline at end of file diff --git a/app/src/main.c b/app/src/main.c index 221a545..14753cd 100644 --- a/app/src/main.c +++ b/app/src/main.c @@ -12,11 +12,75 @@ #include +#include +#include + LOG_MODULE_REGISTER(main, CONFIG_APP_LOG_LEVEL); #define BLINK_PERIOD_MS_STEP 100U #define BLINK_PERIOD_MS_MAX 1000U +#define DEVICE_NAME CONFIG_BT_DEVICE_NAME +#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1) + +/* + * Set Advertisement data. Based on the Eddystone specification: + * https://github.com/google/eddystone/blob/master/protocol-specification.md + * https://github.com/google/eddystone/tree/master/eddystone-url + */ +static const struct bt_data ad[] = { + BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR), + BT_DATA_BYTES(BT_DATA_UUID16_ALL, 0xaa, 0xfe), + BT_DATA_BYTES(BT_DATA_SVC_DATA16, + 0xaa, 0xfe, /* Eddystone UUID */ + 0x10, /* Eddystone-URL frame type */ + 0x00, /* Calibrated Tx power at 0m */ + 0x00, /* URL Scheme Prefix http://www. */ + 'z', 'e', 'p', 'h', 'y', 'r', + 'p', 'r', 'o', 'j', 'e', 'c', 't', + 0x08) /* .org */ +}; + +/* Set Scan Response data */ +static const struct bt_data sd[] = { + BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN), +}; + +static void bt_ready(int err) +{ + char addr_s[BT_ADDR_LE_STR_LEN]; + bt_addr_le_t addr = {0}; + size_t count = 1; + + if (err) + { + LOG_ERR("Bluetooth init failed (err %d)", err); + return; + } + + LOG_INF("Bluetooth initialized"); + + /* Start advertising */ + err = bt_le_adv_start(BT_LE_ADV_NCONN_IDENTITY, ad, ARRAY_SIZE(ad), + sd, ARRAY_SIZE(sd)); + if (err) + { + LOG_ERR("Advertising failed to start (err %d)", err); + return; + } + + /* For connectable advertising you would use + * bt_le_oob_get_local(). For non-connectable non-identity + * advertising an non-resolvable private address is used; + * there is no API to retrieve that. + */ + + bt_id_get(&addr, &count); + bt_addr_le_to_str(&addr, addr_s, sizeof(addr_s)); + + LOG_INF("Beacon started, advertising as %s", addr_s); +} + int main(void) { const struct device *dev; @@ -27,13 +91,24 @@ int main(void) uint8_t font_width; uint8_t font_height; + int err; + printk("Starting Mellifera version %s...\n", APP_VERSION_STRING); // printk("Board: %s\n", BOARD); + LOG_INF("Starting Beacon Demo"); + + /* Initialize the Bluetooth Subsystem */ + err = bt_enable(bt_ready); + if (err) + { + LOG_ERR("Bluetooth init failed (err %d)", err); + } + dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); if (!device_is_ready(dev)) { - LOG_ERR("Device %s not ready\n", dev->name); + LOG_ERR("Device %s not ready", dev->name); return 0; } @@ -46,11 +121,11 @@ int main(void) } } - LOG_INF("Initialized %s\n", dev->name); + LOG_INF("Initialized %s", dev->name); if (cfb_framebuffer_init(dev)) { - LOG_ERR("Framebuffer initialization failed!\n"); + LOG_ERR("Framebuffer initialization failed!"); return 0; } @@ -89,37 +164,37 @@ int main(void) ina = DEVICE_DT_GET(DT_NODELABEL(ina231)); if (!device_is_ready(ina)) { - LOG_ERR("Device %s not ready\n", ina->name); + LOG_ERR("Device %s not ready", ina->name); return 0; } bmp = DEVICE_DT_GET(DT_NODELABEL(bmp388)); if (!device_is_ready(bmp)) { - LOG_ERR("Device %s not ready\n", bmp->name); + LOG_ERR("Device %s not ready", bmp->name); return 0; } bmx = DEVICE_DT_GET(DT_NODELABEL(bmx055)); if (!device_is_ready(bmx)) { - LOG_ERR("Device %s not ready\n", bmx->name); + LOG_ERR("Device %s not ready", bmx->name); return 0; } - LOG_INF("Initialized %s\n", bmx->name); + LOG_INF("Initialized %s", bmx->name); lis = DEVICE_DT_GET(DT_NODELABEL(lis2dh)); if (!device_is_ready(lis)) { - LOG_ERR("Device %s not ready\n", lis->name); + LOG_ERR("Device %s not ready", lis->name); return 0; } - LOG_INF("Initialized %s\n", lis->name); + LOG_INF("Initialized %s", lis->name); hdc = DEVICE_DT_GET(DT_NODELABEL(hdc1080)); if (!device_is_ready(hdc)) { - printf("Device %s not ready\n", hdc->name); + LOG_ERR("Device %s not ready", hdc->name); return 0; } @@ -246,7 +321,7 @@ int main(void) sprintf(str_ay, "Y :%+7.3f", accel_y.val1 + accel_y.val2 * 1e-6); sprintf(str_az, "Z :%+7.3f", accel_z.val1 + accel_z.val2 * 1e-6); sprintf(str_az_ref, "Zr:%+7.3f", accel_z_ref.val1 + accel_z_ref.val2 * 1e-6); - sprintf(str_h, "H :%7.5f", humidity.val1 + humidity.val2 * 1e-6); + sprintf(str_h, "H :%7.3f", humidity.val1 + humidity.val2 * 1e-6); // printf("%s\t%s\t%s\t%s\n", str_v, str_i, str_p, str_t); diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index 2bcba69..1561f7b 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -188,3 +188,29 @@ pinctrl-1 = <&spi1_sleep>; pinctrl-names = "default", "sleep"; }; + +&flash0 { + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + boot_partition: partition@0 { + label = "mcuboot"; + reg = <0x00000000 0xc000>; + }; + slot0_partition: partition@c000 { + label = "image-0"; + reg = <0x0000C000 0x37000>; + }; + slot1_partition: partition@43000 { + label = "image-1"; + reg = <0x00043000 0x37000>; + }; + storage_partition: partition@7a000 { + label = "storage"; + reg = <0x0007a000 0x00006000>; + }; + }; +}; From 847c2f5b5e25f0463e82d850e9ac269a0e2ff0e7 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Mon, 29 Apr 2024 23:25:33 -0600 Subject: [PATCH 19/22] mcuboot builds with `west build -p -b mellifera_rev1 ../mcuboot/boot/zephyr/ -- -DCONF_FILE=$(pwd)/boot.conf ` --- app/prj.conf | 5 ++++- boot.conf | 40 ++++++++++++++++++++++++++++++++++++++++ west.yml | 6 ++++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 boot.conf diff --git a/app/prj.conf b/app/prj.conf index 39523c0..f87ca25 100644 --- a/app/prj.conf +++ b/app/prj.conf @@ -19,4 +19,7 @@ CONFIG_CHARACTER_FRAMEBUFFER=y CONFIG_CBPRINTF_FP_SUPPORT=y CONFIG_BT=y -CONFIG_BT_DEVICE_NAME="Mellifera" \ No newline at end of file +CONFIG_BT_DEVICE_NAME="Mellifera" + +CONFIG_BOOTLOADER_MCUBOOT=y +CONFIG_MCUBOOT_GENERATE_UNSIGNED_IMAGE=y \ No newline at end of file diff --git a/boot.conf b/boot.conf new file mode 100644 index 0000000..bdabedb --- /dev/null +++ b/boot.conf @@ -0,0 +1,40 @@ +CONFIG_PM=n + +CONFIG_BOOT_SIGNATURE_TYPE_NONE=y + +CONFIG_MAIN_STACK_SIZE=10240 +# CONFIG_MBEDTLS_CFG_FILE="mcuboot-mbedtls-cfg.h" + +CONFIG_BOOT_SWAP_SAVE_ENCTLV=n +CONFIG_BOOT_ENCRYPT_IMAGE=n + +CONFIG_BOOT_UPGRADE_ONLY=n +CONFIG_BOOT_BOOTSTRAP=n + +### mbedTLS has its own heap +# CONFIG_HEAP_MEM_POOL_SIZE is not set + +### We never want Zephyr's copy of tinycrypt. If tinycrypt is needed, +### MCUboot has its own copy in tree. +# CONFIG_TINYCRYPT is not set +# CONFIG_TINYCRYPT_ECC_DSA is not set +# CONFIG_TINYCRYPT_SHA256 is not set + +CONFIG_FLASH=y + +### Various Zephyr boards enable features that we don't want. +# CONFIG_BT is not set +# CONFIG_BT_CTLR is not set +# CONFIG_I2C is not set + +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y # former CONFIG_MODE_MINIMAL +### Ensure Zephyr logging changes don't use more resources +CONFIG_LOG_DEFAULT_LEVEL=0 +### Use info log level by default +CONFIG_MCUBOOT_LOG_LEVEL_INF=y +### Decrease footprint by ~4 KB in comparison to CBPRINTF_COMPLETE=y +CONFIG_CBPRINTF_NANO=y +### Use the minimal C library to reduce flash usage +CONFIG_MINIMAL_LIBC=y + diff --git a/west.yml b/west.yml index 6bb551c..b80894a 100644 --- a/west.yml +++ b/west.yml @@ -8,11 +8,14 @@ manifest: remotes: - name: zephyrproject-rtos url-base: https://github.com/zephyrproject-rtos + - name: mcu-tools + url-base: https://github.com/mcu-tools projects: - name: zephyr remote: zephyrproject-rtos revision: main + # revision: v3.6.0 import: # By using name-allowlist we can clone only the modules that are # strictly needed by the application. @@ -20,3 +23,6 @@ manifest: - cmsis # required by the ARM port - hal_nordic # required by the custom_plank board (Nordic based) - hal_stm32 # required by the nucleo_f302r8 board (STM32 based) + - name: mcuboot + remote: mcu-tools + revision: v2.0.0 From 231c781787b01d6fdd3dde4d6ae9403ed0f97054 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Mon, 29 Apr 2024 23:55:18 -0600 Subject: [PATCH 20/22] mcuboot responded --- boot.conf | 3 +++ west.yml | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/boot.conf b/boot.conf index bdabedb..284435c 100644 --- a/boot.conf +++ b/boot.conf @@ -38,3 +38,6 @@ CONFIG_CBPRINTF_NANO=y ### Use the minimal C library to reduce flash usage CONFIG_MINIMAL_LIBC=y + +CONFIG_UART_CONSOLE=n +CONFIG_MCUBOOT_SERIAL=y diff --git a/west.yml b/west.yml index b80894a..13c8dbe 100644 --- a/west.yml +++ b/west.yml @@ -23,6 +23,7 @@ manifest: - cmsis # required by the ARM port - hal_nordic # required by the custom_plank board (Nordic based) - hal_stm32 # required by the nucleo_f302r8 board (STM32 based) + - zcbor # required by mcuboot serial - name: mcuboot remote: mcu-tools - revision: v2.0.0 + revision: main From 91caca175fd0ea5e1f967bbe25efe9c95b877ff5 Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 30 Apr 2024 00:32:46 -0600 Subject: [PATCH 21/22] working bootloader --- boards/bh/mellifera_rev1/mellifera_rev1.dts | 31 ++++++++++++++++--- .../mellifera_rev1/mellifera_rev1_defconfig | 20 +++++++----- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/boards/bh/mellifera_rev1/mellifera_rev1.dts b/boards/bh/mellifera_rev1/mellifera_rev1.dts index 1561f7b..5ba820e 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1.dts +++ b/boards/bh/mellifera_rev1/mellifera_rev1.dts @@ -13,13 +13,14 @@ chosen { zephyr,console = &uart0; - // zephyr,shell-uart = &uart0; - // zephyr,uart-mcumgr = &uart0; - // zephyr,bt-mon-uart = &uart0; - // zephyr,bt-c2h-uart = &uart0; + zephyr,shell-uart = &uart0; + zephyr,uart-mcumgr = &uart0; + zephyr,bt-mon-uart = &uart0; + zephyr,bt-c2h-uart = &uart0; zephyr,sram = &sram0; zephyr,flash = &flash0; zephyr,display = &ssd1306; + zephyr,code-partition = &slot0_partition; }; example_sensor: example-sensor { @@ -65,6 +66,11 @@ buttons { compatible = "gpio-keys"; + button0: button_0 { + gpios = <&gpio0 2 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; + label = "Pushbutton"; + zephyr,code = ; + }; int_drdy: int_drdy { gpios = <&gpio0 22 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>; label = "DRDYM from BMX055 9-DOF"; @@ -103,6 +109,23 @@ led-gpios = <&gpio0 15 GPIO_ACTIVE_HIGH>; blink-period-ms = <1000>; }; + + /* These aliases are provided for compatibility with samples */ + aliases { + led0 = &led0; + led1 = &led1; + led2 = &led2; + led3 = &led3; + // pwm-led0 = &pwm_led0; + sw0 = &button0; + // sw1 = &button1; + // sw2 = &button2; + // sw3 = &button3; + bootloader-led0 = &led0; + mcuboot-button0 = &button0; + mcuboot-led0 = &led0; + watchdog0 = &wdt0; + }; }; &uicr { diff --git a/boards/bh/mellifera_rev1/mellifera_rev1_defconfig b/boards/bh/mellifera_rev1/mellifera_rev1_defconfig index 2c54281..8728c1c 100644 --- a/boards/bh/mellifera_rev1/mellifera_rev1_defconfig +++ b/boards/bh/mellifera_rev1/mellifera_rev1_defconfig @@ -1,15 +1,19 @@ -# Copyright (c) 2021 Nordic Semiconductor ASA -# SPDX-License-Identifier: Apache-2.0 +# Enable MPU CONFIG_ARM_MPU=y + +# Enable hardware stack protection CONFIG_HW_STACK_PROTECTION=y -# Enable UART console on all configurations for convenience. This is usually -# done at board level upstream so that all samples output printed messages to -# the configured #zephyr,console. In production boards, this may be enabled at -# application level or in a debug configuration overlay. +# Enable RTT +CONFIG_USE_SEGGER_RTT=y + +# enable GPIO +CONFIG_GPIO=y + +# enable uart driver CONFIG_SERIAL=y + +# enable console CONFIG_CONSOLE=y CONFIG_UART_CONSOLE=y - -CONFIG_PINCTRL=y From f3510b1bcbcececcaf53004eb3e5ee21d250d44b Mon Sep 17 00:00:00 2001 From: Brendan Haines Date: Tue, 30 Apr 2024 00:33:08 -0600 Subject: [PATCH 22/22] gut readme --- README.md | 85 +++++++++++++++++-------------------------------------- 1 file changed, 26 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 9e92396..cb3004d 100644 --- a/README.md +++ b/README.md @@ -1,51 +1,7 @@ # Zephyr Example Application - - Documentation - - - API Documentation - - -This repository contains a Zephyr example application. The main purpose of this -repository is to serve as a reference on how to structure Zephyr-based -applications. Some of the features demonstrated in this example are: - -- Basic [Zephyr application][app_dev] skeleton -- [Zephyr workspace applications][workspace_app] -- [Zephyr modules][modules] -- [West T2 topology][west_t2] -- [Custom boards][board_porting] -- Custom [devicetree bindings][bindings] -- Out-of-tree [drivers][drivers] -- Out-of-tree libraries -- Example CI configuration (using Github Actions) -- Custom [west extension][west_ext] -- Doxygen and Sphinx documentation boilerplate - -This repository is versioned together with the [Zephyr main tree][zephyr]. This -means that every time that Zephyr is tagged, this repository is tagged as well -with the same version number, and the [manifest](west.yml) entry for `zephyr` -will point to the corresponding Zephyr tag. For example, the `example-application` -v2.6.0 will point to Zephyr v2.6.0. Note that the `main` branch always -points to the development branch of Zephyr, also `main`. - -[app_dev]: https://docs.zephyrproject.org/latest/develop/application/index.html -[workspace_app]: https://docs.zephyrproject.org/latest/develop/application/index.html#zephyr-workspace-app -[modules]: https://docs.zephyrproject.org/latest/develop/modules.html -[west_t2]: https://docs.zephyrproject.org/latest/develop/west/workspaces.html#west-t2 -[board_porting]: https://docs.zephyrproject.org/latest/guides/porting/board_porting.html -[bindings]: https://docs.zephyrproject.org/latest/guides/dts/bindings.html -[drivers]: https://docs.zephyrproject.org/latest/reference/drivers/index.html -[zephyr]: https://github.com/zephyrproject-rtos/zephyr -[west_ext]: https://docs.zephyrproject.org/latest/develop/west/extensions.html - ## Getting Started -Before getting started, make sure you have a proper Zephyr development -environment. Follow the official -[Zephyr Getting Started Guide](https://docs.zephyrproject.org/latest/getting_started/index.html). - ### Initialization The first step is to initialize the workspace folder (``my-workspace``) where @@ -65,21 +21,8 @@ west update To build the application, run the following command: ```shell -cd example-application -west build -b $BOARD app -``` - -where `$BOARD` is the target board. - -You can use the `custom_plank` board found in this -repository. Note that Zephyr sample boards may be used if an -appropriate overlay is provided (see `app/boards`). - -A sample debug configuration is also provided. To apply it, run the following -command: - -```shell -west build -b $BOARD app -- -DOVERLAY_CONFIG=debug.conf +cd mellifera_firmware +west build -b mellifera_rev1 app ``` Once you have built the application, run the following command to flash it: @@ -88,6 +31,30 @@ Once you have built the application, run the following command to flash it: west flash ``` +```shell +go install github.com/apache/mynewt-mcumgr-cli/mcumgr@latest +``` + +### Bootloader +```shell +# build and flash the bootloader +west build -p -b mellifera_rev1 ../mcuboot/boot/zephyr/ -- -DCONF_FILE=$(pwd)/boot.conf +west flash + +# define serial connection to device +~/go/bin/mcumgr conn add acm0 type="serial" connstring="dev=/dev/ttyACM0,baud=115200,mtu=512" +~/go/bin/mcumgr conn add ttyusb0 type="serial" connstring="dev=/dev/ttyUSB0,baud=115200,mtu=512" + +# hold button while power cycling to enter bootloading mode +~/go/bin/mcumgr -c usbtty0 image list + +# build the app +west build -p -b mellifera_rev1 app + +~/go/bin/mcumgr -c ttyusb0 image upload -e build/zephyr/zephyr.signed.bin +~/go/bin/mcumgr -c usbtty0 image list +``` + ### Testing To execute Twister integration tests, run the following command: