From 0b59c9edb1f2346909455f019c32fcbc2b3b0e05 Mon Sep 17 00:00:00 2001 From: Jan-Henrik Bruhn Date: Mon, 20 Jul 2020 17:06:03 +0200 Subject: [PATCH] Implement settings storage for stereo_mix --- stereo_mix/config.h | 4 +++ stereo_mix/drivers/leds.h | 19 +++++----- stereo_mix/settings.cc | 21 +++++++++++ stereo_mix/settings.h | 75 +++++++++++++++++++++++++++++++++++++++ stereo_mix/stereo_mix.cc | 3 +- stereo_mix/ui.cc | 40 ++++++++++++++++++--- stereo_mix/ui.h | 18 +++++++--- stmlib | 2 +- 8 files changed, 160 insertions(+), 22 deletions(-) create mode 100644 stereo_mix/config.h create mode 100644 stereo_mix/settings.cc create mode 100644 stereo_mix/settings.h diff --git a/stereo_mix/config.h b/stereo_mix/config.h new file mode 100644 index 0000000..6fee384 --- /dev/null +++ b/stereo_mix/config.h @@ -0,0 +1,4 @@ +#pragma once + +#define CHANNEL_COUNT (4) + diff --git a/stereo_mix/drivers/leds.h b/stereo_mix/drivers/leds.h index dcc23bc..dd7c106 100644 --- a/stereo_mix/drivers/leds.h +++ b/stereo_mix/drivers/leds.h @@ -11,6 +11,7 @@ #include "stm32f0xx_hal_gpio.h" #include #include +#include "../config.h" using namespace stereo_mix; using namespace stmlib; @@ -21,8 +22,6 @@ enum LedColor { LED_COLOR_ORANGE }; -const uint8_t kNumChannels = 4; - static GPIO_TypeDef* kGpioPorts[] = { GPIOA, GPIOA, GPIOA, GPIOA }; static const uint16_t kGpioPins[] = { GPIO_PIN_8, GPIO_PIN_9, GPIO_PIN_10, GPIO_PIN_11 }; @@ -41,7 +40,7 @@ class Leds { __HAL_RCC_GPIOF_CLK_ENABLE(); GPIO_InitTypeDef gpioInit; - for (size_t i = 0; i < kNumChannels; i++) { + for (size_t i = 0; i < CHANNEL_COUNT; i++) { gpioInit.Mode = GPIO_MODE_OUTPUT_PP; gpioInit.Pin = kGpioColorPins[i]; gpioInit.Pull = GPIO_NOPULL; @@ -71,7 +70,7 @@ class Leds { sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; - for(size_t i = 0; i < kNumChannels; i++) { + for(size_t i = 0; i < CHANNEL_COUNT; i++) { HAL_TIM_PWM_ConfigChannel(&htim1, &sConfigOC, timer_channel[i]); gpioInit.Mode = GPIO_MODE_AF_PP; gpioInit.Pin = kGpioPins[i]; @@ -86,7 +85,7 @@ class Leds { void Write() { - for(size_t i = 0; i < kNumChannels; i++) { + for(size_t i = 0; i < CHANNEL_COUNT; i++) { LedColor targetColor = colors[i]; uint16_t intensity = intensities[i]; if(colors[i] == LED_COLOR_ORANGE) { @@ -108,7 +107,7 @@ class Leds { } void set_intensity_signed(uint8_t channel, int16_t intensity) { - if(channel >= kNumChannels) return; + if(channel >= CHANNEL_COUNT) return; if(intensity < 0) { colors[channel] = LED_COLOR_RED; @@ -122,7 +121,7 @@ class Leds { void set_intensity_unsigned(uint8_t channel, uint16_t intensity, LedColor color) { - if (channel >= kNumChannels) + if (channel >= CHANNEL_COUNT) return; intensities[channel] = intensity; @@ -130,7 +129,7 @@ class Leds { } private: - uint16_t intensities[kNumChannels]; - bool toggle[kNumChannels]; - LedColor colors[kNumChannels]; + uint16_t intensities[CHANNEL_COUNT]; + bool toggle[CHANNEL_COUNT]; + LedColor colors[CHANNEL_COUNT]; }; diff --git a/stereo_mix/settings.cc b/stereo_mix/settings.cc new file mode 100644 index 0000000..cdf9e5d --- /dev/null +++ b/stereo_mix/settings.cc @@ -0,0 +1,21 @@ +#include "stmlib/system/page_storage.h" + +#include "settings.h" +#include "midi2cv/part.h" + +Settings::Settings() : first_start(false) +{ + persistent_data_.honor = 1; + + first_start = !chunk_storage_.Init(&persistent_data_, &state_); +} + +void Settings::SavePersistentData() +{ + chunk_storage_.SavePersistentData(); +} + +void Settings::SaveState() +{ + chunk_storage_.SaveState(); +} diff --git a/stereo_mix/settings.h b/stereo_mix/settings.h new file mode 100644 index 0000000..57c4a6b --- /dev/null +++ b/stereo_mix/settings.h @@ -0,0 +1,75 @@ +#pragma once + +#include "stmlib/stmlib.h" +#include "stmlib/system/storage.h" +#include "config.h" + +#define SETTINGS_START (0x08001800) +#define SETTINGS_END (0x08002000) + +struct ChannelData { + bool mute; + int16_t vol_att; + int16_t pan_att; + uint8_t padding[3]; +}; + +struct PersistentData { + uint8_t honor; + uint8_t padding[7]; + enum { tag = 0x494C4143 }; // CALI +}; + +struct State { + ChannelData channel_datas[CHANNEL_COUNT]; + //uint8_t padding[4]; + enum { tag = 0x54415453 }; // STAT +}; + +class Settings { + public: + Settings(); + ~Settings() {} + + void SavePersistentData(); + void SaveState(); + + inline const State& state() const + { + return state_; + } + + inline State* mutable_state() + { + return &state_; + } + + inline const ChannelData& channel(int i) const + { + return state_.channel_datas[i]; + } + + inline ChannelData* mutable_channel(int i) + { + return &state_.channel_datas[i]; + } + + inline bool is_first_start() { + return this->first_start; + } + + private: + bool first_start; + PersistentData persistent_data_; + State state_; + + stmlib::ChunkStorage< + SETTINGS_START, + SETTINGS_END, + PersistentData, + State> + chunk_storage_; + + DISALLOW_COPY_AND_ASSIGN(Settings); +}; + diff --git a/stereo_mix/stereo_mix.cc b/stereo_mix/stereo_mix.cc index 1366d46..7243915 100644 --- a/stereo_mix/stereo_mix.cc +++ b/stereo_mix/stereo_mix.cc @@ -19,7 +19,8 @@ Adc adc; Leds leds; Switches switches; Processor processors[kNumChannels]; -UI ui(&adc, &switches, &leds, processors); +Settings settings; +UI ui(&adc, &switches, &leds, processors, &settings); bool mute[4]; diff --git a/stereo_mix/ui.cc b/stereo_mix/ui.cc index c9a77fe..945001a 100644 --- a/stereo_mix/ui.cc +++ b/stereo_mix/ui.cc @@ -1,9 +1,10 @@ #include "ui.h" #include "pot_controller.h" +#include "settings.h" #include -const int kLongPressDuration = 2000; -const int kShowChangedValueMilliseconds = 600; +static const int kLongPressDuration = 2000; +static const int kShowChangedValueMilliseconds = 600; void UI::Poll() { @@ -40,8 +41,10 @@ void UI::Poll() system_clock.milliseconds() - press_time[i] + 1); ignore_release[i] = true; } - for (size_t j = 0; j < kNumChannels * 2; j++) + for (size_t j = 0; j < kNumChannels * 2; j++) { potControllers[j].Unlock(); + SaveState(); + } } } @@ -53,6 +56,7 @@ void UI::Poll() if (i < kNumChannels) { processors[i].set_pan_offset(pan_pots[i] - 32767); processors[i].set_volume_offset(volume_pots[i]); + processors[i].set_muted(mute[i]); } if (abs(previous_pot_values[i] - adc->value(ADC_GROUP_POT + i)) > 1900) { previous_pot_values[i] = adc->value(ADC_GROUP_POT + i); @@ -61,6 +65,33 @@ void UI::Poll() } } +void UI::LoadState() { + if(!settings->is_first_start()) { + for(size_t i = 0; i < kNumChannels; i++) { + ChannelData c = settings->channel(i); + mute[i] = c.mute; + this->pan_att_pots[i] = c.pan_att + 32767; + this->volume_att_pots[i] = c.vol_att + 32767; + } + } else { + for(size_t i = 0; i < kNumChannels; i++) { + mute[i] = false; + this->pan_att_pots[i] = this->volume_att_pots[i] = 32767 + (32767 / 2); + } + } +} + +void UI::SaveState() { + for(size_t i = 0; i < kNumChannels; i++) { + ChannelData* c = settings->mutable_channel(i); + c->mute = this->mute[i]; + c->pan_att = this->pan_att_pots[i] - 32767; + c->vol_att = this->volume_att_pots[i] - 32767; + } + + settings->SaveState(); +} + void UI::OnSwitchPressed(const Event& e) { } @@ -79,13 +110,12 @@ void UI::OnPotChanged(const Event& e) void UI::OnSwitchReleased(const Event& e) { mute[e.control_id] = !mute[e.control_id]; - processors[e.control_id].set_muted(mute[e.control_id]); for (size_t i = 0; i < kNumChannels; i++) { last_pan_pot_touch[i] = last_vol_pot_touch[i] = 0; } - // todo: save state + SaveState(); } void UI::TaskProcessPotControllers() diff --git a/stereo_mix/ui.h b/stereo_mix/ui.h index 20cf9f7..2fd49f8 100644 --- a/stereo_mix/ui.h +++ b/stereo_mix/ui.h @@ -6,30 +6,33 @@ #include "pot_controller.h" #include "processor.h" #include "stmlib/ui/event_queue.h" +#include "config.h" +#include "settings.h" using namespace stmlib; -extern const uint8_t kNumChannels; // TODO +const uint8_t kNumChannels = CHANNEL_COUNT; class UI { public: - UI(Adc* adc_, Switches* switches_, Leds* leds_, Processor* processors_) + UI(Adc* adc_, Switches* switches_, Leds* leds_, Processor* processors_, Settings* settings) : adc(adc_) , switches(switches_) , leds(leds_) , processors(processors_) + , settings(settings) { queue.Init(); - }; + void Init() { + LoadState(); + for (size_t i = 0; i < kNumChannels; i++) { uint16_t* volume_hidden_params[] = {&volume_att_pots[i], &volume_att_pots[i], &volume_att_pots[i], &volume_att_pots[i]}; potControllers[i].Init(&volume_pots[i], volume_hidden_params); uint16_t* pan_hidden_params[] = {&pan_att_pots[i], &pan_att_pots[i], &pan_att_pots[i], &pan_att_pots[i]}; potControllers[i + kNumChannels].Init(&pan_pots[i], pan_hidden_params); - - volume_att_pots[i] = pan_att_pots[i] = 32767 + (32767 / 2); } } @@ -45,6 +48,9 @@ class UI { void TaskDrawLeds(void); void TaskProcessPotControllers(void); + void LoadState(); + void SaveState(); + uint8_t ui_task = 0; EventQueue<> queue; @@ -56,6 +62,8 @@ class UI { Processor* processors; + Settings* settings; + uint16_t previous_pot_values[kNumChannels * 2]; uint16_t volume_pots[kNumChannels]; diff --git a/stmlib b/stmlib index 727d85a..ed353ae 160000 --- a/stmlib +++ b/stmlib @@ -1 +1 @@ -Subproject commit 727d85a263af4ee4c2d8dd75191e2611383b9d29 +Subproject commit ed353ae21927643acffb86c96b69eec43879754d