Third
This commit is contained in:
@@ -1,49 +0,0 @@
|
|||||||
#include "buttons.hpp"
|
|
||||||
#include <zephyr/kernel.h>
|
|
||||||
#include <zephyr/device.h>
|
|
||||||
#include <zephyr/logging/log.h>
|
|
||||||
|
|
||||||
LOG_MODULE_REGISTER(buttons, CONFIG_LOG_MAX_LEVEL);
|
|
||||||
K_WORK_DELAYABLE_DEFINE(debounce_work_btn, Buttons::debounce_cb);
|
|
||||||
#define DEBOUNCE_TIME_MS 100
|
|
||||||
|
|
||||||
static const struct gpio_dt_spec Buttons::buttons[Buttons::NR_BUTTONS] = {
|
|
||||||
GPIO_DT_SPEC_GET_OR(DT_ALIAS(int_btn_1), gpios, {0}),
|
|
||||||
GPIO_DT_SPEC_GET_OR(DT_ALIAS(int_btn_2), gpios, {0})
|
|
||||||
};
|
|
||||||
static struct gpio_callback Buttons::buttons_cb_data[Buttons::NR_BUTTONS];
|
|
||||||
|
|
||||||
Buttons::Buttons() {
|
|
||||||
buttons_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
int Buttons::buttons_init() {
|
|
||||||
// BUTTON 1
|
|
||||||
gpio_pin_configure_dt(&buttons[BUTTON1], GPIO_INPUT);
|
|
||||||
gpio_pin_interrupt_configure_dt(&(buttons[BUTTON1]), GPIO_INT_EDGE_TO_ACTIVE);
|
|
||||||
gpio_init_callback(&buttons_cb_data[0], buttons_cb, BIT(buttons[BUTTON1].pin));
|
|
||||||
gpio_add_callback(buttons[BUTTON1].port, &buttons_cb_data[0]);
|
|
||||||
|
|
||||||
// BUTTON 2
|
|
||||||
gpio_pin_configure_dt(&buttons[BUTTON2], GPIO_INPUT);
|
|
||||||
gpio_pin_interrupt_configure_dt(&buttons[BUTTON2], GPIO_INT_EDGE_TO_ACTIVE);
|
|
||||||
gpio_init_callback(&buttons_cb_data[1], buttons_cb, BIT(buttons[BUTTON2].pin));
|
|
||||||
gpio_add_callback(buttons[BUTTON2].port, &buttons_cb_data[1]);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Buttons::debounce_cb(struct k_work *work) {
|
|
||||||
if ( gpio_pin_get_dt(&buttons[BUTTON1]) == GPIO_ACTIVE_HIGH ||
|
|
||||||
gpio_pin_get_dt(&buttons[BUTTON2]) == GPIO_ACTIVE_HIGH) {
|
|
||||||
LOG_DBG("Callback");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void Buttons::buttons_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
|
|
||||||
LOG_DBG("Button:");
|
|
||||||
if (k_work_delayable_is_pending(&debounce_work_btn)) {
|
|
||||||
} else {
|
|
||||||
k_work_schedule(&debounce_work_btn, K_MSEC(DEBOUNCE_TIME_MS));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
#include <zephyr/drivers/gpio.h>
|
|
||||||
|
|
||||||
|
|
||||||
class Buttons {
|
|
||||||
public:
|
|
||||||
|
|
||||||
enum Buttons_e {
|
|
||||||
BUTTON1,
|
|
||||||
BUTTON2,
|
|
||||||
NR_BUTTONS,
|
|
||||||
};
|
|
||||||
|
|
||||||
Buttons();
|
|
||||||
~Buttons();
|
|
||||||
int buttons_init();
|
|
||||||
static void buttons_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins);
|
|
||||||
static void debounce_cb(struct k_work *work);
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const struct gpio_dt_spec buttons[NR_BUTTONS];
|
|
||||||
static struct gpio_callback buttons_cb_data[NR_BUTTONS];
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#include "buttons.h"
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/device.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(buttons, CONFIG_LOG_MAX_LEVEL);
|
||||||
|
K_WORK_DELAYABLE_DEFINE(debounce_work_btn, debounce_cb);
|
||||||
|
#define DEBOUNCE_TIME_MS 100
|
||||||
|
|
||||||
|
static const struct gpio_dt_spec buttons[NR_BUTTONS] = {
|
||||||
|
GPIO_DT_SPEC_GET_OR(DT_ALIAS(int_btn_1), gpios, {0}),
|
||||||
|
GPIO_DT_SPEC_GET_OR(DT_ALIAS(int_btn_2), gpios, {0}),
|
||||||
|
};
|
||||||
|
static struct gpio_callback buttons_cb_data[NR_BUTTONS];
|
||||||
|
|
||||||
|
int buttons_init(void) {
|
||||||
|
// BUTTON 1
|
||||||
|
gpio_pin_configure_dt(&buttons[BUTTON1], GPIO_INPUT);
|
||||||
|
gpio_pin_interrupt_configure_dt(&buttons[BUTTON1], GPIO_INT_EDGE_TO_ACTIVE);
|
||||||
|
gpio_init_callback(&buttons_cb_data[0], buttons_cb, BIT(buttons[BUTTON1].pin));
|
||||||
|
gpio_add_callback(buttons[BUTTON1].port, &buttons_cb_data[0]);
|
||||||
|
|
||||||
|
// BUTTON 2
|
||||||
|
gpio_pin_configure_dt(&buttons[BUTTON2], GPIO_INPUT);
|
||||||
|
gpio_pin_interrupt_configure_dt(&buttons[BUTTON2], GPIO_INT_EDGE_TO_ACTIVE);
|
||||||
|
gpio_init_callback(&buttons_cb_data[1], buttons_cb, BIT(buttons[BUTTON2].pin));
|
||||||
|
gpio_add_callback(buttons[BUTTON2].port, &buttons_cb_data[1]);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debounce_cb(struct k_work *work) {
|
||||||
|
if (gpio_pin_get_dt(&buttons[BUTTON1]) == GPIO_ACTIVE_HIGH ||
|
||||||
|
gpio_pin_get_dt(&buttons[BUTTON2]) == GPIO_ACTIVE_HIGH) {
|
||||||
|
LOG_DBG("Callback");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void buttons_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
|
||||||
|
LOG_DBG("Button:");
|
||||||
|
if (!k_work_delayable_is_pending(&debounce_work_btn)) {
|
||||||
|
k_work_schedule(&debounce_work_btn, K_MSEC(DEBOUNCE_TIME_MS));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef BUTTON_H
|
||||||
|
#define BUTTON_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <zephyr/drivers/gpio.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
BUTTON1,
|
||||||
|
BUTTON2,
|
||||||
|
NR_BUTTONS,
|
||||||
|
} buttons_e;
|
||||||
|
|
||||||
|
int buttons_init(void);
|
||||||
|
void buttons_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins);
|
||||||
|
void debounce_cb(struct k_work *work);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif // BUTTON_H
|
||||||
+7
-6
@@ -10,15 +10,16 @@ static struct nvs_fs nvs;
|
|||||||
static app_config_t ram_config;
|
static app_config_t ram_config;
|
||||||
|
|
||||||
#define CONFIG_ID 0xDEADBEEF
|
#define CONFIG_ID 0xDEADBEEF
|
||||||
#define CONFIG_VERSION 1
|
#define CONFIG_VERSION 2
|
||||||
|
|
||||||
|
|
||||||
static const app_config_t default_config = {
|
static const app_config_t default_config = {
|
||||||
.id = CONFIG_ID,
|
.id = CONFIG_ID,
|
||||||
.version = CONFIG_VERSION,
|
.version = CONFIG_VERSION,
|
||||||
.device_name = "my-device",
|
.mode_config = {
|
||||||
.baud_rate = 115200,
|
.phase_a_ms = (20 * 60 * 1000),
|
||||||
.log_level = 3,
|
.phase_a_ms = (20 * 1000),
|
||||||
.feature_enabled = false,
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
int config_init(void)
|
int config_init(void)
|
||||||
@@ -61,4 +62,4 @@ void config_update(void)
|
|||||||
void config_get(app_config_t *cfg)
|
void config_get(app_config_t *cfg)
|
||||||
{
|
{
|
||||||
*cfg = ram_config;
|
*cfg = ram_config;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-5
@@ -3,14 +3,12 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "mode.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint16_t version;
|
uint16_t version;
|
||||||
char device_name[32];
|
struct mode_config mode_config;
|
||||||
uint32_t baud_rate;
|
|
||||||
uint8_t log_level;
|
|
||||||
bool feature_enabled;
|
|
||||||
} app_config_t;
|
} app_config_t;
|
||||||
|
|
||||||
int config_init(void);
|
int config_init(void);
|
||||||
@@ -18,4 +16,4 @@ int config_save(const app_config_t *cfg);
|
|||||||
void config_update(void);
|
void config_update(void);
|
||||||
void config_get(app_config_t *cfg);
|
void config_get(app_config_t *cfg);
|
||||||
|
|
||||||
#endif /* CONFIG_H */
|
#endif /* CONFIG_H */
|
||||||
|
|||||||
+40
-52
@@ -1,62 +1,50 @@
|
|||||||
#include <zephyr/shell/shell.h>
|
#include "mode.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <zephyr/shell/shell.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
static int cmd_config_read(const struct shell *sh, size_t argc, char **argv)
|
static int cmd_start(const struct shell *sh, size_t argc, char **argv)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(argc);
|
mode_start();
|
||||||
ARG_UNUSED(argv);
|
return 0;
|
||||||
|
|
||||||
app_config_t cfg;
|
|
||||||
config_get(&cfg);
|
|
||||||
|
|
||||||
shell_print(sh, "device_name: %s", cfg.device_name);
|
|
||||||
shell_print(sh, "baud_rate: %u", cfg.baud_rate);
|
|
||||||
shell_print(sh, "log_level: %u", cfg.log_level);
|
|
||||||
shell_print(sh, "feature_enabled: %s", cfg.feature_enabled ? "true" : "false");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_config_update(const struct shell *sh, size_t argc, char **argv)
|
static int cmd_stop(const struct shell *sh, size_t argc, char **argv)
|
||||||
{
|
{
|
||||||
ARG_UNUSED(argc);
|
mode_stop();
|
||||||
ARG_UNUSED(argv);
|
return 0;
|
||||||
|
|
||||||
config_update();
|
|
||||||
shell_print(sh, "Config refreshed from NVS");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cmd_config_baud(const struct shell *sh, size_t argc, char **argv)
|
static int cmd_restart(const struct shell *sh, size_t argc, char **argv)
|
||||||
{
|
{
|
||||||
if (argc != 2) {
|
mode_restart();
|
||||||
shell_error(sh, "Usage: config baud <rate>");
|
return 0;
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t baud = (uint32_t)strtoul(argv[1], NULL, 10);
|
|
||||||
if (baud == 0) {
|
|
||||||
shell_error(sh, "Invalid baud rate");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
app_config_t cfg;
|
|
||||||
config_get(&cfg);
|
|
||||||
cfg.baud_rate = baud;
|
|
||||||
config_save(&cfg);
|
|
||||||
|
|
||||||
shell_print(sh, "Baud rate updated to %u", baud);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SHELL_STATIC_SUBCMD_SET_CREATE(config_cmds,
|
/* mode init <phase_a_ms> <phase_b_ms> */
|
||||||
SHELL_CMD(read, NULL, "Print config from RAM", cmd_config_read),
|
static int cmd_init(const struct shell *sh, size_t argc, char **argv)
|
||||||
SHELL_CMD(update, NULL, "Refresh RAM config from NVS", cmd_config_update),
|
{
|
||||||
SHELL_CMD(baud, NULL, "Set baud rate: config baud <rate>", cmd_config_baud),
|
app_config_t app_cfg;
|
||||||
SHELL_SUBCMD_SET_END
|
|
||||||
|
config_get(&app_cfg);
|
||||||
|
app_cfg.mode_config.phase_a_ms = atoi(argv[1]);
|
||||||
|
app_cfg.mode_config.phase_b_ms = atoi(argv[2]);
|
||||||
|
config_save(&app_cfg);
|
||||||
|
|
||||||
|
mode_init();
|
||||||
|
mode_restart();
|
||||||
|
|
||||||
|
shell_print(sh, "Config saved. phase_a=%s ms, phase_b=%s ms. Restarting.", argv[1], argv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(mode_cmds,
|
||||||
|
SHELL_CMD(start, NULL, "Start the mode thread.", cmd_start),
|
||||||
|
SHELL_CMD(stop, NULL, "Stop the mode thread.", cmd_stop),
|
||||||
|
SHELL_CMD(restart, NULL, "Restart the mode thread.", cmd_restart),
|
||||||
|
SHELL_CMD_ARG(init, NULL, "Set <phase_a_ms> <phase_b_ms>, save and restart.", cmd_init, 3, 0),
|
||||||
|
SHELL_SUBCMD_SET_END
|
||||||
);
|
);
|
||||||
|
|
||||||
SHELL_CMD_REGISTER(config, &config_cmds, "Config commands", NULL);
|
SHELL_CMD_REGISTER(mode, &mode_cmds, "Mode control.", NULL);
|
||||||
|
|||||||
@@ -18,4 +18,4 @@ static void debounce_cb(struct k_work *work);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // IMU_H
|
#endif // IMU_H
|
||||||
|
|||||||
@@ -17,6 +17,11 @@ LOG_MODULE_REGISTER(leds, LOG_LEVEL_INF);
|
|||||||
static const struct device *const strip = DEVICE_DT_GET(STRIP_NODE);
|
static const struct device *const strip = DEVICE_DT_GET(STRIP_NODE);
|
||||||
static struct led_rgb pixels[STRIP_NUM_PIXELS];
|
static struct led_rgb pixels[STRIP_NUM_PIXELS];
|
||||||
|
|
||||||
|
// Saved RGB state for the LED strip
|
||||||
|
static float saved_r = 0.0f;
|
||||||
|
static float saved_g = 0.0f;
|
||||||
|
static float saved_b = 0.0f;
|
||||||
|
|
||||||
#define NR_LEDS 8
|
#define NR_LEDS 8
|
||||||
#define PWM_RESOLUTION 255
|
#define PWM_RESOLUTION 255
|
||||||
|
|
||||||
@@ -145,6 +150,10 @@ int leds_set_all(float r, float g, float b) {
|
|||||||
pixels[i].b = b * STRIP_MAX_BRIGHTNESS;
|
pixels[i].b = b * STRIP_MAX_BRIGHTNESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saved_r = r;
|
||||||
|
saved_g = g;
|
||||||
|
saved_b = b;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,9 +172,6 @@ int leds_clear(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int leds_fade(uint32_t duration, float r, float g, float b) {
|
int leds_fade(uint32_t duration, float r, float g, float b) {
|
||||||
uint32_t step_duration = (duration * 1000) / (STRIP_MAX_BRIGHTNESS * 2);
|
uint32_t step_duration = (duration * 1000) / (STRIP_MAX_BRIGHTNESS * 2);
|
||||||
|
|
||||||
@@ -182,6 +188,10 @@ int leds_fade(uint32_t duration, float r, float g, float b) {
|
|||||||
k_sleep(K_USEC(step_duration));
|
k_sleep(K_USEC(step_duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saved_r = 0.0f;
|
||||||
|
saved_g = 0.0f;
|
||||||
|
saved_b = 0.0f;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +204,11 @@ int leds_fade_in(uint32_t duration, float r, float g, float b) {
|
|||||||
leds_update();
|
leds_update();
|
||||||
k_sleep(K_USEC(step_duration));
|
k_sleep(K_USEC(step_duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saved_r = r;
|
||||||
|
saved_g = g;
|
||||||
|
saved_b = b;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -207,5 +222,40 @@ int leds_fade_out(uint32_t duration, float r, float g, float b) {
|
|||||||
k_sleep(K_USEC(step_duration));
|
k_sleep(K_USEC(step_duration));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
saved_r = 0.0f;
|
||||||
|
saved_g = 0.0f;
|
||||||
|
saved_b = 0.0f;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int leds_fade_to(uint32_t duration, float r, float g, float b) {
|
||||||
|
// Resolve target channels — -1 means keep the saved value
|
||||||
|
float target_r = (r < 0.0f) ? saved_r : r;
|
||||||
|
float target_g = (g < 0.0f) ? saved_g : g;
|
||||||
|
float target_b = (b < 0.0f) ? saved_b : b;
|
||||||
|
|
||||||
|
float from_r = saved_r;
|
||||||
|
float from_g = saved_g;
|
||||||
|
float from_b = saved_b;
|
||||||
|
|
||||||
|
uint32_t step_duration = (duration * 1000) / STRIP_MAX_BRIGHTNESS;
|
||||||
|
|
||||||
|
for (int i = 0; i <= STRIP_MAX_BRIGHTNESS; i++) {
|
||||||
|
float t = (float)i / STRIP_MAX_BRIGHTNESS;
|
||||||
|
leds_set_all(
|
||||||
|
from_r + t * (target_r - from_r),
|
||||||
|
from_g + t * (target_g - from_g),
|
||||||
|
from_b + t * (target_b - from_b)
|
||||||
|
);
|
||||||
|
leds_update();
|
||||||
|
k_sleep(K_USEC(step_duration));
|
||||||
|
}
|
||||||
|
|
||||||
|
// leds_set_all already saved the final color, but set explicitly for clarity
|
||||||
|
saved_r = target_r;
|
||||||
|
saved_g = target_g;
|
||||||
|
saved_b = target_b;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ int leds_clear(void);
|
|||||||
int leds_fade(uint32_t duration, float r, float g, float b);
|
int leds_fade(uint32_t duration, float r, float g, float b);
|
||||||
int leds_fade_in(uint32_t duration, float r, float g, float b);
|
int leds_fade_in(uint32_t duration, float r, float g, float b);
|
||||||
int leds_fade_out(uint32_t duration, float r, float g, float b);
|
int leds_fade_out(uint32_t duration, float r, float g, float b);
|
||||||
|
int leds_fade_to(uint32_t duration, float r, float g, float b);
|
||||||
|
|
||||||
|
|
||||||
#endif // LED_H
|
#endif // LED_H
|
||||||
|
|||||||
+15
-4
@@ -45,10 +45,21 @@ static int cmd_leds_clear(const struct shell *sh, size_t argc, char **argv)
|
|||||||
return leds_clear();
|
return leds_clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int cmd_leds_fade_to(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
if (argc != 5) { shell_error(sh, "Usage: leds fade_to <ms> <r> <g> <b> (0-255, -1 to keep)"); return -EINVAL; }
|
||||||
|
return leds_fade_to(atoi(argv[1]),
|
||||||
|
atoi(argv[2]) < 0 ? -1.0f : atoi(argv[2]) / 255.0f,
|
||||||
|
atoi(argv[3]) < 0 ? -1.0f : atoi(argv[3]) / 255.0f,
|
||||||
|
atoi(argv[4]) < 0 ? -1.0f : atoi(argv[4]) / 255.0f);
|
||||||
|
}
|
||||||
|
|
||||||
SHELL_STATIC_SUBCMD_SET_CREATE(leds_cmds,
|
SHELL_STATIC_SUBCMD_SET_CREATE(leds_cmds,
|
||||||
SHELL_CMD(all, NULL, "Set all <r> <g> <b>", cmd_leds_all),
|
SHELL_CMD(all, NULL, "Set all <r> <g> <b>", cmd_leds_all),
|
||||||
SHELL_CMD(clear, NULL, "Clear all", cmd_leds_clear),
|
SHELL_CMD(clear, NULL, "Clear all", cmd_leds_clear),
|
||||||
SHELL_CMD(fade, NULL, "Fade to <ms> <r> <g> <b>", cmd_leds_fade),
|
SHELL_CMD(fade, NULL, "Fade in/out <ms> <r> <g> <b>", cmd_leds_fade),
|
||||||
|
SHELL_CMD(fade_to, NULL, "Fade to color <ms> <r> <g> <b>", cmd_leds_fade_to),
|
||||||
SHELL_SUBCMD_SET_END
|
SHELL_SUBCMD_SET_END
|
||||||
);
|
);
|
||||||
SHELL_CMD_REGISTER(leds, &leds_cmds, "Addressable LED commands", NULL);
|
|
||||||
|
SHELL_CMD_REGISTER(leds, &leds_cmds, "Addressable LED commands", NULL);
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ int main(void)
|
|||||||
ret = led_init();
|
ret = led_init();
|
||||||
ret = imu_init();
|
ret = imu_init();
|
||||||
|
|
||||||
|
mode_init();
|
||||||
|
mode_start();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
// for (int i = 0; i < 10000; i++) {
|
// for (int i = 0; i < 10000; i++) {
|
||||||
// led_set_progress((float)i / 10000.0);
|
// led_set_progress((float)i / 10000.0);
|
||||||
|
|||||||
+89
@@ -0,0 +1,89 @@
|
|||||||
|
#include "mode.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
|
#include <zephyr/kernel.h>
|
||||||
|
#include <zephyr/logging/log.h>
|
||||||
|
|
||||||
|
LOG_MODULE_REGISTER(mode, LOG_LEVEL_INF);
|
||||||
|
|
||||||
|
#define POLL_MS 100
|
||||||
|
|
||||||
|
K_THREAD_STACK_DEFINE(mode_stack, 1024);
|
||||||
|
static struct k_thread mode_thread;
|
||||||
|
static atomic_t running = ATOMIC_INIT(0);
|
||||||
|
|
||||||
|
static struct mode_config cfg;
|
||||||
|
|
||||||
|
static void mode_thread_fn(void *p1, void *p2, void *p3)
|
||||||
|
{
|
||||||
|
while (atomic_get(&running)) {
|
||||||
|
/* --- Phase A --- */
|
||||||
|
int64_t start = k_uptime_get();
|
||||||
|
while (atomic_get(&running) && k_uptime_get() - start < cfg.phase_a_ms) {
|
||||||
|
float progress = (float)(k_uptime_get() - start) / cfg.phase_a_ms;
|
||||||
|
LOG_DBG("Phase A: %.2f", (double)progress);
|
||||||
|
led_set_progress(progress);
|
||||||
|
/* do phase A work here */
|
||||||
|
k_msleep(POLL_MS);
|
||||||
|
}
|
||||||
|
led_set_progress(0);
|
||||||
|
|
||||||
|
/* --- Phase B --- */
|
||||||
|
start = k_uptime_get();
|
||||||
|
while (atomic_get(&running) && k_uptime_get() - start < cfg.phase_b_ms) {
|
||||||
|
float progress = (float)(k_uptime_get() - start) / cfg.phase_b_ms;
|
||||||
|
LOG_DBG("Phase B: %.2f", (double)progress);
|
||||||
|
leds_fade_to(500, 1, -1, -1);
|
||||||
|
leds_fade_to(500, -1, 1, -1);
|
||||||
|
leds_fade_to(500, -1, 0, -1);
|
||||||
|
leds_fade_to(500, 0, -1, -1);
|
||||||
|
/* do phase B work here */
|
||||||
|
// k_msleep(POLL_MS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LOG_INF("Mode thread stopped.");
|
||||||
|
}
|
||||||
|
|
||||||
|
void mode_init(void)
|
||||||
|
{
|
||||||
|
app_config_t app_cfg;
|
||||||
|
|
||||||
|
config_init();
|
||||||
|
config_get(&app_cfg);
|
||||||
|
|
||||||
|
cfg = app_cfg.mode_config;
|
||||||
|
|
||||||
|
LOG_INF("Mode init: phase_a=%d ms, phase_b=%d ms", cfg.phase_a_ms, cfg.phase_b_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mode_start(void)
|
||||||
|
{
|
||||||
|
if (atomic_cas(&running, 0, 1)) {
|
||||||
|
k_thread_create(&mode_thread, mode_stack,
|
||||||
|
K_THREAD_STACK_SIZEOF(mode_stack),
|
||||||
|
mode_thread_fn, NULL, NULL, NULL,
|
||||||
|
5, 0, K_NO_WAIT);
|
||||||
|
k_thread_name_set(&mode_thread, "mode");
|
||||||
|
LOG_INF("Mode started.");
|
||||||
|
} else {
|
||||||
|
LOG_WRN("Mode already running.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mode_stop(void)
|
||||||
|
{
|
||||||
|
if (atomic_cas(&running, 1, 0)) {
|
||||||
|
k_thread_join(&mode_thread, K_FOREVER);
|
||||||
|
LOG_INF("Mode stopped.");
|
||||||
|
} else {
|
||||||
|
LOG_WRN("Mode not running.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mode_restart(void)
|
||||||
|
{
|
||||||
|
mode_stop();
|
||||||
|
mode_start();
|
||||||
|
}
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
#ifndef MODE_H
|
||||||
|
#define MODE_H
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct mode_config {
|
||||||
|
int32_t phase_a_ms;
|
||||||
|
int32_t phase_b_ms;
|
||||||
|
};
|
||||||
|
|
||||||
|
void mode_init(void);
|
||||||
|
void mode_start(void);
|
||||||
|
void mode_stop(void);
|
||||||
|
void mode_restart(void);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* MODE_H */
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
#include "mode.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#include <zephyr/shell/shell.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
static int cmd_start(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
mode_start();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_stop(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
mode_stop();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int cmd_restart(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
mode_restart();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* mode init <phase_a_ms> <phase_b_ms> */
|
||||||
|
static int cmd_init(const struct shell *sh, size_t argc, char **argv)
|
||||||
|
{
|
||||||
|
app_config_t app_cfg;
|
||||||
|
|
||||||
|
config_get(&app_cfg);
|
||||||
|
app_cfg.mode_config.phase_a_ms = atoi(argv[1]);
|
||||||
|
app_cfg.mode_config.phase_b_ms = atoi(argv[2]);
|
||||||
|
config_save(&app_cfg);
|
||||||
|
|
||||||
|
mode_init();
|
||||||
|
mode_restart();
|
||||||
|
|
||||||
|
shell_print(sh, "Config saved. phase_a=%s ms, phase_b=%s ms. Restarting.", argv[1], argv[2]);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHELL_STATIC_SUBCMD_SET_CREATE(mode_cmds,
|
||||||
|
SHELL_CMD(start, NULL, "Start the mode thread.", cmd_start),
|
||||||
|
SHELL_CMD(stop, NULL, "Stop the mode thread.", cmd_stop),
|
||||||
|
SHELL_CMD(restart, NULL, "Restart the mode thread.", cmd_restart),
|
||||||
|
SHELL_CMD_ARG(init, NULL, "Set <phase_a_ms> <phase_b_ms>, save and restart.", cmd_init, 3, 0),
|
||||||
|
SHELL_SUBCMD_SET_END
|
||||||
|
);
|
||||||
|
|
||||||
|
SHELL_CMD_REGISTER(mode, &mode_cmds, "Mode control.", NULL);
|
||||||
+1
-1
@@ -17,4 +17,4 @@ ZBUS_CHAN_DEFINE(geiger_data_chan, /* Name */
|
|||||||
NULL, /* User data */
|
NULL, /* User data */
|
||||||
ZBUS_OBSERVERS(), /* observers */
|
ZBUS_OBSERVERS(), /* observers */
|
||||||
ZBUS_MSG_INIT(.cps = 0) /* Initial value */
|
ZBUS_MSG_INIT(.cps = 0) /* Initial value */
|
||||||
);
|
);
|
||||||
|
|||||||
+1
-1
@@ -36,4 +36,4 @@ ZBUS_CHAN_DECLARE(geiger_data_chan);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // ZBUS_CHANNEL
|
#endif // ZBUS_CHANNEL
|
||||||
|
|||||||
Reference in New Issue
Block a user