This commit is contained in:
archmina
2026-05-08 03:23:09 +03:00
parent a341b89d16
commit e3e548ca90
30 changed files with 1543 additions and 0 deletions
+49
View File
@@ -0,0 +1,49 @@
#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));
}
}
+25
View File
@@ -0,0 +1,25 @@
#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];
};
+64
View File
@@ -0,0 +1,64 @@
#include "config.h"
#include <zephyr/drivers/flash.h>
#include <zephyr/fs/nvs.h>
#include <zephyr/storage/flash_map.h>
#define NVS_ID_CONFIG 1
static struct nvs_fs nvs;
static app_config_t ram_config;
#define CONFIG_ID 0xDEADBEEF
#define CONFIG_VERSION 1
static const app_config_t default_config = {
.id = CONFIG_ID,
.version = CONFIG_VERSION,
.device_name = "my-device",
.baud_rate = 115200,
.log_level = 3,
.feature_enabled = false,
};
int config_init(void)
{
struct flash_pages_info page;
const struct device *dev = FIXED_PARTITION_DEVICE(storage_partition);
flash_get_page_info_by_offs(dev, FIXED_PARTITION_OFFSET(storage_partition), &page);
nvs.flash_device = dev;
nvs.offset = FIXED_PARTITION_OFFSET(storage_partition);
nvs.sector_size = page.size;
nvs.sector_count = FIXED_PARTITION_SIZE(storage_partition) / page.size;
int rc = nvs_mount(&nvs);
if (rc) {
return rc;
}
ssize_t ret = nvs_read(&nvs, NVS_ID_CONFIG, &ram_config, sizeof(ram_config));
if (ret != sizeof(ram_config) || ram_config.id != CONFIG_ID || ram_config.version != CONFIG_VERSION) {
ram_config = default_config;
nvs_write(&nvs, NVS_ID_CONFIG, &ram_config, sizeof(ram_config));
}
return 0;
}
int config_save(const app_config_t *cfg)
{
ram_config = *cfg;
return nvs_write(&nvs, NVS_ID_CONFIG, &ram_config, sizeof(ram_config));
}
void config_update(void)
{
nvs_read(&nvs, NVS_ID_CONFIG, &ram_config, sizeof(ram_config));
}
void config_get(app_config_t *cfg)
{
*cfg = ram_config;
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef CONFIG_H
#define CONFIG_H
#include <stdint.h>
#include <stdbool.h>
typedef struct {
uint32_t id;
uint16_t version;
char device_name[32];
uint32_t baud_rate;
uint8_t log_level;
bool feature_enabled;
} app_config_t;
int config_init(void);
int config_save(const app_config_t *cfg);
void config_update(void);
void config_get(app_config_t *cfg);
#endif /* CONFIG_H */
+62
View File
@@ -0,0 +1,62 @@
#include <zephyr/shell/shell.h>
#include "config.h"
static int cmd_config_read(const struct shell *sh, size_t argc, char **argv)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
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)
{
ARG_UNUSED(argc);
ARG_UNUSED(argv);
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)
{
if (argc != 2) {
shell_error(sh, "Usage: config baud <rate>");
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,
SHELL_CMD(read, NULL, "Print config from RAM", cmd_config_read),
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),
SHELL_SUBCMD_SET_END
);
SHELL_CMD_REGISTER(config, &config_cmds, "Config commands", NULL);
+148
View File
@@ -0,0 +1,148 @@
#include "imu.h"
#include "zbus_channels.h"
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/i2c.h>
LOG_MODULE_REGISTER(imu, CONFIG_LOG_MAX_LEVEL);
K_WORK_DELAYABLE_DEFINE(debounce_work_imu, debounce_cb);
#define DEBOUNCE_TIME_MS 100
#define DOUBLE_TAP_TIME_MS 500
/* Starting register for X-axis data (e.g., OUT_X_L register) */
#define ACCEL_REG_OUT_X_L 0x3B
static const uint8_t i2c_address = 0b1101001;
static const struct gpio_dt_spec imu_int = GPIO_DT_SPEC_GET_OR(DT_ALIAS(int_head), gpios, {0});
static struct gpio_callback imu_cb_data;
static const struct device *const i2c_dev = DEVICE_DT_GET(DT_ALIAS(i2c_1));
static uint32_t last_tap = 0;
void imu_reset() {
const uint8_t PWR_MGMT_1[2] = {0x6B, (uint8_t)(1 << 7)};
i2c_write(i2c_dev, PWR_MGMT_1, sizeof(PWR_MGMT_1), i2c_address);
k_sleep(K_MSEC(100));
}
int imu_init() {
if (!device_is_ready(i2c_dev)) {
LOG_ERR("I2C device %s is not ready.\n", i2c_dev->name);
return 0;
}
// imu_reset();
// Ensure that Accelerometer is running
const uint8_t PWR_MGMT_1[2] = {0x6B, 0x00};
const uint8_t PWR_MGMT_2[2] = {0x6C, 0x00};
// Accelerometer Configuration
const uint8_t ACCEL_CONFIG_1[2] = {0x1C, 0b00011000};
const uint8_t ACCEL_CONFIG_2[2] = {0x1D, 0b00000000};
// Enable Motion Interrupt
const uint8_t INT_ENABLE[2] = {0x38, 0b00100000};
// Set Motion Threshold
const uint8_t ACCEL_WOM_X_THR[2] = {0x20, 0xff};
const uint8_t ACCEL_WOM_Y_THR[2] = {0x21, 0x8f};
const uint8_t ACCEL_WOM_Z_THR[2] = {0x22, 0xff};
// Set Interrupt Mode & Enable Accelerometer Hardware Intelligence
const uint8_t ACCEL_INTEL_CTRL[2] = {0x69, 0xc0};
// Set Frequency of Wake-Up
const uint8_t SMPLRT_DIV[2] = {0x19, 0x00};
// Enable Cycle Mode (Accelerometer Low-Power Mode)
const uint8_t PWR_MGMT_1_A[2] = {0x6B, 0x20};
int ret;
i2c_write(i2c_dev, PWR_MGMT_1, sizeof(PWR_MGMT_1), i2c_address);
k_sleep(K_MSEC(1));
i2c_write(i2c_dev, PWR_MGMT_2, sizeof(PWR_MGMT_2), i2c_address);
k_sleep(K_MSEC(1));
i2c_write(i2c_dev, ACCEL_CONFIG_1, sizeof(ACCEL_CONFIG_1), i2c_address);
k_sleep(K_MSEC(1));
i2c_write(i2c_dev, ACCEL_CONFIG_2, sizeof(ACCEL_CONFIG_2), i2c_address);
k_sleep(K_MSEC(1));
i2c_write(i2c_dev, INT_ENABLE, sizeof(INT_ENABLE), i2c_address);
k_sleep(K_MSEC(1));
// // i2c_write(i2c_dev, ACCEL_WOM_X_THR, sizeof(ACCEL_WOM_X_THR), i2c_address);
// // k_sleep(K_MSEC(1));
// i2c_write(i2c_dev, ACCEL_WOM_Y_THR, sizeof(ACCEL_WOM_Y_THR), i2c_address);
// k_sleep(K_MSEC(1));
i2c_write(i2c_dev, ACCEL_WOM_Z_THR, sizeof(ACCEL_WOM_Z_THR), i2c_address);
k_sleep(K_MSEC(1));
i2c_write(i2c_dev, ACCEL_INTEL_CTRL, sizeof(ACCEL_INTEL_CTRL), i2c_address);
k_sleep(K_MSEC(1));
i2c_write(i2c_dev, SMPLRT_DIV, sizeof(SMPLRT_DIV), i2c_address);
k_sleep(K_MSEC(1));
i2c_write(i2c_dev, PWR_MGMT_1_A, sizeof(PWR_MGMT_1_A), i2c_address);
k_sleep(K_MSEC(100));
gpio_pin_configure_dt(&(imu_int), GPIO_INPUT);
gpio_pin_interrupt_configure_dt(&(imu_int), GPIO_INT_EDGE_TO_ACTIVE);
gpio_init_callback(&imu_cb_data, imu_cb, BIT(imu_int.pin));
gpio_add_callback(imu_int.port, &imu_cb_data);
last_tap = k_uptime_get();
return 0;
}
void imu_read(struct accel_data_t *buf) {
uint8_t raw_accel_data[6];
// LIGHT
uint16_t reg = ACCEL_REG_OUT_X_L;
/* Write register address, then read consecutive data bytes */
int ret = i2c_write_read(i2c_dev,
i2c_address,
&reg,
sizeof(reg),
raw_accel_data,
sizeof(raw_accel_data));
if (ret) {
printk("Error: I2C burst read failed (%d)\n", ret);
} else {
/* Combine low and high bytes for each axis */
buf->x = (int16_t)((raw_accel_data[1] << 8) | raw_accel_data[0]);
buf->y = (int16_t)((raw_accel_data[3] << 8) | raw_accel_data[2]);
buf->z = (int16_t)((raw_accel_data[5] << 8) | raw_accel_data[4]);
}
}
static void debounce_cb(struct k_work *work) {
if (gpio_pin_get_dt(&imu_int) == GPIO_ACTIVE_HIGH) {
if (k_uptime_get() - last_tap > DOUBLE_TAP_TIME_MS) {
LOG_INF("Tap");
}
else {
LOG_INF("Double tap");
struct button_msg_t msg;
msg.button = IMU;
msg.function = DOUBLE_TAP;
zbus_chan_pub(&buttons_data_chan, &msg, K_NO_WAIT);
}
last_tap = k_uptime_get();
}
}
static void imu_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins) {
/* Check if the work item is already running */
if (k_work_delayable_is_pending(&debounce_work_imu)) {
/* Do nothing, as the work item is already running */
} else {
k_work_schedule(&debounce_work_imu, K_MSEC(DEBOUNCE_TIME_MS));
}
}
+21
View File
@@ -0,0 +1,21 @@
#ifndef IMU_H
#define IMU_H
#include <zephyr/drivers/gpio.h>
struct accel_data_t {
int16_t x;
int16_t y;
int16_t z;
};
int imu_init();
void imu_read(struct accel_data_t *buf);
static void imu_cb(const struct device *dev, struct gpio_callback *cb, uint32_t pins);
static void debounce_cb(struct k_work *work);
#endif // IMU_H
+211
View File
@@ -0,0 +1,211 @@
// LOCAL
#include "led.h"
// ZEPHYR
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/logging/log.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/drivers/led_strip.h>
LOG_MODULE_REGISTER(leds, LOG_LEVEL_INF);
#define STRIP_NODE DT_ALIAS(led_strip)
#define STRIP_NUM_PIXELS DT_PROP(STRIP_NODE, chain_length)
#define STRIP_MAX_BRIGHTNESS 255
static const struct device *const strip = DEVICE_DT_GET(STRIP_NODE);
static struct led_rgb pixels[STRIP_NUM_PIXELS];
#define NR_LEDS 8
#define PWM_RESOLUTION 255
static const struct pwm_dt_spec led1 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1));
static const struct pwm_dt_spec led2 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led2));
static const struct pwm_dt_spec led3 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led3));
static const struct pwm_dt_spec led4 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led4));
static const struct pwm_dt_spec led5 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led5));
static const struct pwm_dt_spec led6 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led6));
static const struct pwm_dt_spec led7 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led7));
static const struct pwm_dt_spec led8 = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led8));
static const struct pwm_dt_spec *leds[NR_LEDS] = {&led1, &led2, &led3, &led4, &led5, &led6, &led7, &led8};
int set_pwm(const struct pwm_dt_spec *dev, uint32_t value, uint32_t max_brightness) {
if ((value <= max_brightness) && (max_brightness > 0)) {
uint32_t pulse_width_ns = value * (dev->period / max_brightness);
int ret = pwm_set_pulse_dt(dev, pulse_width_ns);
return ret;
}
return -1;
}
int led_init(void) {
// Checking if devices are ready
for (int i = 0; i < NR_LEDS; i++) {
if (!device_is_ready(leds[i]->dev)) {
LOG_ERR("PWM LEDs not ready");
return -ENODEV;
}
}
LOG_INF("PWM LEDs initialized");
if (!device_is_ready(strip)) {
LOG_ERR("LED strip device not ready");
return -ENODEV;
}
LOG_INF("LED strip initialized with %d pixels", STRIP_NUM_PIXELS);
return 0;
}
int led_fade(uint32_t duration) {
uint32_t step_duration = (duration * 1000) / (PWM_RESOLUTION * 2);
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) {
set_pwm(leds[j], i, PWM_RESOLUTION);
}
k_sleep(K_USEC(step_duration));
}
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) {
set_pwm(leds[j], (PWM_RESOLUTION - i - 1), PWM_RESOLUTION);
}
k_sleep(K_USEC(step_duration));
}
return 0;
}
int led_fade_in(uint32_t duration) {
uint32_t step_duration = (duration * 1000) / (PWM_RESOLUTION);
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) {
set_pwm(leds[j], i, PWM_RESOLUTION);
}
k_sleep(K_USEC(step_duration));
}
return 0;
}
int led_fade_out(uint32_t duration) {
uint32_t step_duration = (duration * 1000) / (PWM_RESOLUTION);
for (int i = 0; i < PWM_RESOLUTION; i++) {
for (int j = 0; j < NR_LEDS; j++) {
set_pwm(leds[j], (PWM_RESOLUTION - i - 1), PWM_RESOLUTION);
}
k_sleep(K_USEC(step_duration));
}
return 0;
}
int led_set_progress(float progress) {
uint32_t total_progress = (progress * NR_LEDS * PWM_RESOLUTION);
for (int i = 0; i < NR_LEDS; i++) {
if (total_progress > PWM_RESOLUTION) {
set_pwm(leds[i], PWM_RESOLUTION, PWM_RESOLUTION);
total_progress -= PWM_RESOLUTION;
}
else {
set_pwm(leds[i], total_progress, PWM_RESOLUTION);
total_progress = 0;
}
}
}
/* LED strip */
int leds_set_color(uint8_t led_index, float r, float g, float b) {
if (led_index >= STRIP_NUM_PIXELS) {
LOG_ERR("LED index %d out of range (max %d)", led_index, STRIP_NUM_PIXELS - 1);
return -EINVAL;
}
pixels[led_index].r = r * STRIP_MAX_BRIGHTNESS;
pixels[led_index].g = g * STRIP_MAX_BRIGHTNESS;
pixels[led_index].b = b * STRIP_MAX_BRIGHTNESS;
return 0;
}
int leds_set_all(float r, float g, float b) {
for (int i = 0; i < STRIP_NUM_PIXELS; i++) {
pixels[i].r = r * STRIP_MAX_BRIGHTNESS;
pixels[i].g = g * STRIP_MAX_BRIGHTNESS;
pixels[i].b = b * STRIP_MAX_BRIGHTNESS;
}
return 0;
}
int leds_update(void) {
int ret = led_strip_update_rgb(strip, pixels, STRIP_NUM_PIXELS);
if (ret) {
LOG_ERR("Failed to update LED strip: %d", ret);
return ret;
}
return 0;
}
int leds_clear(void) {
return leds_set_all(0, 0, 0) || leds_update();
}
int leds_fade(uint32_t duration, float r, float g, float b) {
uint32_t step_duration = (duration * 1000) / (STRIP_MAX_BRIGHTNESS * 2);
for (int i = 0; i < STRIP_MAX_BRIGHTNESS; i++) {
float value = (float)i / STRIP_MAX_BRIGHTNESS;
leds_set_all((value * r), (value * g), (value * b));
leds_update();
k_sleep(K_USEC(step_duration));
}
for (int i = STRIP_MAX_BRIGHTNESS - 1; i >= 0; i--) {
float value = (float)i / STRIP_MAX_BRIGHTNESS;
leds_set_all((value * r), (value * g), (value * b));
leds_update();
k_sleep(K_USEC(step_duration));
}
return 0;
}
int leds_fade_in(uint32_t duration, float r, float g, float b) {
uint32_t step_duration = (duration * 1000) / (STRIP_MAX_BRIGHTNESS);
for (int i = 0; i < STRIP_MAX_BRIGHTNESS; i++) {
float value = (float)i / STRIP_MAX_BRIGHTNESS;
leds_set_all((value * r), (value * g), (value * b));
leds_update();
k_sleep(K_USEC(step_duration));
}
return 0;
}
int leds_fade_out(uint32_t duration, float r, float g, float b) {
uint32_t step_duration = (duration * 1000) / (STRIP_MAX_BRIGHTNESS);
for (int i = STRIP_MAX_BRIGHTNESS - 1; i >= 0; i--) {
float value = (float)i / STRIP_MAX_BRIGHTNESS;
leds_set_all((value * r), (value * g), (value * b));
leds_update();
k_sleep(K_USEC(step_duration));
}
return 0;
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef LED_H
#define LED_H
#include <stdint.h>
int led_init(void);
int led_fade(uint32_t duration);
int led_fade_in(uint32_t duration);
int led_fade_out(uint32_t duration);
int led_set_progress(float progress);
int leds_set_color(uint8_t led_index, float r, float g, float b);
int leds_set_all(float r, float g, float b);
int leds_update(void);
int leds_clear(void);
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_out(uint32_t duration, float r, float g, float b);
#endif // LED_H
+54
View File
@@ -0,0 +1,54 @@
#include <zephyr/shell/shell.h>
#include "led.h"
/* single led */
static int cmd_led_fade(const struct shell *sh, size_t argc, char **argv)
{
if (argc != 2) { shell_error(sh, "Usage: led fade <ms>"); return -EINVAL; }
return led_fade(atoi(argv[1]));
}
static int cmd_led_progress(const struct shell *sh, size_t argc, char **argv)
{
if (argc != 2) { shell_error(sh, "Usage: led progress <0-100>"); return -EINVAL; }
return led_set_progress(atoi(argv[1]) / 100.0f);
}
SHELL_STATIC_SUBCMD_SET_CREATE(led_cmds,
SHELL_CMD(fade, NULL, "Fade over <ms>", cmd_led_fade),
SHELL_CMD(progress, NULL, "Set progress <0.0-1.0>", cmd_led_progress),
SHELL_SUBCMD_SET_END
);
SHELL_CMD_REGISTER(led, &led_cmds, "Single LED commands", NULL);
/* addressable leds */
static int cmd_leds_all(const struct shell *sh, size_t argc, char **argv)
{
if (argc != 4) { shell_error(sh, "Usage: leds all <r> <g> <b> (0-255)"); return -EINVAL; }
leds_set_all(atoi(argv[1]) / 255.0f, atoi(argv[2]) / 255.0f, atoi(argv[3]) / 255.0f);
return leds_update();
}
static int cmd_leds_fade(const struct shell *sh, size_t argc, char **argv)
{
if (argc != 5) { shell_error(sh, "Usage: leds fade <ms> <r> <g> <b> (0-255)"); return -EINVAL; }
return leds_fade(atoi(argv[1]),
atoi(argv[2]) / 255.0f,
atoi(argv[3]) / 255.0f,
atoi(argv[4]) / 255.0f);
}
static int cmd_leds_clear(const struct shell *sh, size_t argc, char **argv)
{
return leds_clear();
}
SHELL_STATIC_SUBCMD_SET_CREATE(leds_cmds,
SHELL_CMD(all, NULL, "Set all <r> <g> <b>", cmd_leds_all),
SHELL_CMD(clear, NULL, "Clear all", cmd_leds_clear),
SHELL_CMD(fade, NULL, "Fade to <ms> <r> <g> <b>", cmd_leds_fade),
SHELL_SUBCMD_SET_END
);
SHELL_CMD_REGISTER(leds, &leds_cmds, "Addressable LED commands", NULL);
+44
View File
@@ -0,0 +1,44 @@
#include <stdio.h>
#include <zephyr/kernel.h>
#include <zephyr/usb/usb_device.h>
#include <zephyr/logging/log.h>
// LOCAL
#include "led.h"
#include "config.h"
#include "imu.h"
/* 1000 msec = 1 sec */
#define SLEEP_TIME_MS 1000
LOG_MODULE_REGISTER(main, LOG_LEVEL_INF);
int main(void)
{
int ret;
ret = usb_enable(NULL);
if (ret != 0) {
LOG_ERR("Failed to enable USB: %d", ret);
return ret;
}
ret = config_init();
if (ret != 0) {
LOG_ERR("Failed to init config: %d", ret);
return ret;
}
ret = led_init();
ret = imu_init();
while (1) {
// for (int i = 0; i < 10000; i++) {
// led_set_progress((float)i / 10000.0);
// k_msleep(1);
// }
// leds_fade(1000, 0.1, 0.0, 0.05);
k_msleep(SLEEP_TIME_MS);
}
return 0;
}
+18
View File
@@ -0,0 +1,18 @@
#include <zephyr/logging/log.h>
#include <zephyr/shell/shell.h>
#include "config.h"
LOG_MODULE_REGISTER(commands);
void foo(const struct shell *sh, size_t argc, char **argv)
{
LOG_INF("info message");
LOG_WRN("warning message");
LOG_ERR("err message");
ARG_UNUSED(argc);
ARG_UNUSED(argv);
shell_print(sh, "foo executed");
}
SHELL_CMD_REGISTER(foo, NULL, "foo command", foo);
+20
View File
@@ -0,0 +1,20 @@
#include "zbus_channels.h"
ZBUS_CHAN_DEFINE(buttons_data_chan, /* Name */
struct button_msg_t, /* Message type */
NULL, /* Validator */
NULL, /* User data */
ZBUS_OBSERVERS(), /* observers */
ZBUS_MSG_INIT(.button = ERROR, .function = NONE) /* Initial value */
);
ZBUS_CHAN_DEFINE(geiger_data_chan, /* Name */
struct geiger_msg_t, /* Message type */
NULL, /* Validator */
NULL, /* User data */
ZBUS_OBSERVERS(), /* observers */
ZBUS_MSG_INIT(.cps = 0) /* Initial value */
);
+39
View File
@@ -0,0 +1,39 @@
#ifndef ZBUS_CHANNEL
#define ZBUS_CHANNEL
#include <zephyr/kernel.h>
#include <zephyr/zbus/zbus.h>
#include <stdint.h>
typedef enum {
NONE,
TAP,
DOUBLE_TAP
} function_e;
typedef enum {
ERROR = -1,
BTN1,
BTN2,
IMU
} buttons_e;
struct button_msg_t {
buttons_e button;
function_e function;
};
struct geiger_msg_t {
uint32_t cps; // clicks per second
};
ZBUS_CHAN_DECLARE(buttons_data_chan);
ZBUS_CHAN_DECLARE(geiger_data_chan);
#endif // ZBUS_CHANNEL