38 Commits

Author SHA1 Message Date
fc49f1d779 Implement monitor and overall brightness slider 2020-07-17 16:52:47 +02:00
756bb9b6a7 Remove unnecessary circular updates 2020-07-17 16:34:01 +02:00
5943b72fef Implement limits slider 2020-07-17 16:28:15 +02:00
8f4dec0bff Implement overall limit sliders 2020-07-17 16:15:52 +02:00
78f3daf1ff Remove paramater that matches the default 2020-07-17 16:10:10 +02:00
17a4890fdc Refactor clamped and rounded linear interpolation 2020-07-17 14:54:31 +02:00
e4f18911f9 Add placeholder for linux version of monitor getName 2020-07-17 14:53:30 +02:00
17a1eab03d Fix missing library for C++17 filesystem 2020-07-17 14:52:49 +02:00
69b14243bc Fix wrong indentation 2020-07-17 14:52:22 +02:00
65b4fbc484 Fix signed-unsigned comparison warning 2020-07-17 14:51:28 +02:00
5b6dd9e62c Add some GUI abstraction and implement basic monitor selection 2020-07-12 21:04:08 +02:00
994e08bebc Add function to get monitor name 2020-07-12 21:02:51 +02:00
86dbcfda4f Reset everything in monitor move constructor 2020-07-12 19:41:52 +02:00
5e4aba8140 Make sensor move constructible 2020-07-12 19:38:35 +02:00
7b791a071b Implement manual override checkboxes 2020-07-12 19:14:15 +02:00
69a68ce67c Refactor monitor tab GUI setup 2020-07-12 19:06:19 +02:00
afd6de62a0 Refactor GUI setup 2020-07-12 18:55:41 +02:00
cb9a57a24a Make placeholder values obvious 2020-07-12 18:49:11 +02:00
395e58f94d Give UI elements proper names 2020-07-12 18:44:38 +02:00
200ad19d95 Add GUI layout for monitors and sensors 2020-07-12 18:13:53 +02:00
88600b8915 Add revision 2 of PCB 2020-07-12 17:58:24 +02:00
d5dad15d0a Implement log rotation 2020-07-09 21:54:12 +02:00
7331532dfa Reflect watchdog reset with startup color 2020-07-09 20:08:20 +02:00
5169ddd4bd Set watchdog to approximately 2s and add refreshing 2020-07-09 19:58:20 +02:00
8e15ee72f3 Add watch dog timer 2020-07-09 19:41:13 +02:00
7a087c918e Remove duplicate include entries 2020-07-09 19:36:54 +02:00
962dc6ab95 Add readme to firmware 2020-07-09 18:52:36 +02:00
d88dc95a44 Rename firmware folder 2020-07-09 18:16:41 +02:00
e43629d0c0 Make manual override slider bidirectional 2020-07-08 23:12:33 +02:00
1e3596a230 Implement tray icon click 2020-07-08 23:06:38 +02:00
4bb32f0bd0 Add tray icon tool tip 2020-07-08 22:51:01 +02:00
eb18ab9f1e Change window close event to hide window 2020-07-08 22:42:24 +02:00
2253a25011 Move timer callback to separate thread 2020-07-08 22:37:02 +02:00
d1d2d4ae0a Restructure to match order in header 2020-07-08 21:51:44 +02:00
19d73640c7 Properly destroy physical monitor handle 2020-07-08 21:50:49 +02:00
927c318f54 Make info LEDs dependent on flag not debug build 2020-07-08 00:34:32 +02:00
ab8b1bfbbe Change default firmware build to release 2020-07-08 00:34:02 +02:00
d3d80a2062 Add hardware design, schematic, and gerber files 2020-07-07 17:53:51 +02:00
137 changed files with 7882 additions and 168 deletions

View File

@@ -1,13 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"> <ui version="4.0">
<class>AdaptiveBrightnessClass</class> <class>MainWindow</class>
<widget class="QMainWindow" name="AdaptiveBrightnessClass"> <widget class="QMainWindow" name="MainWindow">
<property name="geometry"> <property name="geometry">
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>406</width> <width>450</width>
<height>306</height> <height>555</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">
@@ -17,48 +17,523 @@
<iconset resource="AdaptiveBrightness.qrc"> <iconset resource="AdaptiveBrightness.qrc">
<normaloff>:/AdaptiveBrightness/resources/system.ico</normaloff>:/AdaptiveBrightness/resources/system.ico</iconset> <normaloff>:/AdaptiveBrightness/resources/system.ico</normaloff>:/AdaptiveBrightness/resources/system.ico</iconset>
</property> </property>
<widget class="QWidget" name="centralWidget"> <widget class="QWidget" name="mainWidget">
<layout class="QFormLayout" name="formLayout_2"> <layout class="QGridLayout" name="gridLayout_3">
<item row="0" column="1"> <item row="0" column="1">
<widget class="QGroupBox" name="groupBox"> <widget class="QTabWidget" name="tabs">
<property name="title"> <property name="currentIndex">
<string>Manual brightness control</string> <number>0</number>
</property> </property>
<layout class="QGridLayout" name="gridLayout"> <widget class="QWidget" name="monitorTab">
<item row="0" column="0"> <attribute name="title">
<widget class="QSlider" name="horizontalSlider"> <string>Monitors</string>
<property name="toolTip"> </attribute>
<string>Brightness</string> <layout class="QGridLayout" name="gridLayout_12">
</property> <item row="0" column="0" colspan="2">
<property name="orientation"> <widget class="QGroupBox" name="monitorGroup">
<enum>Qt::Horizontal</enum> <property name="title">
</property> <string>Monitor</string>
</widget> </property>
</item> <layout class="QGridLayout" name="gridLayout_11">
</layout> <item row="0" column="0">
<widget class="QComboBox" name="monitorDropdown">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="monitorEnumerateButton">
<property name="text">
<string>Re-enumerate</string>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="monitorLimitsGroup">
<property name="title">
<string>Limits</string>
</property>
<layout class="QGridLayout" name="gridLayout_9">
<item row="1" column="1">
<widget class="QSlider" name="monitorMaxBrightnessSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="monitorMinBrightnessLabel">
<property name="text">
<string>Minimum</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="monitorMinBrightnessSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="monitorMaxBrightnessLabel">
<property name="text">
<string>Maximum</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="monitorMinBrightnessValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="monitorMaxBrightnessValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="monitorBrightnessGroup">
<property name="title">
<string>Brightness</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QSlider" name="monitorBrightnessSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="monitorOverrideCheck">
<property name="text">
<string>Manual override</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="monitorBrightnessValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="monitorOverallLimitsGroup">
<property name="title">
<string>Overall limits</string>
</property>
<layout class="QGridLayout" name="gridLayout_10">
<item row="0" column="0">
<widget class="QLabel" name="monitorOverallMinBrightnessLabel">
<property name="text">
<string>Minimum</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QSlider" name="monitorOverallMinBrightnessSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="monitorOverallMinBrightnessValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="monitorOverallMaxBrightnessLabel">
<property name="text">
<string>Maximum</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSlider" name="monitorOverallMaxBrightnessSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="monitorOverallMaxBrightnessValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0" colspan="2">
<spacer name="monitorBottomSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>218</width>
<height>35</height>
</size>
</property>
</spacer>
</item>
<item row="5" column="0">
<widget class="QPushButton" name="monitorResetButton">
<property name="text">
<string>Restore all monitors to defaults</string>
</property>
</widget>
</item>
<item row="5" column="1">
<spacer name="monitorResetSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<widget class="QGroupBox" name="monitorOverallBrightnessGroup">
<property name="title">
<string>Overall brightness</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QSlider" name="monitorOverallBrightnessSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="monitorOverallBrightnessValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="monitorOverallOverrideCheck">
<property name="text">
<string>Manual override</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<spacer name="monitorTopSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<widget class="QWidget" name="sensorsTab">
<attribute name="title">
<string>Sensors</string>
</attribute>
<layout class="QGridLayout" name="gridLayout_8">
<item row="0" column="0" colspan="2">
<widget class="QGroupBox" name="sensorGroup">
<property name="title">
<string>Sensor module</string>
</property>
<layout class="QGridLayout" name="gridLayout_6">
<item row="0" column="1">
<widget class="QPushButton" name="sensorEnumerateButton">
<property name="text">
<string>Re-enumerate</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QComboBox" name="sensorDropdown">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="0" colspan="2">
<widget class="QGroupBox" name="sensorReadoutGroup">
<property name="title">
<string>Readout</string>
</property>
<layout class="QGridLayout" name="gridLayout_5">
<item row="0" column="0">
<widget class="QTreeWidget" name="sensorReadoutValues">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::NoFrame</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Plain</enum>
</property>
<property name="verticalScrollBarPolicy">
<enum>Qt::ScrollBarAlwaysOff</enum>
</property>
<property name="sizeAdjustPolicy">
<enum>QAbstractScrollArea::AdjustToContents</enum>
</property>
<property name="indentation">
<number>0</number>
</property>
<column>
<property name="text">
<string>Sensor</string>
</property>
</column>
<column>
<property name="text">
<string>Raw value</string>
</property>
</column>
<column>
<property name="text">
<string>Percentage</string>
</property>
</column>
<item>
<property name="text">
<string>LDR1: Front</string>
</property>
<property name="text">
<string>XXXX</string>
</property>
<property name="text">
<string>XXX%</string>
</property>
</item>
<item>
<property name="text">
<string>LDR2: Bottom</string>
</property>
<property name="text">
<string>XXXX</string>
</property>
<property name="text">
<string>XXX%</string>
</property>
</item>
<item>
<property name="text">
<string>LDR3: Top</string>
</property>
<property name="text">
<string>XXXX</string>
</property>
<property name="text">
<string>XXX%</string>
</property>
</item>
</widget>
</item>
</layout>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="sensorAggregationGroup">
<property name="title">
<string>Sensor aggregation</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="sensorAggregationFunctionLabel">
<property name="text">
<string>Function</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="sensorAggregationFunctionDropdown">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="sensorAggregationResultLabel">
<property name="text">
<string>Module result:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="sensorAggregationValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item row="4" column="0">
<widget class="QPushButton" name="sensorResetButton">
<property name="text">
<string>Restore all sensors to defaults</string>
</property>
</widget>
</item>
<item row="4" column="1">
<spacer name="sensorResetSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="2" column="0" colspan="2">
<widget class="QGroupBox" name="sensorTotalAggregationGroup">
<property name="title">
<string>Total aggregation</string>
</property>
<layout class="QGridLayout" name="gridLayout_7">
<item row="0" column="0">
<widget class="QLabel" name="sensorTotalAggregationFunctionLabel">
<property name="text">
<string>Function</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QComboBox" name="sensorTotalAggregationFunctionDropdown">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLabel" name="sensorTotalAggregationResultLabel">
<property name="text">
<string>Result:</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QLabel" name="sensorTotalAggregationValueLabel">
<property name="text">
<string>XXX%</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item row="1" column="0" colspan="2">
<spacer name="sensorTopSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="0" colspan="2">
<spacer name="sensorBottomSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</widget> </widget>
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>406</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget> </widget>
<layoutdefault spacing="6" margin="11"/> <layoutdefault spacing="6" margin="11"/>
<resources> <resources>

