summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-06-06 10:20:46 +1000
committerjacqueline <me@jacqueline.id.au>2023-06-06 10:20:46 +1000
commit8a2a2d226558d099243eea0aa9ae22b2791e0e0e (patch)
tree16c3defdb167ea7f452e5ce96118b165acf6602f
parentee5f662f9bb150138545ca35ef5c4896eb74daea (diff)
downloadtangara-fw-8a2a2d226558d099243eea0aa9ae22b2791e0e0e.tar.gz
Get basic audio playback going again
-rw-r--r--src/app_console/app_console.cpp8
-rw-r--r--src/app_console/include/app_console.hpp4
-rw-r--r--src/audio/audio_decoder.cpp11
-rw-r--r--src/audio/audio_fsm.cpp32
-rw-r--r--src/audio/audio_task.cpp102
-rw-r--r--src/audio/fatfs_audio_input.cpp4
-rw-r--r--src/audio/include/audio_decoder.hpp3
-rw-r--r--src/audio/include/audio_element.hpp3
-rw-r--r--src/audio/include/fatfs_audio_input.hpp2
-rw-r--r--src/audio/pipeline.cpp2
-rw-r--r--src/drivers/display.cpp58
-rw-r--r--src/drivers/include/relative_wheel.hpp8
-rw-r--r--src/drivers/relative_wheel.cpp15
-rw-r--r--src/system_fsm/running.cpp3
-rw-r--r--src/ui/include/wheel_encoder.hpp18
-rw-r--r--src/ui/lvgl_task.cpp2
-rw-r--r--src/ui/screen_menu.cpp8
-rw-r--r--src/ui/ui_fsm.cpp6
-rw-r--r--src/ui/wheel_encoder.cpp28
19 files changed, 200 insertions, 117 deletions
diff --git a/src/app_console/app_console.cpp b/src/app_console/app_console.cpp
index 39d6d8e0..0483bde9 100644
--- a/src/app_console/app_console.cpp
+++ b/src/app_console/app_console.cpp
@@ -69,7 +69,7 @@ void RegisterListDir() {
esp_console_cmd_register(&cmd);
}
- //sInstance->playback_->Play(path + argv[1]);
+// sInstance->playback_->Play(path + argv[1]);
int CmdPlayFile(int argc, char** argv) {
static const std::string usage = "usage: play [file]";
if (argc != 2) {
@@ -80,7 +80,7 @@ int CmdPlayFile(int argc, char** argv) {
std::string path = "/";
events::Dispatch<audio::PlayFile, audio::AudioState>(
- audio::PlayFile{ .filename = path + argv[1] });
+ audio::PlayFile{.filename = path + argv[1]});
return 0;
}
@@ -200,7 +200,7 @@ void RegisterDbDump() {
esp_console_cmd_register(&cmd);
}
-AppConsole::AppConsole(std::weak_ptr<database::Database> database)
+AppConsole::AppConsole(const std::weak_ptr<database::Database>& database)
: database_(database) {
sInstance = this;
}
@@ -210,8 +210,8 @@ AppConsole::~AppConsole() {
auto AppConsole::RegisterExtraComponents() -> void {
RegisterListDir();
- /*
RegisterPlayFile();
+ /*
RegisterToggle();
RegisterVolume();
RegisterAudioStatus();
diff --git a/src/app_console/include/app_console.hpp b/src/app_console/include/app_console.hpp
index 9df3996b..32242d16 100644
--- a/src/app_console/include/app_console.hpp
+++ b/src/app_console/include/app_console.hpp
@@ -15,10 +15,10 @@ namespace console {
class AppConsole : public Console {
public:
- explicit AppConsole(std::weak_ptr<database::Database> database);
+ explicit AppConsole(const std::weak_ptr<database::Database>& database);
virtual ~AppConsole();
- std::weak_ptr<database::Database> database_;
+ const std::weak_ptr<database::Database>& database_;
protected:
virtual auto RegisterExtraComponents() -> void;
diff --git a/src/audio/audio_decoder.cpp b/src/audio/audio_decoder.cpp
index 981cca6f..5a2c75c7 100644
--- a/src/audio/audio_decoder.cpp
+++ b/src/audio/audio_decoder.cpp
@@ -14,7 +14,6 @@
#include <memory>
#include <variant>
-#include "cbor/tinycbor/src/cborinternal_p.h"
#include "freertos/FreeRTOS.h"
#include "esp_heap_caps.h"
@@ -36,7 +35,8 @@ AudioDecoder::AudioDecoder()
current_codec_(),
current_input_format_(),
current_output_format_(),
- has_samples_to_send_(false) {}
+ has_samples_to_send_(false),
+ has_input_remaining_(false) {}
AudioDecoder::~AudioDecoder() {}
@@ -70,6 +70,10 @@ auto AudioDecoder::ProcessStreamInfo(const StreamInfo& info) -> bool {
return true;
}
+auto AudioDecoder::NeedsToProcess() const -> bool {
+ return has_samples_to_send_ || has_input_remaining_;
+}
+
auto AudioDecoder::Process(const std::vector<InputStream>& inputs,
OutputStream* output) -> void {
auto input = inputs.begin();
@@ -124,7 +128,8 @@ auto AudioDecoder::Process(const std::vector<InputStream>& inputs,
return;
}
- if (res.value()) {
+ has_input_remaining_ = !res.value();
+ if (!has_input_remaining_) {
// We're out of useable data in this buffer. Finish immediately; there's
// nothing to send.
input->mark_incomplete();
diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp
index a1bb956f..9c7af6fe 100644
--- a/src/audio/audio_fsm.cpp
+++ b/src/audio/audio_fsm.cpp
@@ -29,29 +29,29 @@ auto AudioState::Init(drivers::GpioExpander* gpio_expander,
sGpioExpander = gpio_expander;
sDac = dac;
sDatabase = database;
-}
-namespace states {
+ sFileSource.reset(new FatfsAudioInput());
+ sI2SOutput.reset(new I2SAudioOutput(sGpioExpander, sDac));
-void Uninitialised::react(const system_fsm::BootComplete&) {
- transit<Standby>([&]() {
- sFileSource.reset(new FatfsAudioInput());
- sI2SOutput.reset(new I2SAudioOutput(sGpioExpander, sDac));
+ // Perform initial pipeline configuration.
+ // TODO(jacqueline): Factor this out once we have any kind of dynamic
+ // reconfiguration.
+ AudioDecoder* codec = new AudioDecoder();
+ sPipeline.emplace_back(codec);
- // Perform initial pipeline configuration.
- // TODO(jacqueline): Factor this out once we have any kind of dynamic
- // reconfiguration.
- AudioDecoder* codec = new AudioDecoder();
- sPipeline.emplace_back(codec);
+ Pipeline* pipeline = new Pipeline(sPipeline.front().get());
+ pipeline->AddInput(sFileSource.get());
- Pipeline* pipeline = new Pipeline(sPipeline.front().get());
- pipeline->AddInput(sFileSource.get());
+ task::StartPipeline(pipeline, sI2SOutput.get());
+}
- task::StartPipeline(pipeline, sI2SOutput.get());
- });
+namespace states {
+
+void Uninitialised::react(const system_fsm::BootComplete&) {
+ transit<Standby>();
}
-void Standby::react(const PlayFile &ev) {
+void Standby::react(const PlayFile& ev) {
if (sFileSource->OpenFile(ev.filename)) {
transit<Playback>();
}
diff --git a/src/audio/audio_task.cpp b/src/audio/audio_task.cpp
index 6cc2d927..343281a7 100644
--- a/src/audio/audio_task.cpp
+++ b/src/audio/audio_task.cpp
@@ -43,20 +43,64 @@ namespace task {
static const char* kTag = "task";
+// The default amount of time to wait between pipeline iterations for a single
+// song.
+static constexpr uint_fast16_t kDefaultDelayTicks = pdMS_TO_TICKS(5);
+static constexpr uint_fast16_t kMaxDelayTicks = pdMS_TO_TICKS(10);
+static constexpr uint_fast16_t kMinDelayTicks = pdMS_TO_TICKS(1);
+
void AudioTaskMain(std::unique_ptr<Pipeline> pipeline, IAudioSink* sink) {
+ // The stream format for bytes currently in the sink buffer.
std::optional<StreamInfo::Format> output_format;
- uint_fast16_t delay_ticks = pdMS_TO_TICKS(5);
- std::vector<Pipeline*> elements = pipeline->GetIterationOrder();
+ // How long to wait between pipeline iterations. This is reset for each song,
+ // and readjusted on the fly to maintain a reasonable amount playback buffer.
+ // Buffering too much will mean we process samples inefficiently, wasting CPU
+ // time, whilst buffering too little will affect the quality of the output.
+ uint_fast16_t delay_ticks = kDefaultDelayTicks;
+
+ std::vector<Pipeline*> all_elements = pipeline->GetIterationOrder();
- events::EventQueue &event_queue = events::EventQueue::GetInstance();
+ events::EventQueue& event_queue = events::EventQueue::GetInstance();
while (1) {
- event_queue.ServiceAudio(delay_ticks);
+ // First, see if we actually have any pipeline work to do in this iteration.
+ bool has_work = false;
+ // We always have work to do if there's still bytes to be sunk.
+ has_work = all_elements.back()->OutStream().info->bytes_in_stream > 0;
+ if (!has_work) {
+ for (Pipeline* p : all_elements) {
+ has_work = p->OutputElement()->NeedsToProcess();
+ if (has_work) {
+ break;
+ }
+ }
+ }
+
+ // See if there's any new events.
+ event_queue.ServiceAudio(has_work ? delay_ticks : portMAX_DELAY);
+
+ if (!has_work) {
+ // See if we've been given work by this event.
+ for (Pipeline* p : all_elements) {
+ has_work = p->OutputElement()->NeedsToProcess();
+ if (has_work) {
+ delay_ticks = kDefaultDelayTicks;
+ break;
+ }
+ }
+ if (!has_work) {
+ continue;
+ }
+ }
+
+ // We have work to do! Allow each element in the pipeline to process one
+ // chunk. We iterate from input nodes first, so this should result in
+ // samples in the output buffer.
- for (int i = 0; i < elements.size(); i++) {
+ for (int i = 0; i < all_elements.size(); i++) {
std::vector<RawStream> raw_in_streams;
- elements.at(i)->InStreams(&raw_in_streams);
- RawStream raw_out_stream = elements.at(i)->OutStream();
+ all_elements.at(i)->InStreams(&raw_in_streams);
+ RawStream raw_out_stream = all_elements.at(i)->OutStream();
// Crop the input and output streams to the ranges that are safe to
// touch. For the input streams, this is the region that contains
@@ -67,14 +111,14 @@ void AudioTaskMain(std::unique_ptr<Pipeline> pipeline, IAudioSink* sink) {
[&](RawStream& s) { in_streams.emplace_back(&s); });
OutputStream out_stream(&raw_out_stream);
- elements.at(i)->OutputElement()->Process(in_streams, &out_stream);
+ all_elements.at(i)->OutputElement()->Process(in_streams, &out_stream);
}
- RawStream raw_sink_stream = elements.front()->OutStream();
+ RawStream raw_sink_stream = all_elements.back()->OutStream();
InputStream sink_stream(&raw_sink_stream);
if (sink_stream.info().bytes_in_stream == 0) {
- vTaskDelay(pdMS_TO_TICKS(100));
+ // No new bytes to sink, so skip sinking completely.
continue;
}
@@ -86,24 +130,36 @@ void AudioTaskMain(std::unique_ptr<Pipeline> pipeline, IAudioSink* sink) {
ESP_LOGI(kTag, "reconfiguring dac");
output_format = sink_stream.info().format;
sink->Configure(*output_format);
+ } else {
+ continue;
}
}
// We've reconfigured the sink, or it was already configured correctly.
// Send through some data.
- if (output_format == sink_stream.info().format &&
- !std::holds_alternative<std::monostate>(*output_format)) {
- std::size_t sent =
- xStreamBufferSend(sink->buffer(), sink_stream.data().data(),
- sink_stream.data().size_bytes(), 0);
- if (sent > 0) {
- ESP_LOGI(
- kTag, "sunk %u bytes out of %u (%d %%)", sent,
- sink_stream.info().bytes_in_stream,
- (int)(((float)sent / (float)sink_stream.info().bytes_in_stream) *
- 100));
- }
- sink_stream.consume(sent);
+ std::size_t bytes_sunk =
+ xStreamBufferSend(sink->buffer(), sink_stream.data().data(),
+ sink_stream.data().size_bytes(), 0);
+
+ // Adjust how long we wait for the next iteration if we're getting too far
+ // ahead or behind.
+ float sunk_percent = static_cast<float>(bytes_sunk) /
+ static_cast<float>(sink_stream.info().bytes_in_stream);
+
+ if (sunk_percent > 0.66f) {
+ // We're sinking a lot of the output buffer per iteration, so we need to
+ // be running faster.
+ delay_ticks--;
+ } else if (sunk_percent < 0.33f) {
+ // We're not sinking much of the output buffer per iteration, so we can
+ // slow down to save some cycles.
+ delay_ticks++;
+ }
+ delay_ticks = std::clamp(delay_ticks, kMinDelayTicks, kMaxDelayTicks);
+
+ // Finally, actually mark the bytes we sunk as consumed.
+ if (bytes_sunk > 0) {
+ sink_stream.consume(bytes_sunk);
}
}
}
diff --git a/src/audio/fatfs_audio_input.cpp b/src/audio/fatfs_audio_input.cpp
index ed5db315..8abc7d32 100644
--- a/src/audio/fatfs_audio_input.cpp
+++ b/src/audio/fatfs_audio_input.cpp
@@ -51,6 +51,10 @@ auto FatfsAudioInput::OpenFile(const std::string& path) -> bool {
return true;
}
+auto FatfsAudioInput::NeedsToProcess() const -> bool {
+ return is_file_open_;
+}
+
auto FatfsAudioInput::Process(const std::vector<InputStream>& inputs,
OutputStream* output) -> void {
if (!is_file_open_) {
diff --git a/src/audio/include/audio_decoder.hpp b/src/audio/include/audio_decoder.hpp
index 5927e150..3cda0305 100644
--- a/src/audio/include/audio_decoder.hpp
+++ b/src/audio/include/audio_decoder.hpp
@@ -30,6 +30,8 @@ class AudioDecoder : public IAudioElement {
AudioDecoder();
~AudioDecoder();
+ auto NeedsToProcess() const -> bool override;
+
auto Process(const std::vector<InputStream>& inputs, OutputStream* output)
-> void override;
@@ -41,6 +43,7 @@ class AudioDecoder : public IAudioElement {
std::optional<StreamInfo::Format> current_input_format_;
std::optional<StreamInfo::Format> current_output_format_;
bool has_samples_to_send_;
+ bool has_input_remaining_;
auto ProcessStreamInfo(const StreamInfo& info) -> bool;
};
diff --git a/src/audio/include/audio_element.hpp b/src/audio/include/audio_element.hpp
index 133a6ae7..7e3d9d7d 100644
--- a/src/audio/include/audio_element.hpp
+++ b/src/audio/include/audio_element.hpp
@@ -10,6 +10,7 @@
#include <cstdint>
#include <deque>
#include <memory>
+#include <vector>
#include "freertos/FreeRTOS.h"
@@ -46,6 +47,8 @@ class IAudioElement {
IAudioElement() {}
virtual ~IAudioElement() {}
+ virtual auto NeedsToProcess() const -> bool = 0;
+
virtual auto Process(const std::vector<InputStream>& inputs,
OutputStream* output) -> void = 0;
};
diff --git a/src/audio/include/fatfs_audio_input.hpp b/src/audio/include/fatfs_audio_input.hpp
index 98ad4d2b..bfc0064e 100644
--- a/src/audio/include/fatfs_audio_input.hpp
+++ b/src/audio/include/fatfs_audio_input.hpp
@@ -33,6 +33,8 @@ class FatfsAudioInput : public IAudioElement {
auto OpenFile(const std::string& path) -> bool;
+ auto NeedsToProcess() const -> bool override;
+
auto Process(const std::vector<InputStream>& inputs, OutputStream* output)
-> void override;
diff --git a/src/audio/pipeline.cpp b/src/audio/pipeline.cpp
index 60598151..f54f8d11 100644
--- a/src/audio/pipeline.cpp
+++ b/src/audio/pipeline.cpp
@@ -5,6 +5,7 @@
*/
#include "pipeline.hpp"
+#include <algorithm>
#include <memory>
#include "stream_info.hpp"
@@ -53,6 +54,7 @@ auto Pipeline::GetIterationOrder() -> std::vector<Pipeline*> {
}
}
+ std::reverse(found.begin(), found.end());
return found;
}
diff --git a/src/drivers/display.cpp b/src/drivers/display.cpp
index 0c9e56b3..af439def 100644
--- a/src/drivers/display.cpp
+++ b/src/drivers/display.cpp
@@ -97,8 +97,8 @@ auto Display::Create(GpioExpander* expander,
gpio_config(&dr_config);
gpio_set_level(kDisplayDr, 0);
- ledc_timer_config_t led_config {
- .speed_mode = LEDC_LOW_SPEED_MODE,
+ ledc_timer_config_t led_config{
+ .speed_mode = LEDC_LOW_SPEED_MODE,
.duty_resolution = LEDC_TIMER_13_BIT,
.timer_num = LEDC_TIMER_0,
.freq_hz = 5000,
@@ -106,14 +106,12 @@ auto Display::Create(GpioExpander* expander,
};
ledc_timer_config(&led_config);
- ledc_channel_config_t led_channel {
- .gpio_num = kDisplayLedEn,
- .speed_mode = LEDC_LOW_SPEED_MODE,
- .channel = LEDC_CHANNEL_0,
- .timer_sel = LEDC_TIMER_0,
- .duty = 4095,
- .hpoint = 0
- };
+ ledc_channel_config_t led_channel{.gpio_num = kDisplayLedEn,
+ .speed_mode = LEDC_LOW_SPEED_MODE,
+ .channel = LEDC_CHANNEL_0,
+ .timer_sel = LEDC_TIMER_0,
+ .duty = 4095,
+ .hpoint = 0};
ledc_channel_config(&led_channel);
// Next, init the SPI device
@@ -260,32 +258,32 @@ void Display::OnLvglFlush(lv_disp_drv_t* disp_drv,
// area is stack-allocated, so it isn't safe to reference from the flush
// thread.
lv_area_t area_copy = *area;
- //worker_task_->Dispatch<void>([=, this]() {
- // Ideally we want to complete a single flush as quickly as possible, so
- // grab the bus for this entire transaction sequence.
- spi_device_acquire_bus(handle_, portMAX_DELAY);
+ // worker_task_->Dispatch<void>([=, this]() {
+ // Ideally we want to complete a single flush as quickly as possible, so
+ // grab the bus for this entire transaction sequence.
+ spi_device_acquire_bus(handle_, portMAX_DELAY);
- // First we need to specify the rectangle of the display we're writing into.
- uint16_t data[2] = {0, 0};
+ // First we need to specify the rectangle of the display we're writing into.
+ uint16_t data[2] = {0, 0};
- data[0] = SPI_SWAP_DATA_TX(area_copy.x1, 16);
- data[1] = SPI_SWAP_DATA_TX(area_copy.x2, 16);
- SendCommandWithData(displays::ST77XX_CASET,
- reinterpret_cast<uint8_t*>(data), 4);
+ data[0] = SPI_SWAP_DATA_TX(area_copy.x1, 16);
+ data[1] = SPI_SWAP_DATA_TX(area_copy.x2, 16);
+ SendCommandWithData(displays::ST77XX_CASET, reinterpret_cast<uint8_t*>(data),
+ 4);
- data[0] = SPI_SWAP_DATA_TX(area_copy.y1, 16);
- data[1] = SPI_SWAP_DATA_TX(area_copy.y2, 16);
- SendCommandWithData(displays::ST77XX_RASET,
- reinterpret_cast<uint8_t*>(data), 4);
+ data[0] = SPI_SWAP_DATA_TX(area_copy.y1, 16);
+ data[1] = SPI_SWAP_DATA_TX(area_copy.y2, 16);
+ SendCommandWithData(displays::ST77XX_RASET, reinterpret_cast<uint8_t*>(data),
+ 4);
- // Now send the pixels for this region.
- uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
- SendCommandWithData(displays::ST77XX_RAMWR,
- reinterpret_cast<uint8_t*>(color_map), size * 2);
+ // Now send the pixels for this region.
+ uint32_t size = lv_area_get_width(area) * lv_area_get_height(area);
+ SendCommandWithData(displays::ST77XX_RAMWR,
+ reinterpret_cast<uint8_t*>(color_map), size * 2);
- spi_device_release_bus(handle_);
+ spi_device_release_bus(handle_);
- lv_disp_flush_ready(&driver_);
+ lv_disp_flush_ready(&driver_);
//});
}
diff --git a/src/drivers/include/relative_wheel.hpp b/src/drivers/include/relative_wheel.hpp
index 3ff64b70..da4f9e3d 100644
--- a/src/drivers/include/relative_wheel.hpp
+++ b/src/drivers/include/relative_wheel.hpp
@@ -20,9 +20,11 @@ namespace drivers {
class RelativeWheel {
public:
- static auto Create(TouchWheel *touch) -> RelativeWheel* { return new RelativeWheel(touch); }
+ static auto Create(TouchWheel* touch) -> RelativeWheel* {
+ return new RelativeWheel(touch);
+ }
- explicit RelativeWheel(TouchWheel *touch);
+ explicit RelativeWheel(TouchWheel* touch);
// Not copyable or movable.
RelativeWheel(const RelativeWheel&) = delete;
@@ -34,7 +36,7 @@ class RelativeWheel {
auto ticks() -> std::int_fast16_t;
private:
- TouchWheel *touch_;
+ TouchWheel* touch_;
bool is_pressed_;
bool is_first_read_;
std::int_fast16_t ticks_;
diff --git a/src/drivers/relative_wheel.cpp b/src/drivers/relative_wheel.cpp
index f64d213d..4c9e19bb 100644
--- a/src/drivers/relative_wheel.cpp
+++ b/src/drivers/relative_wheel.cpp
@@ -13,12 +13,12 @@
namespace drivers {
-RelativeWheel::RelativeWheel(TouchWheel *touch)
- :touch_(touch),
- is_pressed_(false),
- is_first_read_(true),
- ticks_(0),
- last_angle_(0) {}
+RelativeWheel::RelativeWheel(TouchWheel* touch)
+ : touch_(touch),
+ is_pressed_(false),
+ is_first_read_(true),
+ ticks_(0),
+ last_angle_(0) {}
auto RelativeWheel::Update() -> void {
touch_->Update();
@@ -68,11 +68,10 @@ auto RelativeWheel::is_pressed() -> bool {
auto RelativeWheel::ticks() -> std::int_fast16_t {
int_fast16_t t = ticks_;
if (t != 0) {
- ESP_LOGI("teeks", "ticks %d", t);
+ ESP_LOGI("teeks", "ticks %d", t);
}
ticks_ = 0;
return t;
}
-
} // namespace drivers
diff --git a/src/system_fsm/running.cpp b/src/system_fsm/running.cpp
index 3e8b8b76..9116ec9d 100644
--- a/src/system_fsm/running.cpp
+++ b/src/system_fsm/running.cpp
@@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-only
*/
+#include "freertos/projdefs.h"
#include "result.hpp"
#include "audio_fsm.hpp"
@@ -24,6 +25,7 @@ static const char kTag[] = "RUN";
*/
void Running::entry() {
ESP_LOGI(kTag, "mounting sd card");
+ vTaskDelay(pdMS_TO_TICKS(250));
auto storage_res = drivers::SdStorage::Create(sGpioExpander.get());
if (storage_res.has_error()) {
events::Dispatch<StorageError, SystemState, audio::AudioState, ui::UiState>(
@@ -31,6 +33,7 @@ void Running::entry() {
return;
}
sStorage.reset(storage_res.value());
+ vTaskDelay(pdMS_TO_TICKS(250));
ESP_LOGI(kTag, "opening database");
auto database_res = database::Database::Open();
diff --git a/src/ui/include/wheel_encoder.hpp b/src/ui/include/wheel_encoder.hpp
index 0651ce0b..d4975db9 100644
--- a/src/ui/include/wheel_encoder.hpp
+++ b/src/ui/include/wheel_encoder.hpp
@@ -15,16 +15,16 @@
namespace ui {
class TouchWheelEncoder {
- public:
- explicit TouchWheelEncoder(std::weak_ptr<drivers::RelativeWheel> wheel);
+ public:
+ explicit TouchWheelEncoder(std::weak_ptr<drivers::RelativeWheel> wheel);
- auto Read(lv_indev_data_t *data) -> void;
- auto registration() -> lv_indev_t* { return registration_; }
+ auto Read(lv_indev_data_t* data) -> void;
+ auto registration() -> lv_indev_t* { return registration_; }
- private:
- lv_indev_drv_t driver_;
- lv_indev_t *registration_;
- std::weak_ptr<drivers::RelativeWheel> wheel_;
+ private:
+ lv_indev_drv_t driver_;
+ lv_indev_t* registration_;
+ std::weak_ptr<drivers::RelativeWheel> wheel_;
};
-} // namespace ui
+} // namespace ui
diff --git a/src/ui/lvgl_task.cpp b/src/ui/lvgl_task.cpp
index 1ce7fd40..b0e2e0ed 100644
--- a/src/ui/lvgl_task.cpp
+++ b/src/ui/lvgl_task.cpp
@@ -54,7 +54,7 @@ void LvglMain(std::weak_ptr<drivers::RelativeWheel> weak_touch_wheel,
lv_init();
TouchWheelEncoder encoder(weak_touch_wheel);
- lv_group_t *nav_group = lv_group_create();
+ lv_group_t* nav_group = lv_group_create();
lv_group_set_default(nav_group);
lv_indev_set_group(encoder.registration(), nav_group);
diff --git a/src/ui/screen_menu.cpp b/src/ui/screen_menu.cpp
index da0a7d3c..94c8fa06 100644
--- a/src/ui/screen_menu.cpp
+++ b/src/ui/screen_menu.cpp
@@ -18,14 +18,14 @@ namespace ui {
namespace screens {
Menu::Menu() {
- lv_obj_t *menu = lv_menu_create(root_);
+ lv_obj_t* menu = lv_menu_create(root_);
lv_obj_set_size(menu, lv_disp_get_hor_res(NULL), lv_disp_get_ver_res(NULL));
lv_obj_center(menu);
- lv_obj_t *main_page = lv_menu_page_create(menu, NULL);
+ lv_obj_t* main_page = lv_menu_page_create(menu, NULL);
- lv_obj_t *container;
- lv_obj_t *label;
+ lv_obj_t* container;
+ lv_obj_t* label;
container = lv_menu_cont_create(main_page);
label = lv_label_create(container);
diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp
index f12104e6..6d53eb45 100644
--- a/src/ui/ui_fsm.cpp
+++ b/src/ui/ui_fsm.cpp
@@ -28,12 +28,14 @@ auto UiState::Init(drivers::GpioExpander* gpio_expander,
sGpioExpander = gpio_expander;
sTouchWheel = touchwheel;
sDisplay = display;
+
+ StartLvgl(sTouchWheel, sDisplay);
}
namespace states {
void PreBoot::react(const system_fsm::DisplayReady& ev) {
- transit<Splash>([&]() { StartLvgl(sTouchWheel, sDisplay); });
+ transit<Splash>();
}
void Splash::entry() {
@@ -45,7 +47,7 @@ void Splash::react(const system_fsm::BootComplete& ev) {
}
void Interactive::entry() {
- //sCurrentScreen.reset(new screens::Menu());
+ // sCurrentScreen.reset(new screens::Menu());
}
} // namespace states
diff --git a/src/ui/wheel_encoder.cpp b/src/ui/wheel_encoder.cpp
index 0129434d..3b817f61 100644
--- a/src/ui/wheel_encoder.cpp
+++ b/src/ui/wheel_encoder.cpp
@@ -9,21 +9,24 @@
namespace ui {
-void encoder_read(lv_indev_drv_t * drv, lv_indev_data_t*data){
- TouchWheelEncoder *instance = reinterpret_cast<TouchWheelEncoder*>(drv->user_data);
+void encoder_read(lv_indev_drv_t* drv, lv_indev_data_t* data) {
+ TouchWheelEncoder* instance =
+ reinterpret_cast<TouchWheelEncoder*>(drv->user_data);
instance->Read(data);
}
- TouchWheelEncoder::TouchWheelEncoder(std::weak_ptr<drivers::RelativeWheel> wheel) : wheel_(wheel) {
- lv_indev_drv_init(&driver_);
- driver_.type = LV_INDEV_TYPE_ENCODER;
- driver_.read_cb = encoder_read;
- driver_.user_data = this;
+TouchWheelEncoder::TouchWheelEncoder(
+ std::weak_ptr<drivers::RelativeWheel> wheel)
+ : wheel_(wheel) {
+ lv_indev_drv_init(&driver_);
+ driver_.type = LV_INDEV_TYPE_ENCODER;
+ driver_.read_cb = encoder_read;
+ driver_.user_data = this;
- registration_ = lv_indev_drv_register(&driver_);
- }
+ registration_ = lv_indev_drv_register(&driver_);
+}
-auto TouchWheelEncoder::Read(lv_indev_data_t *data) -> void {
+auto TouchWheelEncoder::Read(lv_indev_data_t* data) -> void {
auto lock = wheel_.lock();
if (lock == nullptr) {
data->state = LV_INDEV_STATE_RELEASED;
@@ -32,8 +35,9 @@ auto TouchWheelEncoder::Read(lv_indev_data_t *data) -> void {
}
lock->Update();
- data->state = lock->is_pressed() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
+ data->state =
+ lock->is_pressed() ? LV_INDEV_STATE_PRESSED : LV_INDEV_STATE_RELEASED;
data->enc_diff = lock->ticks();
}
-} // namespace ui
+} // namespace ui