blob: 26c8ceb638b313656a1187b0c44f22edfcd64b51 [file] [log] [blame]
/*
* Copyright (c) 2021 Titouan Christophe
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/drivers/gpio.h>
#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)),
DEVICE_DT_GET(DT_NODELABEL(vl53l0x_c)),
DEVICE_DT_GET(DT_NODELABEL(vl53l0x_r)),
};
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;
}
}
void 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 (!device_is_ready(button.port)) {
printk("Error: button device %s is not ready\n",
button.port->name);
return;
}
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]();
}
}