View File

@@ -1,14 +1,50 @@
#pragma once #pragma once
#include <filesystem>
#include <string>
#include <vector>
#include <cstddef>
#include <QDateTime> #include <QDateTime>
#include <QFile> #include <QFile>
#include <QMessageLogger> #include <QMessageLogger>
#include <QString> #include <QString>
#include <QTextStream> #include <QTextStream>
static inline void rotateLog(const std::filesystem::path& logFileName, int numRotatingLogs)
{
const auto generateRotateNames = [&]() {
std::vector<QString> rotateFileNames = {QString().fromStdString(logFileName.string())};
for(int i = 1; i < numRotatingLogs; ++i) {
auto rotateName = logFileName.stem();
rotateName += std::string(".") + std::to_string(i);
rotateName += logFileName.extension();
rotateFileNames.push_back(QString().fromStdString(rotateName.string()));
}
return rotateFileNames;
};
const auto rotateFileNames = generateRotateNames();
for(auto i = static_cast<int>(rotateFileNames.size()) - 2; i >= 0; --i) {
QFile file(rotateFileNames[i]);
QFile newFile(rotateFileNames[i + 1]);
if(file.exists()) {
newFile.remove();
file.rename(rotateFileNames[i + 1]);
}
}
}
void logToFile(QtMsgType msgType, [[maybe_unused]] const QMessageLogContext& msgContext, const QString& msg) void logToFile(QtMsgType msgType, [[maybe_unused]] const QMessageLogContext& msgContext, const QString& msg)
{ {
constexpr auto LOG_FILE = "AdaptiveBrightness.log"; constexpr auto MAX_LOG_FILE_SIZE = 4 /*MiB*/ * 1024 * 1024;
constexpr auto NUM_ROTATING_LOGS = 4;
const auto logFileName = std::filesystem::path{"AdaptiveBrightness.log"};
const auto dateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz"); const auto dateTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz");
QString formattedMsg = QString("[%1] ").arg(dateTime); QString formattedMsg = QString("[%1] ").arg(dateTime);
@@ -48,9 +84,15 @@ void logToFile(QtMsgType msgType, [[maybe_unused]] const QMessageLogContext& msg
formattedMsg += QString("%1").arg(msg); formattedMsg += QString("%1").arg(msg);
QFile logFile(LOG_FILE); QFile logFile(QString().fromStdString(logFileName.string()));
logFile.open(QIODevice::WriteOnly | QIODevice::Append); logFile.open(QIODevice::WriteOnly | QIODevice::Append);
if(logFile.size() > MAX_LOG_FILE_SIZE) {
logFile.close();
rotateLog(logFileName, NUM_ROTATING_LOGS);
logFile.open(QIODevice::WriteOnly | QIODevice::Append);
}
#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) #if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)
constexpr auto qtEndl = Qt::endl; constexpr auto qtEndl = Qt::endl;
#else #else

View File

@@ -5,8 +5,11 @@
#include <cmath> #include <cmath>
#include <QCloseEvent>
#include <QGroupBox> #include <QGroupBox>
#include <QSlider> #include <QSlider>
#include <QTabWidget>
#include <QWidget>
#include <QtDebug> #include <QtDebug>
#include <QtGlobal> #include <QtGlobal>
@@ -20,63 +23,53 @@ MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
qDebug(ltr("Creating main window")); qDebug(ltr("Creating main window"));
m_ui.setupUi(this); m_ui.setupUi(this);
auto slider = m_ui.centralWidget->findChild<QGroupBox*>("groupBox")->findChild<QSlider*>("horizontalSlider");
if(slider) { enumSensors();
connect(slider, &QSlider::valueChanged, [this](int value) { enumMonitors();
const auto mappedBrightness = utils::map(value, 0, 100, 0.f, 1.f);
const auto newBrightness = std::clamp(mappedBrightness, 0.f, 1.f);
qDebug(ltr("Overriding brightness with %1").arg(newBrightness));
m_brightness = newBrightness;
});
}
loadIcons(); setupMonitorsTab();
if(!QSystemTrayIcon::isSystemTrayAvailable()) { setupTrayIcon();
qWarning(ltr("System tray is not available -> tray icon will be disabled"));
}
else {
qDebug(ltr("System tray is available"));
m_trayIconMenu = new QMenu(this); setupCallbackTimer();
m_showHideAction = m_trayIconMenu->addAction(tr("Show"), [this]() {
if(m_visibility) {
m_showHideAction->setText(tr("Show"));
hide();
}
else {
m_showHideAction->setText(tr("Hide"));
show();
}
m_visibility = !m_visibility;
});
m_trayIconMenu->addSeparator();
m_trayIconMenu->addAction(tr("Quit"), this, &QWidget::close);
qDebug(ltr("Tray icon context menu initialized"));
m_trayIcon = new QSystemTrayIcon(this);
m_trayIcon->setIcon(*m_errorIcon);
m_trayIcon->setContextMenu(m_trayIconMenu);
m_trayIcon->show();
qDebug(ltr("Tray icon initialized"));
}
m_timer = new QTimer(this);
connect(m_timer, &QTimer::timeout, this, &MainWindow::updateState);
m_timer->start(1000);
qDebug(ltr("Tray icon update timer started"));
m_sensors = enumerateSensors();
m_monitors = enumerateMonitors();
} }
MainWindow::~MainWindow() MainWindow::~MainWindow()
{ {
qDebug(ltr("Destroying main window")); qDebug(ltr("Destroying main window"));
m_timerThread->quit();
if(!m_timerThread->wait()) {
qCritical(ltr("Timer thread did not terminate cleanly"));
}
}
void MainWindow::closeEvent(QCloseEvent* event)
{
m_showHideAction->activate(QAction::Trigger);
event->ignore();
}
void MainWindow::enumSensors()
{
auto sensors = enumerateSensors();
for(auto& sensor: sensors) {
m_sensors.push_back({std::move(sensor)});
}
}
void MainWindow::enumMonitors()
{
m_ui.monitorDropdown->clear();
auto monitors = enumerateMonitors();
for(auto& monitor: monitors) {
const auto currentBrightness = monitor.getBrightness();
m_ui.monitorDropdown->addItem(monitor.getName());
m_monitors.push_back({std::move(monitor), 0.f, 1.f, currentBrightness, false});
}
} }
void MainWindow::loadIcons() void MainWindow::loadIcons()
@@ -114,13 +107,170 @@ void MainWindow::loadIcons()
qDebug(ltr("Icons loaded")); qDebug(ltr("Icons loaded"));
} }
void MainWindow::setupMonitorsTab()
{
connect(m_ui.monitorDropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::updateCurrentMonitorGUI);
setupLimitsSlider();
setupOverallLimitsSlider();
setupBrightness();
setupOverallBrightness();
}
void MainWindow::setupLimitsSlider()
{
connect(m_ui.monitorMinBrightnessSlider, &QSlider::valueChanged, [this](int value) {
m_ui.monitorMinBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
if(value > m_ui.monitorMaxBrightnessSlider->value()) {
m_ui.monitorMaxBrightnessSlider->setValue(value);
}
const auto curIdx = m_ui.monitorDropdown->currentIndex();
m_monitors[curIdx].minBrightness = utils::map(value, 0, 100, 0.f, 1.f);
});
connect(m_ui.monitorMaxBrightnessSlider, &QSlider::valueChanged, [this](int value) {
m_ui.monitorMaxBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
if(value < m_ui.monitorMinBrightnessSlider->value()) {
m_ui.monitorMinBrightnessSlider->setValue(value);
}
const auto curIdx = m_ui.monitorDropdown->currentIndex();
m_monitors[curIdx].maxBrightness = utils::map(value, 0, 100, 0.f, 1.f);
});
}
void MainWindow::setupOverallLimitsSlider()
{
connect(m_ui.monitorOverallMinBrightnessSlider, &QSlider::valueChanged, [this](int value) {
m_ui.monitorOverallMinBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
if(value > m_ui.monitorOverallMaxBrightnessSlider->value()) {
m_ui.monitorOverallMaxBrightnessSlider->setValue(value);
}
for(auto& monitor: m_monitors) {
monitor.minBrightness = utils::map(value, 0, 100, 0.f, 1.f);
}
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
});
connect(m_ui.monitorOverallMaxBrightnessSlider, &QSlider::valueChanged, [this](int value) {
m_ui.monitorOverallMaxBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
if(value < m_ui.monitorOverallMinBrightnessSlider->value()) {
m_ui.monitorOverallMinBrightnessSlider->setValue(value);
}
for(auto& monitor: m_monitors) {
monitor.maxBrightness = utils::map(value, 0, 100, 0.f, 1.f);
}
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
});
}
void MainWindow::setupBrightness()
{
m_ui.monitorBrightnessSlider->setDisabled(true);
connect(m_ui.monitorBrightnessSlider, &QSlider::valueChanged, [this](int value) {
m_ui.monitorBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
const auto newBrightness = utils::map(value, 0, 100, 0.f, 1.f);
qDebug(ltr("Overriding brightness with %1").arg(newBrightness));
const auto curIdx = m_ui.monitorDropdown->currentIndex();
m_monitors[curIdx].brightness = newBrightness;
});
m_ui.monitorOverrideCheck->setChecked(false);
connect(m_ui.monitorOverrideCheck, &QCheckBox::stateChanged, [this](int state) {
m_ui.monitorBrightnessSlider->setEnabled(state == Qt::CheckState::Checked);
const auto curIdx = m_ui.monitorDropdown->currentIndex();
m_monitors[curIdx].manualOverride = state == Qt::CheckState::Checked;
});
}
void MainWindow::setupOverallBrightness()
{
m_ui.monitorOverallBrightnessSlider->setDisabled(true);
connect(m_ui.monitorOverallBrightnessSlider, &QSlider::valueChanged, [this](int value) {
m_ui.monitorOverallBrightnessValueLabel->setText(tr("%1%").arg(value, 3));
const auto newBrightness = utils::map(value, 0, 100, 0.f, 1.f);
qDebug(ltr("Overriding overall brightness with %1").arg(newBrightness));
for(auto& monitor: m_monitors) {
monitor.brightness = newBrightness;
}
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
});
m_ui.monitorOverallOverrideCheck->setChecked(false);
connect(m_ui.monitorOverallOverrideCheck, &QCheckBox::stateChanged, [this](int state) {
m_ui.monitorOverallBrightnessSlider->setEnabled(state == Qt::CheckState::Checked);
for(auto& monitor: m_monitors) {
monitor.manualOverride = state == Qt::CheckState::Checked;
}
updateCurrentMonitorGUI(m_ui.monitorDropdown->currentIndex());
});
}
void MainWindow::setupTrayIcon()
{
loadIcons();
if(!QSystemTrayIcon::isSystemTrayAvailable()) {
qWarning(ltr("System tray is not available -> tray icon will be disabled"));
}
else {
qDebug(ltr("System tray is available"));
m_trayIconMenu = new QMenu(this);
m_showHideAction = m_trayIconMenu->addAction(tr("Show"), [this]() {
if(m_visibility) {
m_showHideAction->setText(tr("Show"));
hide();
}
else {
m_showHideAction->setText(tr("Hide"));
show();
}
m_visibility = !m_visibility;
});
m_trayIconMenu->addSeparator();
m_trayIconMenu->addAction(tr("Quit"), this, &QCoreApplication::quit);
qDebug(ltr("Tray icon context menu initialized"));
m_trayIcon = new QSystemTrayIcon(this);
m_trayIcon->setIcon(*m_errorIcon);
m_trayIcon->setContextMenu(m_trayIconMenu);
m_trayIcon->show();
m_trayIcon->setToolTip(tr("AdaptiveBrightness"));
connect(m_trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::trayIconClicked);
qDebug(ltr("Tray icon initialized"));
}
}
void MainWindow::setupCallbackTimer()
{
m_timerThread = new QThread(this);
m_timer = new QTimer(nullptr);
m_timer->setInterval(1000);
m_timer->moveToThread(m_timerThread);
m_timerThread->connect(m_timer, &QTimer::timeout, this, &MainWindow::updateState, Qt::DirectConnection);
m_timer->connect(m_timerThread, SIGNAL(started()), SLOT(start()));
m_timerThread->start();
qDebug(ltr("Callback timer started"));
}
void MainWindow::updateCurrentMonitorGUI(int index)
{
m_ui.monitorMinBrightnessSlider->setValue(utils::map(m_monitors[index].minBrightness, 0.f, 1.f, 0, 100));
m_ui.monitorMaxBrightnessSlider->setValue(utils::map(m_monitors[index].maxBrightness, 0.f, 1.f, 0, 100));
m_ui.monitorBrightnessSlider->setValue(utils::map(m_monitors[index].brightness, 0.f, 1.f, 0, 100));
m_ui.monitorOverrideCheck->setChecked(m_monitors[index].manualOverride);
}
void MainWindow::updateState() void MainWindow::updateState()
{ {
qDebug(ltr("Updating state")); qDebug(ltr("Updating state"));
bool sensorError = false; bool sensorError = false;
bool monitorError = false; bool monitorError = false;
size_t iconBrightness = 0;
const auto getAverageSensorValue = [this](float& brightness) { const auto getAverageSensorValue = [this](float& brightness) {
if(m_sensors.empty()) { if(m_sensors.empty()) {
@@ -130,8 +280,8 @@ void MainWindow::updateState()
std::vector<float> values; std::vector<float> values;
for(auto& sensor: m_sensors) { for(auto& sensor: m_sensors) {
const auto sensorValues = sensor.readValues(); const auto sensorValues = sensor.driver.readValues();
if(!sensor) { if(!sensor.driver) {
return false; return false;
} }
values.insert(values.end(), sensorValues.begin(), sensorValues.end()); values.insert(values.end(), sensorValues.begin(), sensorValues.end());
@@ -148,24 +298,26 @@ void MainWindow::updateState()
bool errorOccurred = false; bool errorOccurred = false;
for(auto& monitor: m_monitors) { for(auto& monitor: m_monitors) {
if(!monitor.setBrightness(brightness)) { monitor.brightness = monitor.manualOverride ? monitor.brightness : brightness;
if(!monitor.driver.setBrightness(monitor.brightness)) {
errorOccurred = true; errorOccurred = true;
} }
} }
return !errorOccurred; return !errorOccurred;
}; };
if(!getAverageSensorValue(m_brightness)) { auto brightness = 0.5f;
m_sensors = enumerateSensors();
if(!getAverageSensorValue(brightness)) {
enumSensors();
qInfo(ltr("At least one sensor became invalid, re-enumerating sensors found %1 valid sensor(s)").arg(m_sensors.size())); qInfo(ltr("At least one sensor became invalid, re-enumerating sensors found %1 valid sensor(s)").arg(m_sensors.size()));
sensorError = true; sensorError = true;
} }
const auto roundedBrightness = std::round(utils::map(m_brightness, 0.f, 1.f, 0, 8)); const auto iconBrightness = utils::map(brightness, 0.f, 1.f, size_t{0}, size_t{8});
iconBrightness = std::clamp<size_t>(roundedBrightness, 0, 8);
if(!setAllMonitorsBrightness(m_brightness)) { if(!setAllMonitorsBrightness(brightness)) {
m_monitors = enumerateMonitors(); enumMonitors();
qInfo(ltr("At least one monitor became invalid, re-enumerating monitors found %1 valid monitor(s)").arg(m_monitors.size())); qInfo(ltr("At least one monitor became invalid, re-enumerating monitors found %1 valid monitor(s)").arg(m_monitors.size()));
monitorError = true; monitorError = true;
} }
@@ -179,4 +331,15 @@ void MainWindow::updateState()
else if(m_trayIcon) { else if(m_trayIcon) {
m_trayIcon->setIcon(*m_errorIcon); m_trayIcon->setIcon(*m_errorIcon);
} }
if(m_trayIcon) {
m_trayIcon->setToolTip(tr("AdaptiveBrightness - %1%").arg(brightness * 100, 0, 'f', 0));
}
}
void MainWindow::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::ActivationReason::Trigger) {
m_showHideAction->trigger();
}
} }

View File

@@ -8,7 +8,9 @@
#include <QIcon> #include <QIcon>
#include <QMainWindow> #include <QMainWindow>
#include <QMenu> #include <QMenu>
#include <QSlider>
#include <QSystemTrayIcon> #include <QSystemTrayIcon>
#include <QThread>
#include <QTimer> #include <QTimer>
#include "monitor.hpp" #include "monitor.hpp"
@@ -24,11 +26,29 @@ class MainWindow : public QMainWindow {
~MainWindow(); ~MainWindow();
private: private:
void closeEvent(QCloseEvent* event) override;
void enumSensors();
void enumMonitors();
void loadIcons(); void loadIcons();
void setupMonitorsTab();
void setupLimitsSlider();
void setupOverallLimitsSlider();
void setupBrightness();
void setupOverallBrightness();
void setupTrayIcon();
void setupCallbackTimer();
void updateCurrentMonitorGUI(int index);
void updateState(); void updateState();
Ui::AdaptiveBrightnessClass m_ui; void trayIconClicked(QSystemTrayIcon::ActivationReason reason);
Ui::MainWindow m_ui;
std::array<std::unique_ptr<QIcon>, 9> m_noSensorStateIcons; std::array<std::unique_ptr<QIcon>, 9> m_noSensorStateIcons;
std::array<std::unique_ptr<QIcon>, 9> m_sensorStateIcons; std::array<std::unique_ptr<QIcon>, 9> m_sensorStateIcons;
@@ -39,10 +59,21 @@ class MainWindow : public QMainWindow {
QMenu* m_trayIconMenu = nullptr; QMenu* m_trayIconMenu = nullptr;
QSystemTrayIcon* m_trayIcon = nullptr; QSystemTrayIcon* m_trayIcon = nullptr;
QThread* m_timerThread = nullptr;
QTimer* m_timer = nullptr; QTimer* m_timer = nullptr;
float m_brightness = 0.5f; struct SensorData {
Sensor driver;
};
std::vector<Sensor> m_sensors; struct MonitorData {
std::vector<Monitor> m_monitors; Monitor driver;
float minBrightness;
float maxBrightness;
float brightness;
bool manualOverride;
};
std::vector<SensorData> m_sensors;
std::vector<MonitorData> m_monitors;
}; };

View File

@@ -10,6 +10,8 @@
#include <physicalmonitorenumerationapi.h> #include <physicalmonitorenumerationapi.h>
#include <windows.h> #include <windows.h>
#include <QString>
namespace detail { namespace detail {
extern BOOL enumMonitorsCallback(HMONITOR, HDC, LPRECT, LPARAM); extern BOOL enumMonitorsCallback(HMONITOR, HDC, LPRECT, LPARAM);
@@ -19,11 +21,15 @@ extern BOOL enumMonitorsCallback(HMONITOR, HDC, LPRECT, LPARAM);
class Monitor { class Monitor {
public: public:
Monitor() = delete; Monitor() = delete;
Monitor(const Monitor&) = delete;
Monitor(Monitor&& other) noexcept;
~Monitor(); ~Monitor();
bool setBrightness(float percentage); bool setBrightness(float percentage);
float getBrightness(); float getBrightness();
QString getName() const;
operator bool() const; operator bool() const;
private: private:
@@ -36,8 +42,8 @@ class Monitor {
friend BOOL detail::enumMonitorsCallback(HMONITOR, HDC, LPRECT, LPARAM); friend BOOL detail::enumMonitorsCallback(HMONITOR, HDC, LPRECT, LPARAM);
const HMONITOR m_hMonitor; HMONITOR m_hMonitor;
const PhysicalMonitor m_physicalMonitor; PhysicalMonitor m_physicalMonitor;
std::optional<std::pair<DWORD, DWORD>> m_brightnessRange; std::optional<std::pair<DWORD, DWORD>> m_brightnessRange;
bool m_errorOccurred = false; bool m_errorOccurred = false;
@@ -51,6 +57,8 @@ class Monitor {
#if defined(__clang__) || defined(__GNUC__) #if defined(__clang__) || defined(__GNUC__)
#include <QString>
class Monitor { class Monitor {
public: public:
Monitor(); Monitor();
@@ -58,6 +66,8 @@ class Monitor {
bool setBrightness(float); bool setBrightness(float);
float getBrightness(); float getBrightness();
QString getName() const;
operator bool() const; operator bool() const;
private: private:

View File

@@ -28,14 +28,14 @@ static BOOL enumMonitorsCallback(HMONITOR hMonitor, [[maybe_unused]] HDC hDC, [[
} }
for(const auto& physicalMonitor: physicalMonitors) { for(const auto& physicalMonitor: physicalMonitors) {
const auto monitor = Monitor(hMonitor, physicalMonitor); auto monitor = Monitor(hMonitor, physicalMonitor);
if(monitor.hasBrightnessCapability()) { if(monitor.hasBrightnessCapability()) {
qInfo(ltr("Found brightness capable monitor '%1' with handle '0x%2' and physical handle '0x%3'") qInfo(ltr("Found brightness capable monitor '%1' with handle '0x%2' and physical handle '0x%3'")
.arg(monitor.m_physicalMonitor.name) .arg(monitor.m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(monitor.m_hMonitor), 0, 16) .arg(reinterpret_cast<qulonglong>(monitor.m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(monitor.m_physicalMonitor.handle), 0, 16)); .arg(reinterpret_cast<qulonglong>(monitor.m_physicalMonitor.handle), 0, 16));
monitors.push_back(monitor); monitors.push_back(std::move(monitor));
} }
} }

View File

@@ -26,6 +26,12 @@ float Monitor::getBrightness()
return NAN; return NAN;
} }
QString Monitor::getName() const
{
qWarning(ltr("Getting monitor name not implemented"));
return "Unknown";
}
Monitor::operator bool() const Monitor::operator bool() const
{ {
qWarning(ltr("Checking monitor validity not implemented")); qWarning(ltr("Checking monitor validity not implemented"));

View File

@@ -15,14 +15,17 @@
#include "log_tr.hpp" #include "log_tr.hpp"
#include "utils.hpp" #include "utils.hpp"
Monitor::Monitor(HMONITOR hMonitor, PHYSICAL_MONITOR physicalMonitor) Monitor::Monitor(Monitor&& other) noexcept
: m_hMonitor(hMonitor) : m_hMonitor(other.m_hMonitor)
, m_physicalMonitor(physicalMonitor.hPhysicalMonitor, physicalMonitor.szPhysicalMonitorDescription) , m_physicalMonitor(other.m_physicalMonitor)
, m_brightnessRange(other.m_brightnessRange)
, m_errorOccurred(other.m_errorOccurred)
{ {
qDebug(ltr("Creating monitor '%1' with handle '0x%2' and physical handle '0x%3'") other.m_hMonitor = 0;
.arg(m_physicalMonitor.name) other.m_physicalMonitor.name.clear();
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16) other.m_physicalMonitor.handle = 0;
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16)); other.m_brightnessRange.reset();
other.m_errorOccurred = false;
} }
Monitor::~Monitor() Monitor::~Monitor()
@@ -31,6 +34,14 @@ Monitor::~Monitor()
.arg(m_physicalMonitor.name) .arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16) .arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16)); .arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16));
if(m_physicalMonitor.handle && !DestroyPhysicalMonitor(m_physicalMonitor.handle)) {
qCritical(ltr("Error occurred while destroying monitor '%1' with handle '0x%2' and physical handle '0x%3', error: %4")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16)
.arg(getLastErrorString()));
}
} }
bool Monitor::setBrightness(float percentage) bool Monitor::setBrightness(float percentage)
@@ -53,8 +64,7 @@ bool Monitor::setBrightness(float percentage)
return false; return false;
} }
const auto mappedBrightness = utils::map(percentage, 0.f, 1.f, m_brightnessRange->first, m_brightnessRange->second); const auto newBrightness = utils::map(percentage, 0.f, 1.f, m_brightnessRange->first, m_brightnessRange->second);
const auto newBrightness = std::clamp<DWORD>(std::round(mappedBrightness), m_brightnessRange->first, m_brightnessRange->second);
if(!SetMonitorBrightness(m_physicalMonitor.handle, newBrightness)) { if(!SetMonitorBrightness(m_physicalMonitor.handle, newBrightness)) {
qCritical(ltr("Failed to set brightness of monitor '%1' with handle '0x%2' and physical handle '0x%3', error: %4") qCritical(ltr("Failed to set brightness of monitor '%1' with handle '0x%2' and physical handle '0x%3', error: %4")
@@ -99,7 +109,15 @@ float Monitor::getBrightness()
m_brightnessRange = std::pair{minBrightness, maxBrightness}; m_brightnessRange = std::pair{minBrightness, maxBrightness};
m_errorOccurred = false; m_errorOccurred = false;
return std::clamp(utils::map(brightness, minBrightness, maxBrightness, 0.f, 1.f), 0.f, 1.f); return utils::map(brightness, minBrightness, maxBrightness, 0.f, 1.f);
}
QString Monitor::getName() const
{
return QString("%1 (0x%2:0x%3)")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16);
} }
Monitor::operator bool() const Monitor::operator bool() const
@@ -107,6 +125,16 @@ Monitor::operator bool() const
return !m_errorOccurred; return !m_errorOccurred;
} }
Monitor::Monitor(HMONITOR hMonitor, PHYSICAL_MONITOR physicalMonitor)
: m_hMonitor(hMonitor)
, m_physicalMonitor(physicalMonitor.hPhysicalMonitor, physicalMonitor.szPhysicalMonitorDescription)
{
qDebug(ltr("Creating monitor '%1' with handle '0x%2' and physical handle '0x%3'")
.arg(m_physicalMonitor.name)
.arg(reinterpret_cast<qulonglong>(m_hMonitor), 0, 16)
.arg(reinterpret_cast<qulonglong>(m_physicalMonitor.handle), 0, 16));
}
bool Monitor::hasBrightnessCapability() const bool Monitor::hasBrightnessCapability() const
{ {
qDebug(ltr("Getting capabilities of monitor '%1' with handle '0x%2' and physical handle '0x%3'") qDebug(ltr("Getting capabilities of monitor '%1' with handle '0x%2' and physical handle '0x%3'")

View File

@@ -15,6 +15,13 @@ Sensor::~Sensor()
qDebug(ltr("Destroying sensor on serial port %1").arg(m_serialPortName)); qDebug(ltr("Destroying sensor on serial port %1").arg(m_serialPortName));
} }
Sensor::Sensor(Sensor&& other) noexcept : m_serialPortName(other.m_serialPortName), m_errorOccurred(other.m_errorOccurred), m_range(other.m_range)
{
other.m_serialPortName.clear();
other.m_errorOccurred = false;
other.m_range.reset();
}
std::vector<float> Sensor::readValues() std::vector<float> Sensor::readValues()
{ {
qDebug(ltr("Reading values of sensor on port %1").arg(m_serialPortName)); qDebug(ltr("Reading values of sensor on port %1").arg(m_serialPortName));
@@ -40,8 +47,7 @@ std::vector<float> Sensor::readValues()
std::vector<float> normalizedValues; std::vector<float> normalizedValues;
for(const auto& value: values) { for(const auto& value: values) {
const auto mappedValue = utils::map(value, m_range->first, m_range->second, 0.f, 1.f); normalizedValues.push_back(utils::map(value, m_range->first, m_range->second, 0.f, 1.f));
normalizedValues.push_back(std::clamp(mappedValue, 0.f, 1.f));
} }
return normalizedValues; return normalizedValues;

View File

@@ -11,6 +11,8 @@
class Sensor { class Sensor {
public: public:
Sensor(const Sensor&) = delete;
Sensor(Sensor&& other) noexcept;
~Sensor(); ~Sensor();
std::vector<float> readValues(); std::vector<float> readValues();
@@ -26,7 +28,7 @@ class Sensor {
static constexpr auto SUPPORTED_FIRMWARE = std::string_view{"AdaptiveBrightness v1.2"}; static constexpr auto SUPPORTED_FIRMWARE = std::string_view{"AdaptiveBrightness v1.2"};
const QString m_serialPortName; QString m_serialPortName;
bool m_errorOccurred = false; bool m_errorOccurred = false;
std::optional<std::pair<int, int>> m_range; std::optional<std::pair<int, int>> m_range;

View File

@@ -21,7 +21,7 @@ std::vector<Sensor> enumerateSensors()
auto sensor = Sensor(portInfo.portName()); auto sensor = Sensor(portInfo.portName());
if(sensor.isValidSensor()) { if(sensor.isValidSensor()) {
qInfo(ltr("Successfully enumerated sensor on port %1").arg(portInfo.portName())); qInfo(ltr("Successfully enumerated sensor on port %1").arg(portInfo.portName()));
sensors.push_back(sensor); sensors.push_back(std::move(sensor));
} }
} }

View File

@@ -1,17 +1,30 @@
#pragma once #pragma once
#include <algorithm>
#include <array> #include <array>
#include <type_traits>
#include <cmath>
#include <cstddef> #include <cstddef>
namespace utils { namespace utils {
template<typename InType, typename OutType> template<typename InType, typename OutType>
auto map(InType value, InType inMin, InType inMax, OutType outMin, OutType outMax) auto interpolate(InType value, InType inMin, InType inMax, OutType outMin, OutType outMax)
{ {
return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin; return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
} }
template<typename InType, typename OutType>
auto map(InType value, InType inMin, InType inMax, OutType outMin, OutType outMax)
{
if constexpr(std::is_integral_v<OutType>) {
return std::clamp(static_cast<OutType>(std::round(interpolate(value, inMin, inMax, outMin, outMax))), outMin, outMax);
}
return std::clamp(static_cast<OutType>(interpolate(value, inMin, inMax, outMin, outMax)), outMin, outMax);
}
template<typename> template<typename>
struct array_size; struct array_size;

File diff suppressed because one or more lines are too long

View File

@@ -71,10 +71,16 @@ target_link_libraries(AdaptiveBrightness
Qt5::SerialPort Qt5::SerialPort
) )
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
target_link_libraries(AdaptiveBrightness
stdc++fs
)
endif()
if(MSVC) if(MSVC)
target_link_libraries(AdaptiveBrightness target_link_libraries(AdaptiveBrightness
Dxva2.lib Dxva2.lib
) )
endif() endif()
if(MSVC) if(MSVC)

14
firmware/.mxproject Normal file

File diff suppressed because one or more lines are too long

View File

@@ -6,19 +6,21 @@ GPIO.groupedBy=Group By Peripherals
KeepUserPlacement=false KeepUserPlacement=false
Mcu.Family=STM32F0 Mcu.Family=STM32F0
Mcu.IP0=ADC Mcu.IP0=ADC
Mcu.IP1=NVIC Mcu.IP1=IWDG
Mcu.IP2=RCC Mcu.IP2=NVIC
Mcu.IP3=SYS Mcu.IP3=RCC
Mcu.IP4=USB Mcu.IP4=SYS
Mcu.IP5=USB_DEVICE Mcu.IP5=USB
Mcu.IPNb=6 Mcu.IP6=USB_DEVICE
Mcu.IPNb=7
Mcu.Name=STM32F042K(4-6)Tx Mcu.Name=STM32F042K(4-6)Tx
Mcu.Package=LQFP32 Mcu.Package=LQFP32
Mcu.Pin0=PA0 Mcu.Pin0=PA0
Mcu.Pin1=PA1 Mcu.Pin1=PA1
Mcu.Pin10=PB8 Mcu.Pin10=PB8
Mcu.Pin11=VP_SYS_VS_Systick Mcu.Pin11=VP_IWDG_VS_IWDG
Mcu.Pin12=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS Mcu.Pin12=VP_SYS_VS_Systick
Mcu.Pin13=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
Mcu.Pin2=PA2 Mcu.Pin2=PA2
Mcu.Pin3=PA7 Mcu.Pin3=PA7
Mcu.Pin4=PB0 Mcu.Pin4=PB0
@@ -27,7 +29,7 @@ Mcu.Pin6=PA11
Mcu.Pin7=PA12 Mcu.Pin7=PA12
Mcu.Pin8=PA13 Mcu.Pin8=PA13
Mcu.Pin9=PA14 Mcu.Pin9=PA14
Mcu.PinsNb=13 Mcu.PinsNb=14
Mcu.ThirdPartyNb=0 Mcu.ThirdPartyNb=0
Mcu.UserConstants= Mcu.UserConstants=
Mcu.UserName=STM32F042K6Tx Mcu.UserName=STM32F042K6Tx
@@ -87,13 +89,13 @@ ProjectManager.ComputerToolchain=false
ProjectManager.CoupleFile=true ProjectManager.CoupleFile=true
ProjectManager.CustomerFirmwarePackage= ProjectManager.CustomerFirmwarePackage=
ProjectManager.DefaultFWLocation=true ProjectManager.DefaultFWLocation=true
ProjectManager.DeletePrevious=true ProjectManager.DeletePrevious=false
ProjectManager.DeviceId=STM32F042K6Tx ProjectManager.DeviceId=STM32F042K6Tx
ProjectManager.FirmwarePackage=STM32Cube FW_F0 V1.11.0 ProjectManager.FirmwarePackage=STM32Cube FW_F0 V1.11.0
ProjectManager.FreePins=false ProjectManager.FreePins=false
ProjectManager.HalAssertFull=false ProjectManager.HalAssertFull=false
ProjectManager.HeapSize=0x000 ProjectManager.HeapSize=0x000
ProjectManager.KeepUserCode=false ProjectManager.KeepUserCode=true
ProjectManager.LastFirmware=true ProjectManager.LastFirmware=true
ProjectManager.LibraryCopy=1 ProjectManager.LibraryCopy=1
ProjectManager.MainLocation=Src ProjectManager.MainLocation=Src
@@ -106,7 +108,7 @@ ProjectManager.StackSize=0x700
ProjectManager.TargetToolchain=Makefile ProjectManager.TargetToolchain=Makefile
ProjectManager.ToolChainLocation= ProjectManager.ToolChainLocation=
ProjectManager.UnderRoot=false ProjectManager.UnderRoot=false
ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_ADC_Init-ADC-false-HAL-true,4-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-false,3-MX_ADC_Init-ADC-false-HAL-true,4-MX_USB_DEVICE_Init-USB_DEVICE-false-HAL-false,5-MX_IWDG_Init-IWDG-false-HAL-true
RCC.AHBFreq_Value=48000000 RCC.AHBFreq_Value=48000000
RCC.APB1Freq_Value=48000000 RCC.APB1Freq_Value=48000000
RCC.APB1TimFreq_Value=48000000 RCC.APB1TimFreq_Value=48000000
@@ -132,6 +134,8 @@ USB_DEVICE.IPParameters=VirtualMode,VirtualModeFS,CLASS_NAME_FS,PRODUCT_STRING_C
USB_DEVICE.PRODUCT_STRING_CDC_FS=AdaptiveBrightness USB_DEVICE.PRODUCT_STRING_CDC_FS=AdaptiveBrightness
USB_DEVICE.VirtualMode=Cdc USB_DEVICE.VirtualMode=Cdc
USB_DEVICE.VirtualModeFS=Cdc_FS USB_DEVICE.VirtualModeFS=Cdc_FS
VP_IWDG_VS_IWDG.Mode=IWDG_Activate
VP_IWDG_VS_IWDG.Signal=IWDG_VS_IWDG
VP_SYS_VS_Systick.Mode=SysTick VP_SYS_VS_Systick.Mode=SysTick
VP_SYS_VS_Systick.Signal=SYS_VS_Systick VP_SYS_VS_Systick.Signal=SYS_VS_Systick
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS

View File

@@ -0,0 +1,242 @@
/**
******************************************************************************
* @file stm32f0xx_hal_iwdg.h
* @author MCD Application Team
* @brief Header file of IWDG HAL module.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef STM32F0xx_HAL_IWDG_H
#define STM32F0xx_HAL_IWDG_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal_def.h"
/** @addtogroup STM32F0xx_HAL_Driver
* @{
*/
/** @defgroup IWDG IWDG
* @{
*/
/* Exported types ------------------------------------------------------------*/
/** @defgroup IWDG_Exported_Types IWDG Exported Types
* @{
*/
/**
* @brief IWDG Init structure definition
*/
typedef struct
{
uint32_t Prescaler; /*!< Select the prescaler of the IWDG.
This parameter can be a value of @ref IWDG_Prescaler */
uint32_t Reload; /*!< Specifies the IWDG down-counter reload value.
This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */
uint32_t Window; /*!< Specifies the window value to be compared to the down-counter.
This parameter must be a number between Min_Data = 0 and Max_Data = 0x0FFF */
} IWDG_InitTypeDef;
/**
* @brief IWDG Handle Structure definition
*/
typedef struct
{
IWDG_TypeDef *Instance; /*!< Register base address */
IWDG_InitTypeDef Init; /*!< IWDG required parameters */
} IWDG_HandleTypeDef;
/**
* @}
*/
/* Exported constants --------------------------------------------------------*/
/** @defgroup IWDG_Exported_Constants IWDG Exported Constants
* @{
*/
/** @defgroup IWDG_Prescaler IWDG Prescaler
* @{
*/
#define IWDG_PRESCALER_4 0x00000000u /*!< IWDG prescaler set to 4 */
#define IWDG_PRESCALER_8 IWDG_PR_PR_0 /*!< IWDG prescaler set to 8 */
#define IWDG_PRESCALER_16 IWDG_PR_PR_1 /*!< IWDG prescaler set to 16 */
#define IWDG_PRESCALER_32 (IWDG_PR_PR_1 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 32 */
#define IWDG_PRESCALER_64 IWDG_PR_PR_2 /*!< IWDG prescaler set to 64 */
#define IWDG_PRESCALER_128 (IWDG_PR_PR_2 | IWDG_PR_PR_0) /*!< IWDG prescaler set to 128 */
#define IWDG_PRESCALER_256 (IWDG_PR_PR_2 | IWDG_PR_PR_1) /*!< IWDG prescaler set to 256 */
/**
* @}
*/
/** @defgroup IWDG_Window_option IWDG Window option
* @{
*/
#define IWDG_WINDOW_DISABLE IWDG_WINR_WIN
/**
* @}
*/
/**
* @}
*/
/* Exported macros -----------------------------------------------------------*/
/** @defgroup IWDG_Exported_Macros IWDG Exported Macros
* @{
*/
/**
* @brief Enable the IWDG peripheral.
* @param __HANDLE__ IWDG handle
* @retval None
*/
#define __HAL_IWDG_START(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_ENABLE)
/**
* @brief Reload IWDG counter with value defined in the reload register
* (write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers disabled).
* @param __HANDLE__ IWDG handle
* @retval None
*/
#define __HAL_IWDG_RELOAD_COUNTER(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_RELOAD)
/**
* @}
*/
/* Exported functions --------------------------------------------------------*/
/** @defgroup IWDG_Exported_Functions IWDG Exported Functions
* @{
*/
/** @defgroup IWDG_Exported_Functions_Group1 Initialization and Start functions
* @{
*/
/* Initialization/Start functions ********************************************/
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg);
/**
* @}
*/
/** @defgroup IWDG_Exported_Functions_Group2 IO operation functions
* @{
*/
/* I/O operation functions ****************************************************/
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg);
/**
* @}
*/
/**
* @}
*/
/* Private constants ---------------------------------------------------------*/
/** @defgroup IWDG_Private_Constants IWDG Private Constants
* @{
*/
/**
* @brief IWDG Key Register BitMask
*/
#define IWDG_KEY_RELOAD 0x0000AAAAu /*!< IWDG Reload Counter Enable */
#define IWDG_KEY_ENABLE 0x0000CCCCu /*!< IWDG Peripheral Enable */
#define IWDG_KEY_WRITE_ACCESS_ENABLE 0x00005555u /*!< IWDG KR Write Access Enable */
#define IWDG_KEY_WRITE_ACCESS_DISABLE 0x00000000u /*!< IWDG KR Write Access Disable */
/**
* @}
*/
/* Private macros ------------------------------------------------------------*/
/** @defgroup IWDG_Private_Macros IWDG Private Macros
* @{
*/
/**
* @brief Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers.
* @param __HANDLE__ IWDG handle
* @retval None
*/
#define IWDG_ENABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_ENABLE)
/**
* @brief Disable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers.
* @param __HANDLE__ IWDG handle
* @retval None
*/
#define IWDG_DISABLE_WRITE_ACCESS(__HANDLE__) WRITE_REG((__HANDLE__)->Instance->KR, IWDG_KEY_WRITE_ACCESS_DISABLE)
/**
* @brief Check IWDG prescaler value.
* @param __PRESCALER__ IWDG prescaler value
* @retval None
*/
#define IS_IWDG_PRESCALER(__PRESCALER__) (((__PRESCALER__) == IWDG_PRESCALER_4) || \
((__PRESCALER__) == IWDG_PRESCALER_8) || \
((__PRESCALER__) == IWDG_PRESCALER_16) || \
((__PRESCALER__) == IWDG_PRESCALER_32) || \
((__PRESCALER__) == IWDG_PRESCALER_64) || \
((__PRESCALER__) == IWDG_PRESCALER_128)|| \
((__PRESCALER__) == IWDG_PRESCALER_256))
/**
* @brief Check IWDG reload value.
* @param __RELOAD__ IWDG reload value
* @retval None
*/
#define IS_IWDG_RELOAD(__RELOAD__) ((__RELOAD__) <= IWDG_RLR_RL)
/**
* @brief Check IWDG window value.
* @param __WINDOW__ IWDG window value
* @retval None
*/
#define IS_IWDG_WINDOW(__WINDOW__) ((__WINDOW__) <= IWDG_WINR_WIN)
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* STM32F0xx_HAL_IWDG_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -0,0 +1,264 @@
/**
******************************************************************************
* @file stm32f0xx_hal_iwdg.c
* @author MCD Application Team
* @brief IWDG HAL module driver.
* This file provides firmware functions to manage the following
* functionalities of the Independent Watchdog (IWDG) peripheral:
* + Initialization and Start functions
* + IO operation functions
*
@verbatim
==============================================================================
##### IWDG Generic features #####
==============================================================================
[..]
(+) The IWDG can be started by either software or hardware (configurable
through option byte).
(+) The IWDG is clocked by Low-Speed clock (LSI) and thus stays active even
if the main clock fails.
(+) Once the IWDG is started, the LSI is forced ON and both can not be
disabled. The counter starts counting down from the reset value (0xFFF).
When it reaches the end of count value (0x000) a reset signal is
generated (IWDG reset).
(+) Whenever the key value 0x0000 AAAA is written in the IWDG_KR register,
the IWDG_RLR value is reloaded in the counter and the watchdog reset is
prevented.
(+) The IWDG is implemented in the VDD voltage domain that is still functional
in STOP and STANDBY mode (IWDG reset can wake-up from STANDBY).
IWDGRST flag in RCC_CSR register can be used to inform when an IWDG
reset occurs.
(+) Debug mode : When the microcontroller enters debug mode (core halted),
the IWDG counter either continues to work normally or stops, depending
on DBG_IWDG_STOP configuration bit in DBG module, accessible through
__HAL_DBGMCU_FREEZE_IWDG() and __HAL_DBGMCU_UNFREEZE_IWDG() macros.
[..] Min-max timeout value @32KHz (LSI): ~125us / ~32.7s
The IWDG timeout may vary due to LSI frequency dispersion. STM32F0xx
devices provide the capability to measure the LSI frequency (LSI clock
connected internally to TIM16 CH1 input capture). The measured value
can be used to have an IWDG timeout with an acceptable accuracy.
##### How to use this driver #####
==============================================================================
[..]
(#) Use IWDG using HAL_IWDG_Init() function to :
(++) Enable instance by writing Start keyword in IWDG_KEY register. LSI
clock is forced ON and IWDG counter starts counting down.
(++) Enable write access to configuration registers:
IWDG_PR, IWDG_RLR and IWDG_WINR.
(++) Configure the IWDG prescaler and counter reload value. This reload
value will be loaded in the IWDG counter each time the watchdog is
reloaded, then the IWDG will start counting down from this value.
(++) Wait for status flags to be reset.
(++) Depending on window parameter:
(+++) If Window Init parameter is same as Window register value,
nothing more is done but reload counter value in order to exit
function with exact time base.
(+++) Else modify Window register. This will automatically reload
watchdog counter.
(#) Then the application program must refresh the IWDG counter at regular
intervals during normal operation to prevent an MCU reset, using
HAL_IWDG_Refresh() function.
*** IWDG HAL driver macros list ***
====================================
[..]
Below the list of most used macros in IWDG HAL driver:
(+) __HAL_IWDG_START: Enable the IWDG peripheral
(+) __HAL_IWDG_RELOAD_COUNTER: Reloads IWDG counter with value defined in
the reload register
@endverbatim
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2016 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm32f0xx_hal.h"
/** @addtogroup STM32F0xx_HAL_Driver
* @{
*/
#ifdef HAL_IWDG_MODULE_ENABLED
/** @addtogroup IWDG
* @brief IWDG HAL module driver.
* @{
*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/** @defgroup IWDG_Private_Defines IWDG Private Defines
* @{
*/
/* Status register need 5 RC LSI divided by prescaler clock to be updated. With
higher prescaler (256), and according to LSI variation, we need to wait at
least 6 cycles so 48 ms. */
#define HAL_IWDG_DEFAULT_TIMEOUT 48u
/**
* @}
*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Exported functions --------------------------------------------------------*/
/** @addtogroup IWDG_Exported_Functions
* @{
*/
/** @addtogroup IWDG_Exported_Functions_Group1
* @brief Initialization and Start functions.
*
@verbatim
===============================================================================
##### Initialization and Start functions #####
===============================================================================
[..] This section provides functions allowing to:
(+) Initialize the IWDG according to the specified parameters in the
IWDG_InitTypeDef of associated handle.
(+) Manage Window option.
(+) Once initialization is performed in HAL_IWDG_Init function, Watchdog
is reloaded in order to exit function with correct time base.
@endverbatim
* @{
*/
/**
* @brief Initialize the IWDG according to the specified parameters in the
* IWDG_InitTypeDef and start watchdog. Before exiting function,
* watchdog is refreshed in order to have correct time base.
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
* the configuration information for the specified IWDG module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_IWDG_Init(IWDG_HandleTypeDef *hiwdg)
{
uint32_t tickstart;
/* Check the IWDG handle allocation */
if (hiwdg == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_IWDG_ALL_INSTANCE(hiwdg->Instance));
assert_param(IS_IWDG_PRESCALER(hiwdg->Init.Prescaler));
assert_param(IS_IWDG_RELOAD(hiwdg->Init.Reload));
assert_param(IS_IWDG_WINDOW(hiwdg->Init.Window));
/* Enable IWDG. LSI is turned on automatically */
__HAL_IWDG_START(hiwdg);
/* Enable write access to IWDG_PR, IWDG_RLR and IWDG_WINR registers by writing
0x5555 in KR */
IWDG_ENABLE_WRITE_ACCESS(hiwdg);
/* Write to IWDG registers the Prescaler & Reload values to work with */
hiwdg->Instance->PR = hiwdg->Init.Prescaler;
hiwdg->Instance->RLR = hiwdg->Init.Reload;
/* Check pending flag, if previous update not done, return timeout */
tickstart = HAL_GetTick();
/* Wait for register to be updated */
while (hiwdg->Instance->SR != 0x00u)
{
if ((HAL_GetTick() - tickstart) > HAL_IWDG_DEFAULT_TIMEOUT)
{
return HAL_TIMEOUT;
}
}
/* If window parameter is different than current value, modify window
register */
if (hiwdg->Instance->WINR != hiwdg->Init.Window)
{
/* Write to IWDG WINR the IWDG_Window value to compare with. In any case,
even if window feature is disabled, Watchdog will be reloaded by writing
windows register */
hiwdg->Instance->WINR = hiwdg->Init.Window;
}
else
{
/* Reload IWDG counter with value defined in the reload register */
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
}
/* Return function status */
return HAL_OK;
}
/**
* @}
*/
/** @addtogroup IWDG_Exported_Functions_Group2
* @brief IO operation functions
*
@verbatim
===============================================================================
##### IO operation functions #####
===============================================================================
[..] This section provides functions allowing to:
(+) Refresh the IWDG.
@endverbatim
* @{
*/
/**
* @brief Refresh the IWDG.
* @param hiwdg pointer to a IWDG_HandleTypeDef structure that contains
* the configuration information for the specified IWDG module.
* @retval HAL status
*/
HAL_StatusTypeDef HAL_IWDG_Refresh(IWDG_HandleTypeDef *hiwdg)
{
/* Reload IWDG counter with value defined in the reload register */
__HAL_IWDG_RELOAD_COUNTER(hiwdg);
/* Return function status */
return HAL_OK;
}
/**
* @}
*/
/**
* @}
*/
#endif /* HAL_IWDG_MODULE_ENABLED */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

58
firmware/Inc/iwdg.h Normal file
View File

@@ -0,0 +1,58 @@
/**
******************************************************************************
* File Name : IWDG.h
* Description : This file provides code for the configuration
* of the IWDG instances.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under Ultimate Liberty license
* SLA0044, the "License"; You may not use this file except in compliance with
* the License. You may obtain a copy of the License at:
* www.st.com/SLA0044
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __iwdg_H
#define __iwdg_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "init.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern IWDG_HandleTypeDef hiwdg;
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
void MX_IWDG_Init(void);
/* USER CODE BEGIN Prototypes */
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ iwdg_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@@ -42,7 +42,7 @@
/*#define HAL_TSC_MODULE_ENABLED */ /*#define HAL_TSC_MODULE_ENABLED */
/*#define HAL_DAC_MODULE_ENABLED */ /*#define HAL_DAC_MODULE_ENABLED */
/*#define HAL_I2S_MODULE_ENABLED */ /*#define HAL_I2S_MODULE_ENABLED */
/*#define HAL_IWDG_MODULE_ENABLED */ #define HAL_IWDG_MODULE_ENABLED
/*#define HAL_LCD_MODULE_ENABLED */ /*#define HAL_LCD_MODULE_ENABLED */
/*#define HAL_LPTIM_MODULE_ENABLED */ /*#define HAL_LPTIM_MODULE_ENABLED */
/*#define HAL_RNG_MODULE_ENABLED */ /*#define HAL_RNG_MODULE_ENABLED */

View File

@@ -83,7 +83,7 @@ class VirtualComPort {
return hcdc->TxState != 0; return hcdc->TxState != 0;
}; };
#ifndef NDEBUG #ifdef INFO_LEDS
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
#endif #endif
@@ -98,7 +98,7 @@ class VirtualComPort {
USBD_CDC_SetTxBuffer(&hUsbDeviceFS, const_cast<uint8_t*>(m_usbAsyncTxBuffer.data), m_usbAsyncTxBuffer.size); USBD_CDC_SetTxBuffer(&hUsbDeviceFS, const_cast<uint8_t*>(m_usbAsyncTxBuffer.data), m_usbAsyncTxBuffer.size);
USBD_CDC_TransmitPacket(&hUsbDeviceFS); USBD_CDC_TransmitPacket(&hUsbDeviceFS);
#ifndef NDEBUG #ifdef INFO_LEDS
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
#endif #endif
} }
@@ -116,7 +116,7 @@ class VirtualComPort {
static int8_t CdcInit() static int8_t CdcInit()
{ {
#ifndef NDEBUG #ifdef INFO_LEDS
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
@@ -129,7 +129,7 @@ class VirtualComPort {
static int8_t CdcDeInit() static int8_t CdcDeInit()
{ {
#ifndef NDEBUG #ifdef INFO_LEDS
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_SET);
@@ -196,7 +196,7 @@ class VirtualComPort {
static int8_t CdcReceive([[maybe_unused]] uint8_t* buf, uint32_t* length) static int8_t CdcReceive([[maybe_unused]] uint8_t* buf, uint32_t* length)
{ {
#ifndef NDEBUG #ifdef INFO_LEDS
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_RESET);
#endif #endif
@@ -208,7 +208,7 @@ class VirtualComPort {
rxHandler(m_usbAsyncRxBuffer.data[i]); rxHandler(m_usbAsyncRxBuffer.data[i]);
} }
#ifndef NDEBUG #ifdef INFO_LEDS
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, GPIO_PIN_SET);
#endif #endif
return USBD_OK; return USBD_OK;

Some files were not shown because too many files have changed in this diff Show More