Compare commits
43 Commits
d88dc95a44
...
v1.3
| Author | SHA1 | Date | |
|---|---|---|---|
| 77d9a22419 | |||
| 392a03a23d | |||
| e796ff3663 | |||
| de58e2d472 | |||
| 314b281c03 | |||
| 5253dc1df6 | |||
| 4bdedbc110 | |||
| 42043bcd55 | |||
| 45116d8857 | |||
| c930e316c4 | |||
| 1e3836cb9f | |||
| 7ea9638488 | |||
| ddec3d2431 | |||
| aeca6a5dc0 | |||
| 4956dde368 | |||
| 348631fedc | |||
| fc49f1d779 | |||
| 756bb9b6a7 | |||
| 5943b72fef | |||
| 8f4dec0bff | |||
| 78f3daf1ff | |||
| 17a4890fdc | |||
| e4f18911f9 | |||
| 17a1eab03d | |||
| 69b14243bc | |||
| 65b4fbc484 | |||
| 5b6dd9e62c | |||
| 994e08bebc | |||
| 86dbcfda4f | |||
| 5e4aba8140 | |||
| 7b791a071b | |||
| 69a68ce67c | |||
| afd6de62a0 | |||
| cb9a57a24a | |||
| 395e58f94d | |||
| 200ad19d95 | |||
| 88600b8915 | |||
| d5dad15d0a | |||
| 7331532dfa | |||
| 5169ddd4bd | |||
| 8e15ee72f3 | |||
| 7a087c918e | |||
| 962dc6ab95 |
@@ -1,13 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>AdaptiveBrightnessClass</class>
|
||||
<widget class="QMainWindow" name="AdaptiveBrightnessClass">
|
||||
<class>MainWindow</class>
|
||||
<widget class="QMainWindow" name="MainWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>406</width>
|
||||
<height>306</height>
|
||||
<width>450</width>
|
||||
<height>555</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -17,48 +17,541 @@
|
||||
<iconset resource="AdaptiveBrightness.qrc">
|
||||
<normaloff>:/AdaptiveBrightness/resources/system.ico</normaloff>:/AdaptiveBrightness/resources/system.ico</iconset>
|
||||
</property>
|
||||
<widget class="QWidget" name="centralWidget">
|
||||
<layout class="QFormLayout" name="formLayout_2">
|
||||
<widget class="QWidget" name="mainWidget">
|
||||
<layout class="QGridLayout" name="gridLayout_3">
|
||||
<item row="0" column="1">
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Manual brightness control</string>
|
||||
<widget class="QTabWidget" name="tabs">
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout">
|
||||
<item row="0" column="0">
|
||||
<widget class="QSlider" name="horizontalSlider">
|
||||
<property name="toolTip">
|
||||
<string>Brightness</string>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QWidget" name="monitorTab">
|
||||
<attribute name="title">
|
||||
<string>Monitors</string>
|
||||
</attribute>
|
||||
<layout class="QGridLayout" name="gridLayout_12">
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QGroupBox" name="monitorGroup">
|
||||
<property name="title">
|
||||
<string>Monitor</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_11">
|
||||
<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="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<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="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<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="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<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="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<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="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<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="value">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<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>
|
||||
</item>
|
||||
</layout>
|
||||
</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>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources>
|
||||
|
||||
@@ -1,14 +1,50 @@
|
||||
#pragma once
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QMessageLogger>
|
||||
#include <QString>
|
||||
#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)
|
||||
{
|
||||
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");
|
||||
QString formattedMsg = QString("[%1] ").arg(dateTime);
|
||||
@@ -48,9 +84,15 @@ void logToFile(QtMsgType msgType, [[maybe_unused]] const QMessageLogContext& msg
|
||||
|
||||
formattedMsg += QString("%1").arg(msg);
|
||||
|
||||
QFile logFile(LOG_FILE);
|
||||
QFile logFile(QString().fromStdString(logFileName.string()));
|
||||
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)
|
||||
constexpr auto qtEndl = Qt::endl;
|
||||
#else
|
||||
|
||||
@@ -5,8 +5,12 @@
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include <QAbstractButton>
|
||||
#include <QCloseEvent>
|
||||
#include <QGroupBox>
|
||||
#include <QSlider>
|
||||
#include <QTabWidget>
|
||||
#include <QWidget>
|
||||
#include <QtDebug>
|
||||
#include <QtGlobal>
|
||||
|
||||
@@ -15,69 +19,21 @@
|
||||
#include "sensor_driver.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent)
|
||||
MainWindow::MainWindow(QWidget* parent) : QMainWindow(parent), m_mtx(QMutex::RecursionMode::Recursive)
|
||||
{
|
||||
qDebug(ltr("Creating main window"));
|
||||
|
||||
m_ui.setupUi(this);
|
||||
m_manualBrightnessSlider = m_ui.centralWidget->findChild<QGroupBox*>("groupBox")->findChild<QSlider*>("horizontalSlider");
|
||||
|
||||
if(m_manualBrightnessSlider) {
|
||||
connect(m_manualBrightnessSlider, &QSlider::valueChanged, [this](int value) {
|
||||
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;
|
||||
});
|
||||
}
|
||||
enumSensors();
|
||||
enumMonitors();
|
||||
|
||||
loadIcons();
|
||||
setupMonitorsTab();
|
||||
setupSensorsTab();
|
||||
|
||||
if(!QSystemTrayIcon::isSystemTrayAvailable()) {
|
||||
qWarning(ltr("System tray is not available -> tray icon will be disabled"));
|
||||
}
|
||||
else {
|
||||
qDebug(ltr("System tray is available"));
|
||||
setupTrayIcon();
|
||||
|
||||
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"));
|
||||
}
|
||||
|
||||
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("Tray icon update timer started"));
|
||||
|
||||
m_sensors = enumerateSensors();
|
||||
m_monitors = enumerateMonitors();
|
||||
setupCallbackTimer();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@@ -96,6 +52,35 @@ void MainWindow::closeEvent(QCloseEvent* event)
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void MainWindow::enumSensors()
|
||||
{
|
||||
m_sensors.clear();
|
||||
|
||||
auto sensors = enumerateSensors();
|
||||
|
||||
for(auto& sensor: sensors) {
|
||||
m_sensors.push_back({std::move(sensor)});
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::enumMonitors()
|
||||
{
|
||||
m_mtx.lock();
|
||||
|
||||
m_ui.monitorDropdown->clear();
|
||||
m_monitors.clear();
|
||||
|
||||
auto monitors = enumerateMonitors();
|
||||
|
||||
for(auto& monitor: monitors) {
|
||||
const auto currentBrightness = monitor.getBrightness();
|
||||
m_monitors.push_back({std::move(monitor), 0.f, 1.f, currentBrightness, false});
|
||||
m_ui.monitorDropdown->addItem(m_monitors.back().driver.getName());
|
||||
}
|
||||
|
||||
m_mtx.unlock();
|
||||
}
|
||||
|
||||
void MainWindow::loadIcons()
|
||||
{
|
||||
qDebug(ltr("Loading icons"));
|
||||
@@ -131,13 +116,194 @@ void MainWindow::loadIcons()
|
||||
qDebug(ltr("Icons loaded"));
|
||||
}
|
||||
|
||||
void MainWindow::setupMonitorsTab()
|
||||
{
|
||||
connect(m_ui.monitorDropdown, QOverload<int>::of(&QComboBox::currentIndexChanged), this, &MainWindow::updateCurrentMonitorGUI);
|
||||
connect(m_ui.monitorEnumerateButton, &QAbstractButton::clicked, [this](bool) { enumMonitors(); });
|
||||
connect(m_ui.monitorResetButton, &QAbstractButton::clicked, [this](bool) { resetAllMonitorSettings(); });
|
||||
|
||||
setupLimitsSlider();
|
||||
setupOverallLimitsSlider();
|
||||
|
||||
setupBrightness();
|
||||
setupOverallBrightness();
|
||||
|
||||
resetAllMonitorSettings();
|
||||
}
|
||||
|
||||
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) {
|
||||
if(monitor.manualOverride) {
|
||||
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::setupSensorsTab()
|
||||
{
|
||||
m_ui.tabs->removeTab(1);
|
||||
}
|
||||
|
||||
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::resetAllMonitorSettings()
|
||||
{
|
||||
m_ui.monitorOverallMinBrightnessSlider->setValue(0);
|
||||
m_ui.monitorOverallMaxBrightnessSlider->setValue(100);
|
||||
m_ui.monitorOverallOverrideCheck->setCheckState(Qt::CheckState::Unchecked);
|
||||
}
|
||||
|
||||
void MainWindow::updateCurrentMonitorGUI(int index)
|
||||
{
|
||||
if(index == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
m_mtx.lock();
|
||||
|
||||
qDebug(ltr("Updating state"));
|
||||
|
||||
bool sensorError = false;
|
||||
bool monitorError = false;
|
||||
size_t iconBrightness = 0;
|
||||
|
||||
const auto getAverageSensorValue = [this](float& brightness) {
|
||||
if(m_sensors.empty()) {
|
||||
@@ -147,8 +313,8 @@ void MainWindow::updateState()
|
||||
std::vector<float> values;
|
||||
|
||||
for(auto& sensor: m_sensors) {
|
||||
const auto sensorValues = sensor.readValues();
|
||||
if(!sensor) {
|
||||
const auto sensorValues = sensor.driver.readValues();
|
||||
if(!sensor.driver) {
|
||||
return false;
|
||||
}
|
||||
values.insert(values.end(), sensorValues.begin(), sensorValues.end());
|
||||
@@ -158,35 +324,22 @@ void MainWindow::updateState()
|
||||
return true;
|
||||
};
|
||||
|
||||
const auto setAllMonitorsBrightness = [this](float& brightness) {
|
||||
if(m_monitors.empty()) {
|
||||
return false;
|
||||
}
|
||||
auto brightness = NAN;
|
||||
|
||||
bool errorOccurred = false;
|
||||
for(auto& monitor: m_monitors) {
|
||||
if(!monitor.setBrightness(brightness)) {
|
||||
errorOccurred = true;
|
||||
}
|
||||
}
|
||||
return !errorOccurred;
|
||||
};
|
||||
|
||||
if(!getAverageSensorValue(m_brightness)) {
|
||||
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()));
|
||||
sensorError = true;
|
||||
}
|
||||
|
||||
const auto roundedBrightness = std::round(utils::map(m_brightness, 0.f, 1.f, 0, 8));
|
||||
iconBrightness = std::clamp<size_t>(roundedBrightness, 0, 8);
|
||||
|
||||
if(!setAllMonitorsBrightness(m_brightness)) {
|
||||
m_monitors = enumerateMonitors();
|
||||
if(!setMonitorBrightness(brightness)) {
|
||||
enumMonitors();
|
||||
qInfo(ltr("At least one monitor became invalid, re-enumerating monitors found %1 valid monitor(s)").arg(m_monitors.size()));
|
||||
monitorError = true;
|
||||
}
|
||||
|
||||
const auto iconBrightness = utils::map(brightness, 0.f, 1.f, size_t{0}, size_t{8});
|
||||
|
||||
if(!sensorError && !monitorError && m_trayIcon) {
|
||||
m_trayIcon->setIcon(*m_sensorStateIcons[iconBrightness]);
|
||||
}
|
||||
@@ -198,12 +351,52 @@ void MainWindow::updateState()
|
||||
}
|
||||
|
||||
if(m_trayIcon) {
|
||||
m_trayIcon->setToolTip(tr("AdaptiveBrightness - %1%").arg(m_brightness * 100, 0, 'f', 0));
|
||||
m_trayIcon->setToolTip(tr("AdaptiveBrightness - %1%").arg(brightness * 100, 0, 'f', 0));
|
||||
}
|
||||
|
||||
if(m_manualBrightnessSlider) {
|
||||
m_manualBrightnessSlider->setValue(utils::map(m_brightness, 0.f, 1.f, 0, 100));
|
||||
m_mtx.unlock();
|
||||
}
|
||||
|
||||
bool MainWindow::setMonitorBrightness(float& brightness)
|
||||
{
|
||||
if(m_monitors.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool errorOccurred = false;
|
||||
bool allMonitorsSameBrightness = true;
|
||||
|
||||
for(size_t i = 0; i < m_monitors.size(); ++i) {
|
||||
if(!std::isnan(brightness) && !m_monitors[i].manualOverride) {
|
||||
m_monitors[i].brightness = brightness;
|
||||
}
|
||||
|
||||
m_monitors[i].brightness = std::clamp(m_monitors[i].brightness, m_monitors[i].minBrightness, m_monitors[i].maxBrightness);
|
||||
|
||||
if(i > 0 && m_monitors[i - 1].brightness != m_monitors[i].brightness) {
|
||||
allMonitorsSameBrightness = false;
|
||||
}
|
||||
|
||||
if(!m_monitors[i].driver.setBrightness(m_monitors[i].brightness)) {
|
||||
errorOccurred = true;
|
||||
}
|
||||
else if(m_ui.monitorDropdown->currentIndex() == static_cast<int>(i)) {
|
||||
updateCurrentMonitorGUI(static_cast<int>(i));
|
||||
}
|
||||
}
|
||||
|
||||
if(!errorOccurred) {
|
||||
auto avgBrightness = 0.f;
|
||||
std::for_each(m_monitors.begin(), m_monitors.end(), [&avgBrightness](const auto& mon) { avgBrightness += mon.brightness; });
|
||||
avgBrightness /= m_monitors.size();
|
||||
brightness = avgBrightness;
|
||||
}
|
||||
|
||||
if(allMonitorsSameBrightness) {
|
||||
m_ui.monitorOverallBrightnessSlider->setValue(utils::map(brightness, 0.f, 1.f, 0, 100));
|
||||
}
|
||||
|
||||
return !errorOccurred;
|
||||
}
|
||||
|
||||
void MainWindow::trayIconClicked(QSystemTrayIcon::ActivationReason reason)
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <QIcon>
|
||||
#include <QMainWindow>
|
||||
#include <QMenu>
|
||||
#include <QMutex>
|
||||
#include <QSlider>
|
||||
#include <QSystemTrayIcon>
|
||||
#include <QThread>
|
||||
@@ -28,13 +29,33 @@ class MainWindow : public QMainWindow {
|
||||
private:
|
||||
void closeEvent(QCloseEvent* event) override;
|
||||
|
||||
void enumSensors();
|
||||
void enumMonitors();
|
||||
|
||||
void loadIcons();
|
||||
|
||||
void setupMonitorsTab();
|
||||
void setupLimitsSlider();
|
||||
void setupOverallLimitsSlider();
|
||||
void setupBrightness();
|
||||
void setupOverallBrightness();
|
||||
|
||||
void setupSensorsTab();
|
||||
|
||||
void setupTrayIcon();
|
||||
void setupCallbackTimer();
|
||||
|
||||
void resetAllMonitorSettings();
|
||||
|
||||
void updateCurrentMonitorGUI(int index);
|
||||
|
||||
void updateState();
|
||||
|
||||
bool setMonitorBrightness(float& brightness);
|
||||
|
||||
void trayIconClicked(QSystemTrayIcon::ActivationReason reason);
|
||||
|
||||
Ui::AdaptiveBrightnessClass m_ui;
|
||||
Ui::MainWindow m_ui;
|
||||
|
||||
std::array<std::unique_ptr<QIcon>, 9> m_noSensorStateIcons;
|
||||
std::array<std::unique_ptr<QIcon>, 9> m_sensorStateIcons;
|
||||
@@ -47,11 +68,20 @@ class MainWindow : public QMainWindow {
|
||||
|
||||
QThread* m_timerThread = nullptr;
|
||||
QTimer* m_timer = nullptr;
|
||||
QMutex m_mtx;
|
||||
|
||||
QSlider* m_manualBrightnessSlider = nullptr;
|
||||
struct SensorData {
|
||||
Sensor driver;
|
||||
};
|
||||
|
||||
float m_brightness = 0.5f;
|
||||
struct MonitorData {
|
||||
Monitor driver;
|
||||
float minBrightness;
|
||||
float maxBrightness;
|
||||
float brightness;
|
||||
bool manualOverride;
|
||||
};
|
||||
|
||||
std::vector<Sensor> m_sensors;
|
||||
std::vector<Monitor> m_monitors;
|
||||
std::vector<SensorData> m_sensors;
|
||||
std::vector<MonitorData> m_monitors;
|
||||
};
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <physicalmonitorenumerationapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace detail {
|
||||
|
||||
extern BOOL enumMonitorsCallback(HMONITOR, HDC, LPRECT, LPARAM);
|
||||
@@ -26,6 +28,8 @@ class Monitor {
|
||||
bool setBrightness(float percentage);
|
||||
float getBrightness();
|
||||
|
||||
QString getName() const;
|
||||
|
||||
operator bool() const;
|
||||
|
||||
private:
|
||||
@@ -53,6 +57,8 @@ class Monitor {
|
||||
|
||||
#if defined(__clang__) || defined(__GNUC__)
|
||||
|
||||
#include <QString>
|
||||
|
||||
class Monitor {
|
||||
public:
|
||||
Monitor();
|
||||
@@ -60,6 +66,8 @@ class Monitor {
|
||||
bool setBrightness(float);
|
||||
float getBrightness();
|
||||
|
||||
QString getName() const;
|
||||
|
||||
operator bool() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -26,6 +26,12 @@ float Monitor::getBrightness()
|
||||
return NAN;
|
||||
}
|
||||
|
||||
QString Monitor::getName() const
|
||||
{
|
||||
qWarning(ltr("Getting monitor name not implemented"));
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
Monitor::operator bool() const
|
||||
{
|
||||
qWarning(ltr("Checking monitor validity not implemented"));
|
||||
|
||||
@@ -24,6 +24,8 @@ Monitor::Monitor(Monitor&& other) noexcept
|
||||
other.m_hMonitor = 0;
|
||||
other.m_physicalMonitor.name.clear();
|
||||
other.m_physicalMonitor.handle = 0;
|
||||
other.m_brightnessRange.reset();
|
||||
other.m_errorOccurred = false;
|
||||
}
|
||||
|
||||
Monitor::~Monitor()
|
||||
@@ -62,8 +64,7 @@ bool Monitor::setBrightness(float percentage)
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto mappedBrightness = 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);
|
||||
const auto newBrightness = utils::map(percentage, 0.f, 1.f, m_brightnessRange->first, m_brightnessRange->second);
|
||||
|
||||
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")
|
||||
@@ -108,7 +109,15 @@ float Monitor::getBrightness()
|
||||
m_brightnessRange = std::pair{minBrightness, maxBrightness};
|
||||
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
|
||||
|
||||
@@ -15,6 +15,13 @@ Sensor::~Sensor()
|
||||
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()
|
||||
{
|
||||
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;
|
||||
|
||||
for(const auto& value: values) {
|
||||
const auto mappedValue = utils::map(value, m_range->first, m_range->second, 0.f, 1.f);
|
||||
normalizedValues.push_back(std::clamp(mappedValue, 0.f, 1.f));
|
||||
normalizedValues.push_back(utils::map(value, m_range->first, m_range->second, 0.f, 1.f));
|
||||
}
|
||||
|
||||
return normalizedValues;
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
|
||||
class Sensor {
|
||||
public:
|
||||
Sensor(const Sensor&) = delete;
|
||||
Sensor(Sensor&& other) noexcept;
|
||||
~Sensor();
|
||||
|
||||
std::vector<float> readValues();
|
||||
@@ -26,7 +28,7 @@ class Sensor {
|
||||
|
||||
static constexpr auto SUPPORTED_FIRMWARE = std::string_view{"AdaptiveBrightness v1.2"};
|
||||
|
||||
const QString m_serialPortName;
|
||||
QString m_serialPortName;
|
||||
bool m_errorOccurred = false;
|
||||
|
||||
std::optional<std::pair<int, int>> m_range;
|
||||
|
||||
@@ -21,7 +21,7 @@ std::vector<Sensor> enumerateSensors()
|
||||
auto sensor = Sensor(portInfo.portName());
|
||||
if(sensor.isValidSensor()) {
|
||||
qInfo(ltr("Successfully enumerated sensor on port %1").arg(portInfo.portName()));
|
||||
sensors.push_back(sensor);
|
||||
sensors.push_back(std::move(sensor));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <type_traits>
|
||||
|
||||
#include <cmath>
|
||||
#include <cstddef>
|
||||
|
||||
namespace utils {
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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>
|
||||
struct array_size;
|
||||
|
||||
|
||||
@@ -71,10 +71,16 @@ target_link_libraries(AdaptiveBrightness
|
||||
Qt5::SerialPort
|
||||
)
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang|AppleClang")
|
||||
target_link_libraries(AdaptiveBrightness
|
||||
stdc++fs
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(AdaptiveBrightness
|
||||
Dxva2.lib
|
||||
)
|
||||
target_link_libraries(AdaptiveBrightness
|
||||
Dxva2.lib
|
||||
)
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -6,19 +6,21 @@ GPIO.groupedBy=Group By Peripherals
|
||||
KeepUserPlacement=false
|
||||
Mcu.Family=STM32F0
|
||||
Mcu.IP0=ADC
|
||||
Mcu.IP1=NVIC
|
||||
Mcu.IP2=RCC
|
||||
Mcu.IP3=SYS
|
||||
Mcu.IP4=USB
|
||||
Mcu.IP5=USB_DEVICE
|
||||
Mcu.IPNb=6
|
||||
Mcu.IP1=IWDG
|
||||
Mcu.IP2=NVIC
|
||||
Mcu.IP3=RCC
|
||||
Mcu.IP4=SYS
|
||||
Mcu.IP5=USB
|
||||
Mcu.IP6=USB_DEVICE
|
||||
Mcu.IPNb=7
|
||||
Mcu.Name=STM32F042K(4-6)Tx
|
||||
Mcu.Package=LQFP32
|
||||
Mcu.Pin0=PA0
|
||||
Mcu.Pin1=PA1
|
||||
Mcu.Pin10=PB8
|
||||
Mcu.Pin11=VP_SYS_VS_Systick
|
||||
Mcu.Pin12=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
Mcu.Pin11=VP_IWDG_VS_IWDG
|
||||
Mcu.Pin12=VP_SYS_VS_Systick
|
||||
Mcu.Pin13=VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS
|
||||
Mcu.Pin2=PA2
|
||||
Mcu.Pin3=PA7
|
||||
Mcu.Pin4=PB0
|
||||
@@ -27,7 +29,7 @@ Mcu.Pin6=PA11
|
||||
Mcu.Pin7=PA12
|
||||
Mcu.Pin8=PA13
|
||||
Mcu.Pin9=PA14
|
||||
Mcu.PinsNb=13
|
||||
Mcu.PinsNb=14
|
||||
Mcu.ThirdPartyNb=0
|
||||
Mcu.UserConstants=
|
||||
Mcu.UserName=STM32F042K6Tx
|
||||
@@ -87,13 +89,13 @@ ProjectManager.ComputerToolchain=false
|
||||
ProjectManager.CoupleFile=true
|
||||
ProjectManager.CustomerFirmwarePackage=
|
||||
ProjectManager.DefaultFWLocation=true
|
||||
ProjectManager.DeletePrevious=true
|
||||
ProjectManager.DeletePrevious=false
|
||||
ProjectManager.DeviceId=STM32F042K6Tx
|
||||
ProjectManager.FirmwarePackage=STM32Cube FW_F0 V1.11.0
|
||||
ProjectManager.FreePins=false
|
||||
ProjectManager.HalAssertFull=false
|
||||
ProjectManager.HeapSize=0x000
|
||||
ProjectManager.KeepUserCode=false
|
||||
ProjectManager.KeepUserCode=true
|
||||
ProjectManager.LastFirmware=true
|
||||
ProjectManager.LibraryCopy=1
|
||||
ProjectManager.MainLocation=Src
|
||||
@@ -106,7 +108,7 @@ ProjectManager.StackSize=0x700
|
||||
ProjectManager.TargetToolchain=Makefile
|
||||
ProjectManager.ToolChainLocation=
|
||||
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.APB1Freq_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.VirtualMode=Cdc
|
||||
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.Signal=SYS_VS_Systick
|
||||
VP_USB_DEVICE_VS_USB_DEVICE_CDC_FS.Mode=CDC_FS
|
||||
|
||||
242
firmware/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_iwdg.h
Normal file
242
firmware/Drivers/STM32F0xx_HAL_Driver/Inc/stm32f0xx_hal_iwdg.h
Normal file
@@ -0,0 +1,242 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* @file stm32f0xx_hal_iwdg.h
|
||||
* @author MCD Application Team
|
||||
* @brief Header file of IWDG HAL module.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© 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****/
|
||||
264
firmware/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_iwdg.c
Normal file
264
firmware/Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_iwdg.c
Normal 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>© 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
58
firmware/Inc/iwdg.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : IWDG.h
|
||||
* Description : This file provides code for the configuration
|
||||
* of the IWDG instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© 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****/
|
||||
@@ -42,7 +42,7 @@
|
||||
/*#define HAL_TSC_MODULE_ENABLED */
|
||||
/*#define HAL_DAC_MODULE_ENABLED */
|
||||
/*#define HAL_I2S_MODULE_ENABLED */
|
||||
/*#define HAL_IWDG_MODULE_ENABLED */
|
||||
#define HAL_IWDG_MODULE_ENABLED
|
||||
/*#define HAL_LCD_MODULE_ENABLED */
|
||||
/*#define HAL_LPTIM_MODULE_ENABLED */
|
||||
/*#define HAL_RNG_MODULE_ENABLED */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
##########################################################################################################################
|
||||
# File automatically-generated by tool: [projectgenerator] version: [3.7.1] date: [Sun Jun 28 13:32:11 CEST 2020]
|
||||
# File automatically-generated by tool: [projectgenerator] version: [3.7.1] date: [Thu Jul 09 19:18:35 CEST 2020]
|
||||
# and modified by hand
|
||||
##########################################################################################################################
|
||||
|
||||
@@ -38,6 +38,7 @@ BUILD_DIR = build
|
||||
# C sources
|
||||
C_SOURCES = \
|
||||
Src/init.c \
|
||||
Src/iwdg.c \
|
||||
Src/gpio.c \
|
||||
Src/adc.c \
|
||||
Src/usb_device.c \
|
||||
@@ -65,6 +66,7 @@ Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_adc.c \
|
||||
Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_adc_ex.c \
|
||||
Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim.c \
|
||||
Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_tim_ex.c \
|
||||
Drivers/STM32F0xx_HAL_Driver/Src/stm32f0xx_hal_iwdg.c \
|
||||
Src/system_stm32f0xx.c \
|
||||
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c \
|
||||
Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c \
|
||||
@@ -147,7 +149,6 @@ C_INCLUDES = \
|
||||
-IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc \
|
||||
-IMiddlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \
|
||||
-IDrivers/CMSIS/Device/ST/STM32F0xx/Include \
|
||||
-IDrivers/CMSIS/Include \
|
||||
-IDrivers/CMSIS/Include
|
||||
|
||||
# C++ includes
|
||||
@@ -158,7 +159,6 @@ CXX_INCLUDES = \
|
||||
-IMiddlewares/ST/STM32_USB_Device_Library/Core/Inc \
|
||||
-IMiddlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc \
|
||||
-IDrivers/CMSIS/Device/ST/STM32F0xx/Include \
|
||||
-IDrivers/CMSIS/Include \
|
||||
-IDrivers/CMSIS/Include
|
||||
|
||||
|
||||
|
||||
94
firmware/README.md
Normal file
94
firmware/README.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# Adaptive Brightness Firmware
|
||||
|
||||
## Building
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- [gcc-arm-none-eabi](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) with C++17 support
|
||||
- make
|
||||
|
||||
### Build instructions
|
||||
|
||||
The gcc-arn-none-eabi compiler needs to be in the path. For example by executing `export PATH="$(pwd):$PATH"` in the `bin` directory of the toolchain.
|
||||
|
||||
Navigate to the firmware directory and do:
|
||||
|
||||
```console
|
||||
$ make
|
||||
```
|
||||
|
||||
This will build the firmware in a directory called `build`. By default the firmware will be built in release mode. Change the `DEBUG` and `OPT` settings in the Makefile for a debug build like this:
|
||||
|
||||
```Makefile
|
||||
DEBUG = 1
|
||||
OPT = -Og
|
||||
```
|
||||
|
||||
## Flashing
|
||||
|
||||
The firmware can either be flashed using the built-in DFU bootloader or using the SWD (Serial Wire Debug) interface with, for example, an ST-Link v2 programmer/debugger.
|
||||
|
||||
### DFU
|
||||
|
||||
#### Prerequisites for DFU
|
||||
|
||||
- [dfu-util](https://sourceforge.net/projects/dfu-util/files/)
|
||||
- [Zadig](https://zadig.akeo.ie/) (Windows only)
|
||||
|
||||
#### Entering DFU bootloader
|
||||
|
||||
The board has a button labeled **BOOT**, hold this button down while plugging in the device and the DFU bootloader will be executed.
|
||||
|
||||
#### Installing correct driver (Windows only)
|
||||
|
||||
Use Zadig to install the `WinUSB` driver for the device while it is running the bootloader. Make sure to enable the _List All Devices_ option in order to be able to select the device.
|
||||
|
||||
This only needs to be done once. Windows will then always use the installed driver for this device.
|
||||
|
||||
#### Flashing with dfu-util
|
||||
|
||||
You can check if the device is recognized by executing:
|
||||
|
||||
```console
|
||||
$ dfu-util -l
|
||||
|
||||
Found DFU: [0483:df11] ver=2200, devnum=57, cfg=1, intf=0, path="2-13.2.2", alt=1, name="@Option Bytes /0x1FFFF800/01*016 e", serial="FFFFFFFEFFFF"
|
||||
Found DFU: [0483:df11] ver=2200, devnum=57, cfg=1, intf=0, path="2-13.2.2", alt=0, name="@Internal Flash /0x08000000/032*0001Kg", serial="FFFFFFFEFFFF"
|
||||
```
|
||||
|
||||
The firmware can then be flashed using:
|
||||
|
||||
```console
|
||||
$ dfu-util -a 0 -s 0x08000000 -D AdaptiveBrightnessFirmware.bin
|
||||
|
||||
Invalid DFU suffix signature
|
||||
A valid DFU suffix will be required in a future dfu-util release!!!
|
||||
Opening DFU capable USB device...
|
||||
ID 0483:df11
|
||||
Run-time device DFU version 011a
|
||||
Claiming USB DFU Interface...
|
||||
Setting Alternate Setting #0 ...
|
||||
Determining device status: state = dfuERROR, status = 10
|
||||
dfuERROR, clearing status
|
||||
Determining device status: state = dfuIDLE, status = 0
|
||||
dfuIDLE, continuing
|
||||
DFU mode device DFU version 011a
|
||||
Device returned transfer size 2048
|
||||
DfuSe interface name: "Internal Flash "
|
||||
Downloading to address = 0x08000000, size = 21256
|
||||
Download [=========================] 100% 21256 bytes
|
||||
Download done.
|
||||
File downloaded successfully
|
||||
```
|
||||
|
||||
You need to unplug and re-plug the device to exit the bootloader and start executing the firmware.
|
||||
|
||||
### SWD
|
||||
|
||||
Instructions vary depending on the SWD device and software used. As an example you could use `openocd` with an ST-Link v2 like this:
|
||||
|
||||
```console
|
||||
$ openocd -f interface/stlink.cfg -f target/stm32f0x.cfg -c "program build/AdaptiveBrightnessFirmware.elf verify reset exit"
|
||||
```
|
||||
|
||||
**Note:** The `STM32 ST-LINK Utility` from ST does not issue a reset signal over the SWD interface. This makes flashing using this tool extremely difficult, as the reset line has to be manually triggered for the utility to be able to connect to the chip. `openocd` does not have this problem.
|
||||
@@ -107,10 +107,12 @@ void SystemClock_Config(void)
|
||||
|
||||
/** Initializes the CPU, AHB and APB busses clocks
|
||||
*/
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI14|RCC_OSCILLATORTYPE_HSI48;
|
||||
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI14|RCC_OSCILLATORTYPE_HSI48
|
||||
|RCC_OSCILLATORTYPE_LSI;
|
||||
RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
|
||||
RCC_OscInitStruct.HSI14State = RCC_HSI14_ON;
|
||||
RCC_OscInitStruct.HSI14CalibrationValue = 16;
|
||||
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
|
||||
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
|
||||
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
|
||||
{
|
||||
|
||||
48
firmware/Src/iwdg.c
Normal file
48
firmware/Src/iwdg.c
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* File Name : IWDG.c
|
||||
* Description : This file provides code for the configuration
|
||||
* of the IWDG instances.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© 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
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
/* Includes ------------------------------------------------------------------*/
|
||||
#include "iwdg.h"
|
||||
|
||||
/* USER CODE BEGIN 0 */
|
||||
|
||||
/* USER CODE END 0 */
|
||||
|
||||
IWDG_HandleTypeDef hiwdg;
|
||||
|
||||
/* IWDG init function */
|
||||
void MX_IWDG_Init(void)
|
||||
{
|
||||
|
||||
hiwdg.Instance = IWDG;
|
||||
hiwdg.Init.Prescaler = IWDG_PRESCALER_16;
|
||||
hiwdg.Init.Window = 4095;
|
||||
hiwdg.Init.Reload = 4095;
|
||||
if (HAL_IWDG_Init(&hiwdg) != HAL_OK)
|
||||
{
|
||||
Error_Handler();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* USER CODE BEGIN 1 */
|
||||
|
||||
/* USER CODE END 1 */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "init.h"
|
||||
#include "iwdg.h"
|
||||
#include "terminal.hpp"
|
||||
#include "uart.hpp"
|
||||
|
||||
@@ -14,6 +15,8 @@ extern "C" void Error_Handler(void)
|
||||
|
||||
static inline void initializeHardware()
|
||||
{
|
||||
const auto resetByWatchdog = (__HAL_RCC_GET_FLAG(RCC_FLAG_IWDGRST)) ? true : false;
|
||||
|
||||
terminal_t terminal;
|
||||
|
||||
do {
|
||||
@@ -23,8 +26,13 @@ static inline void initializeHardware()
|
||||
HAL_GPIO_WritePin(RED_LED_GPIO_Port, RED_LED_Pin, g_error ? GPIO_PIN_RESET : GPIO_PIN_SET);
|
||||
} while(g_error);
|
||||
|
||||
if(resetByWatchdog) {
|
||||
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin, GPIO_PIN_SET);
|
||||
}
|
||||
else {
|
||||
HAL_GPIO_WritePin(GREEN_LED_GPIO_Port, GREEN_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_RESET);
|
||||
HAL_GPIO_WritePin(BLUE_LED_GPIO_Port, BLUE_LED_Pin, GPIO_PIN_RESET);
|
||||
|
||||
HAL_Delay(1000);
|
||||
@@ -37,11 +45,13 @@ static inline void initializeHardware()
|
||||
int main()
|
||||
{
|
||||
initializeHardware();
|
||||
MX_IWDG_Init();
|
||||
|
||||
terminal_t terminal;
|
||||
|
||||
while(true) {
|
||||
terminal.callback();
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
1267
hardware/AdaptiveBrightness_v2.brd
Normal file
1267
hardware/AdaptiveBrightness_v2.brd
Normal file
File diff suppressed because it is too large
Load Diff
192
hardware/AdaptiveBrightness_v2.cam
Normal file
192
hardware/AdaptiveBrightness_v2.cam
Normal file
@@ -0,0 +1,192 @@
|
||||
[CAM Processor Job]
|
||||
Description[en]="For 2 layer PCB designs using Eagle version 7.2 or higher."
|
||||
Section=Sec_0
|
||||
Section=Sec_1
|
||||
Section=Sec_2
|
||||
Section=Sec_3
|
||||
Section=Sec_4
|
||||
Section=Sec_5
|
||||
Section=Sec_6
|
||||
Section=Sec_7
|
||||
Section=Sec_8
|
||||
Section=Sec_9
|
||||
|
||||
[Sec_0]
|
||||
Name[en]="Top Solder Paste"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GTP"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 31"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_1]
|
||||
Name[en]="Bottom Solder Paste"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GBP"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 32"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_2]
|
||||
Name[en]="Top Copper Layer"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GTL"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 1 17 18"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_3]
|
||||
Name[en]="Bottom Copper Layer"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GBL"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 16 17 18"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_4]
|
||||
Name[en]="Top Silkscreen"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GTO"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 21 25"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_5]
|
||||
Name[en]="Bottom Silkscreen"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GBO"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 22 26"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_6]
|
||||
Name[en]="Top Solder Mask"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GTS"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 29"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_7]
|
||||
Name[en]="Bottom Solder Mask"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GBS"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 30"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_8]
|
||||
Name[en]="Mechanical"
|
||||
Prompt=""
|
||||
Device="GERBER_RS274X"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".GML"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 20 46"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
|
||||
[Sec_9]
|
||||
Name[en]="Drill Layer"
|
||||
Prompt=""
|
||||
Device="EXCELLON_24"
|
||||
Wheel=".whl"
|
||||
Rack=""
|
||||
Scale=1
|
||||
Output=".TXT"
|
||||
Flags="0 0 0 1 0 1 1"
|
||||
Emulate="0"
|
||||
Offset="0.0mil 0.0mil"
|
||||
Sheet=1
|
||||
Tolerance="0 0 0 0 0 0"
|
||||
Pen="0.0mil 0"
|
||||
Page="12000.0mil 8000.0mil"
|
||||
Layers=" 44 45 46"
|
||||
Colors=" 1 2 1 2 1 2 1 2 1 2 1 2 1 2 1 2 6 6 4 8 8 8 8 8 8 8 8 8 8 8 8 8 4 4 1 1 1 1 3 3 1 2 6 8 8 5 8 8 8 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 4 2 4 3 6 6 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0"
|
||||
1946
hardware/AdaptiveBrightness_v2.sch
Normal file
1946
hardware/AdaptiveBrightness_v2.sch
Normal file
File diff suppressed because it is too large
Load Diff
BIN
hardware/AdaptiveBrightness_v2_2020-07-12.zip
Normal file
BIN
hardware/AdaptiveBrightness_v2_2020-07-12.zip
Normal file
Binary file not shown.
BIN
hardware/AdaptiveBrightness_v2_schematic.pdf
Normal file
BIN
hardware/AdaptiveBrightness_v2_schematic.pdf
Normal file
Binary file not shown.
Reference in New Issue
Block a user