/* * Copyright (c) 2021 Titouan Christophe * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include "display_7seg.h" /* * Get button configuration from the devicetree sw0 alias. This is mandatory. */ #define SW0_NODE DT_ALIAS(sw0) #if !DT_NODE_HAS_STATUS(SW0_NODE, okay) #error "Unsupported board: sw0 devicetree alias is not defined" #endif #define N_MODES ARRAY_SIZE(modes) #define N_SENSORS ARRAY_SIZE(sensors) #define LEFT sensors[0] #define CENTER sensors[1] #define RIGHT sensors[2] typedef void (*fsm_state)(void); static int64_t last_mode_change; static const struct device *const sensors[] = { DEVICE_DT_GET(DT_NODELABEL(vl53l0x_l_x_nucleo_53l0a1)), DEVICE_DT_GET(DT_NODELABEL(vl53l0x_c_x_nucleo_53l0a1)), DEVICE_DT_GET(DT_NODELABEL(vl53l0x_r_x_nucleo_53l0a1)), }; static void mode_show_distance(void) { int ret; double distance; struct sensor_value value; ret = sensor_sample_fetch(CENTER); if (ret) { printk("sensor_sample_fetch(%s) failed -> %d\n", CENTER->name, ret); display_chars(TEXT_Err); return; } ret = sensor_channel_get(CENTER, SENSOR_CHAN_DISTANCE, &value); if (ret) { printk("sensor_channel_get(%s) failed -> %d\n", CENTER->name, ret); display_chars(TEXT_Err); return; } distance = sensor_value_to_double(&value); if (distance < 1.25) { display_number(100 * distance, 10); } else { display_chars(DISPLAY_OFF); } } static void mode_show_presence(void) { int i, ret; struct sensor_value value; uint8_t text[4] = { CHAR_OFF, CHAR_OFF, CHAR_OFF, CHAR_OFF }; for (i = 0; i < N_SENSORS; i++) { ret = sensor_sample_fetch(sensors[i]); if (ret) { printk("sensor_sample_fetch(%s) failed -> %d\n", sensors[i]->name, ret); display_chars(TEXT_Err); return; } ret = sensor_channel_get(sensors[i], SENSOR_CHAN_PROX, &value); if (ret) { printk("sensor_channel_get(%s) failed -> %d\n", sensors[i]->name, ret); display_chars(TEXT_Err); return; } if (value.val1) { text[i] = CHAR_UNDERSCORE | CHAR_DASH | CHAR_OVERLINE; } } display_chars(text); } static size_t current_mode; static fsm_state modes[] = { mode_show_distance, mode_show_presence, }; static void change_mode(const struct device *dev, struct gpio_callback *cb, uint32_t pins) { (void) dev; (void) cb; (void) pins; int64_t now = k_uptime_get(); if (now - last_mode_change > 300) { current_mode = (current_mode + 1) % N_MODES; last_mode_change = now; } } int main(void) { struct gpio_callback button_cb_data; const uint8_t Hello[4] = { CHAR_H, CHAR_E, CHAR_PIPE | CHAR_1, CHAR_0 }; const struct gpio_dt_spec button = GPIO_DT_SPEC_GET(SW0_NODE, gpios); display_chars(Hello); k_sleep(K_MSEC(1000)); if (!gpio_is_ready_dt(&button)) { printk("Error: button device %s is not ready\n", button.port->name); return 0; } gpio_pin_configure_dt(&button, GPIO_INPUT); gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_RISING); gpio_init_callback(&button_cb_data, change_mode, BIT(button.pin)); gpio_add_callback(button.port, &button_cb_data); while (1) { modes[current_mode](); } return 0; }