/* Copyright (C) 2026 Reiner Herrmann * SPDX-License-Identifier: GPL-3.0-or-later */ #include #include "config.h" #include "metronome.h" struct Configuration { uint8_t version; uint16_t bpm; uint8_t beats; uint8_t volume; uint8_t beat_indicators; } __attribute__((__packed__)); #define SETTINGS_KEY 1 #define CONFIG_VERSION 1 static struct Configuration configuration; static void config_persist() { persist_write_data(SETTINGS_KEY, &configuration, sizeof(configuration)); } static void config_load_defaults() { configuration.version = CONFIG_VERSION; configuration.bpm = 90; configuration.beats = 4; configuration.volume = 100; configuration.beat_indicators = 0xff; } static void config_load() { config_load_defaults(); /* buffer remains unchanged if no data is persisted */ persist_read_data(SETTINGS_KEY, &configuration, sizeof(configuration)); if (configuration.version != CONFIG_VERSION) { /* unknown persisted configuration format */ config_load_defaults(); } } static void config_inbox_received_handler(DictionaryIterator *iter, void *context) { struct Configuration new_configuration; memcpy(&new_configuration, &configuration, sizeof(configuration)); Tuple *bpm_tuple = dict_find(iter, MESSAGE_KEY_bpm); if (bpm_tuple) { int32_t bpm = bpm_tuple->value->int32; configuration.bpm = (uint16_t) bpm; } Tuple *beats_tuple = dict_find(iter, MESSAGE_KEY_beats); if (beats_tuple) { int32_t beats = beats_tuple->value->int32; configuration.beats = (uint8_t) beats; } Tuple *volume_tuple = dict_find(iter, MESSAGE_KEY_volume); if (volume_tuple) { int32_t volume = volume_tuple->value->int32; configuration.volume = (uint8_t) volume; } const int num_beat_indicators = 3; for (int i=0; ivalue->uint8; /* clear bit */ configuration.beat_indicators &= ~(1 << i); /* set value into bit */ configuration.beat_indicators |= (val << i); } } if (memcmp(&new_configuration, &configuration, sizeof(configuration)) != 0) { /* only persist if something changed */ config_persist(); update_display(); } } void config_init() { config_load(); app_message_register_inbox_received(config_inbox_received_handler); app_message_open(128, 128); } void config_deinit() { app_message_deregister_callbacks(); } uint16_t config_get_bpm() { return configuration.bpm; } void config_set_bpm(uint16_t bpm) { configuration.bpm = bpm; config_persist(); } uint8_t config_get_beats() { return configuration.beats; } void config_set_beats(uint8_t beats) { configuration.beats = beats; config_persist(); } uint8_t config_get_volume() { return configuration.volume; } bool config_is_indicator_enabled(enum BeatIndicator indicator) { return configuration.beat_indicators & (1 << indicator); }