summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRoland Reichwein <mail@reichwein.it>2025-01-20 20:39:10 +0100
committerRoland Reichwein <mail@reichwein.it>2025-01-20 20:39:10 +0100
commit5fd637644c7529bfdc5291215f3f8ee1edd304c4 (patch)
tree2f135c3cae2bc034aa27b33b39dca95b992cb69f
parentef578ac72a70bfbe8aee726d43374c841d77ade4 (diff)
Fixed status led
-rw-r--r--MainLoop.cpp187
-rw-r--r--MainLoop.h2
-rw-r--r--StatusLED.cpp41
-rw-r--r--StatusLED.h7
4 files changed, 141 insertions, 96 deletions
diff --git a/MainLoop.cpp b/MainLoop.cpp
index 2ffcc0a..b6331a2 100644
--- a/MainLoop.cpp
+++ b/MainLoop.cpp
@@ -23,6 +23,7 @@ using namespace std::chrono_literals;
using namespace std::string_literals;
MainLoop::MainLoop(int argc, char** argv):
+ m_status{},
m_config{argc, argv},
m_note_click{m_config},
m_clock_click{},
@@ -31,6 +32,8 @@ MainLoop::MainLoop(int argc, char** argv):
m_pcm{m_config},
m_ui{m_config}
{
+ m_status.add(LED{"/sys/class/leds/ACT", "/sys/class/leds/PWR"});
+ m_status.add(LED{"/sys/class/leds/thingm1:green:led1", "/sys/class/leds/thingm1:red:led1"});
}
bool run_flag = true;
@@ -60,97 +63,103 @@ void MainLoop::reconfigure_mode() {
int MainLoop::run()
{
- signal(SIGTERM, signal_handler);
- signal(SIGINT, signal_handler);
-
- //debug_cout.activate();
- log_cout.activate();
- log_cout.log_lines(log_lines);
-
- m_pcm.write();
-
- Timer timer_50ms(50ms, true);
- timer_50ms.start();
-
- Timer timer_500ms(500ms, true);
- timer_500ms.start();
-
- Timer timer_10min(10min, true);
- timer_10min.start();
-
- // Main signals
- boost::signals2::signal<void()> signal_count_loops;
-
- //
- // Signal-Slot Connections:
- //
- m_midi.signal_note.connect([&](int channel, int note, uint64_t timestamp){m_note_click.receive_note(channel, note, timestamp);});
- //m_click_connection = m_note_click.signal_click.connect([&](){m_pcm.click(0);});
- reconfigure_mode();
- m_note_click.signal_bpm.connect([&](int bpm){m_ui.slot_note_bpm(bpm);});
- m_clock_click.signal_bpm.connect([&](int bpm){m_ui.slot_clock_bpm(bpm);});
- m_midi.signal_active_sensing.connect([&](){m_ui.slot_active_sensing();});
- timer_500ms.elapsed.connect([&](){m_ui.draw();});
- signal_count_loops.connect([&](){m_ui.count_main_loops();});
- m_midi.signal_count_events.connect([&](size_t size){m_ui.count_midi_events(size);});
- timer_10min.elapsed.connect([&](){m_config.persist();});
- m_midi.signal_note.connect([&](int channel, int note, uint64_t timestamp){m_ui.slot_midi_note(channel, note, timestamp);});
- m_midi.signal_clock.connect([&](){m_clock_click.receive_clock();});
- m_config.signal_mode.connect([&](int mode){reconfigure_mode();});
- timer_50ms.elapsed.connect([&](){m_internal_click.run_cyclic_50ms();});
-
- m_midi.flush();
-
- while (run_flag) {
- debug_cout << "Main loop entered." << std::endl;
- signal_count_loops();
-
- fd_set read_set;
- FD_ZERO(&read_set);
- FD_SET(m_midi.fd(), &read_set);
- FD_SET(0, &read_set);
-
- if constexpr (0) {
- // PCM fd almost always writeable: for single frames at high speed
- fd_set write_set;
- FD_ZERO(&write_set);
- FD_SET(m_pcm.fd(), &write_set);
+ try {
+ signal(SIGTERM, signal_handler);
+ signal(SIGINT, signal_handler);
+
+ //debug_cout.activate();
+ log_cout.activate();
+ log_cout.log_lines(log_lines);
+
+ m_pcm.write();
+
+ Timer timer_50ms(50ms, true);
+ timer_50ms.start();
+
+ Timer timer_500ms(500ms, true);
+ timer_500ms.start();
+
+ Timer timer_10min(10min, true);
+ timer_10min.start();
+
+ // Main signals
+ boost::signals2::signal<void()> signal_count_loops;
+
+ //
+ // Signal-Slot Connections:
+ //
+ m_midi.signal_note.connect([&](int channel, int note, uint64_t timestamp){m_note_click.receive_note(channel, note, timestamp);});
+ //m_click_connection = m_note_click.signal_click.connect([&](){m_pcm.click(0);});
+ reconfigure_mode();
+ m_note_click.signal_bpm.connect([&](int bpm){m_ui.slot_note_bpm(bpm);});
+ m_clock_click.signal_bpm.connect([&](int bpm){m_ui.slot_clock_bpm(bpm);});
+ m_midi.signal_active_sensing.connect([&](){m_ui.slot_active_sensing();});
+ timer_500ms.elapsed.connect([&](){m_ui.draw();});
+ signal_count_loops.connect([&](){m_ui.count_main_loops();});
+ m_midi.signal_count_events.connect([&](size_t size){m_ui.count_midi_events(size);});
+ timer_10min.elapsed.connect([&](){m_config.persist();});
+ m_midi.signal_note.connect([&](int channel, int note, uint64_t timestamp){m_ui.slot_midi_note(channel, note, timestamp);});
+ m_midi.signal_clock.connect([&](){m_clock_click.receive_clock();});
+ m_config.signal_mode.connect([&](int mode){reconfigure_mode();});
+ timer_50ms.elapsed.connect([&](){m_internal_click.run_cyclic_50ms();});
+
+ m_midi.flush();
+
+ while (run_flag) {
+ debug_cout << "Main loop entered." << std::endl;
+ signal_count_loops();
+
+ fd_set read_set;
+ FD_ZERO(&read_set);
+ FD_SET(m_midi.fd(), &read_set);
+ FD_SET(0, &read_set);
+
+ if constexpr (0) {
+ // PCM fd almost always writeable: for single frames at high speed
+ fd_set write_set;
+ FD_ZERO(&write_set);
+ FD_SET(m_pcm.fd(), &write_set);
+ }
+
+ struct timeval timeout;
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 20000;
+
+ int result = select(FD_SETSIZE, &read_set, nullptr/*&write_set*/, nullptr, &timeout);
+ if (result < 0) {
+ throw std::runtime_error("select() failed");
+ } else if (result == 0) {
+ debug_cout << "select() timeout" << std::endl;
+ }
+
+ while (m_midi.event_ready())
+ {
+ //std::cout << "read..." << std::endl;
+ auto event = m_midi.read();
+ //std::cout << "process..." << std::endl;
+ m_midi.process(event);
+ }
+
+ if (m_pcm.write_available()) {
+ //std::cout << "DEBUG: WRITE" << std::endl;
+ m_pcm.write();
+ }
+
+ while (m_ui.key_available()) {
+ m_ui.handle_input();
+ }
+
+ // handle timers, TODO: make updates more efficient at scale
+ timer_50ms.update();
+ timer_500ms.update();
+ timer_10min.update();
}
- struct timeval timeout;
- timeout.tv_sec = 0;
- timeout.tv_usec = 20000;
-
- int result = select(FD_SETSIZE, &read_set, nullptr/*&write_set*/, nullptr, &timeout);
- if (result < 0) {
- throw std::runtime_error("select() failed");
- } else if (result == 0) {
- debug_cout << "select() timeout" << std::endl;
- }
-
- while (m_midi.event_ready())
- {
- //std::cout << "read..." << std::endl;
- auto event = m_midi.read();
- //std::cout << "process..." << std::endl;
- m_midi.process(event);
- }
-
- if (m_pcm.write_available()) {
- //std::cout << "DEBUG: WRITE" << std::endl;
- m_pcm.write();
- }
-
- while (m_ui.key_available()) {
- m_ui.handle_input();
- }
-
- // handle timers, TODO: make updates more efficient at scale
- timer_50ms.update();
- timer_500ms.update();
- timer_10min.update();
+ return 0;
+ } catch (const std::exception& ex) {
+ std::cerr << "Error: " << ex.what() << std::endl;
+ m_status.setMode(StatusLED::Mode::Error);
+ return 1;
}
-
- return 0;
}
diff --git a/MainLoop.h b/MainLoop.h
index bfa0084..b732c32 100644
--- a/MainLoop.h
+++ b/MainLoop.h
@@ -1,5 +1,6 @@
#pragma once
+#include "StatusLED.h"
#include "NoteClick.h"
#include "ClockClick.h"
#include "InternalClick.h"
@@ -21,6 +22,7 @@ private:
boost::signals2::connection m_click_connection;
+ StatusLED m_status;
Config m_config;
PIDFile m_pid_file{m_config.get_programname()};
diff --git a/StatusLED.cpp b/StatusLED.cpp
index 3013ddb..711257d 100644
--- a/StatusLED.cpp
+++ b/StatusLED.cpp
@@ -1,21 +1,33 @@
#include "StatusLED.h"
+#include <iostream>
+
+#include <fmt/format.h>
+#include <libreichwein/file.h>
+
namespace fs = std::filesystem;
StatusLED::StatusLED(): m_mode{Mode::OK}, m_bpm{60}
{
}
-void StatusLED::addLED(const LED& led)
+void StatusLED::add(const LED& led)
{
if (fs::exists(led.green) && fs::exists(led.red)) {
- m_leds.push_back(led);
+ if (init(led)) {
+ m_leds.push_back(led);
+ update(led);
+ }
}
}
void StatusLED::setMode(Mode mode)
{
m_mode = mode;
+
+ for (const auto& i: m_leds) {
+ update(i);
+ }
}
void StatusLED::setBPM(int bpm)
@@ -23,10 +35,31 @@ void StatusLED::setBPM(int bpm)
m_bpm = bpm;
}
-void StatusLED::initLED(const LED& led)
+bool StatusLED::init(const LED& led)
{
+ try {
+ Reichwein::File::setFile(led.green / "trigger", "none");
+ Reichwein::File::setFile(led.red / "trigger", "none");
+ return true;
+ } catch (...) {
+ return false;
+ }
}
-void StatusLED::updateLED(const LED& led)
+void StatusLED::update(const LED& led)
{
+ int green{};
+ int red{};
+
+ if (m_mode == Mode::OK) {
+ green = 255;
+ } else if (m_mode == Mode::Error) {
+ red = 255;
+ } else {
+ throw std::runtime_error("LED mode unimplemented");
+ }
+
+ Reichwein::File::setFile(led.green / "brightness", fmt::format("{}", green));
+ Reichwein::File::setFile(led.red / "brightness", fmt::format("{}", red));
}
+
diff --git a/StatusLED.h b/StatusLED.h
index b1c0f23..9348f19 100644
--- a/StatusLED.h
+++ b/StatusLED.h
@@ -22,16 +22,17 @@ public:
StatusLED();
- void addLED(const LED& led);
+ void add(const LED& led);
void setMode(Mode mode);
void setBPM(int bpm);
private:
- void initLED(const LED& led);
- void updateLED(const LED& led);
+ bool init(const LED& led);
+ void update(const LED& led);
std::vector<LED> m_leds; // on best effort base, those will all show the same status
Mode m_mode;
int m_bpm;
};
+