1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) 2017-2022, Mudita Sp. z.o.o. All rights reserved.
// For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md
#include "ControlFunctions.hpp"
#include <cmath>
namespace screen_light_control::functions
{
namespace
{
struct FunctionSection
{
float xBound;
float a;
float b;
};
std::vector<FunctionSection> linearFunction;
float rampStep;
float hysteresis;
bsp::eink_frontlight::BrightnessPercentage rampTarget;
bsp::eink_frontlight::BrightnessPercentage rampState;
bool rampTargetReached = false;
} // namespace
void calculateBrightness(bsp::light_sensor::IlluminanceLux measurement)
{
for (const auto §ion : linearFunction) {
if (measurement < section.xBound) {
rampTarget = section.a * measurement + section.b;
return;
}
}
if (linearFunction.empty()) {
rampTarget = 0.0f;
return;
}
rampTarget = linearFunction.back().xBound * linearFunction.back().a + linearFunction.back().b;
}
bsp::eink_frontlight::BrightnessPercentage brightnessRampOut()
{
if (rampTargetReached && std::abs(rampTarget - rampState) > hysteresis) {
rampTargetReached = false;
}
if (!rampTargetReached) {
if (rampState < rampTarget) {
rampState += rampStep;
if (rampState >= rampTarget) {
rampState = rampTarget;
rampTargetReached = true;
}
}
else if (rampState > rampTarget) {
rampState -= rampStep;
if (rampState <= rampTarget) {
rampState = rampTarget;
rampTargetReached = true;
}
}
else {
rampTargetReached = true;
}
}
return rampState;
}
void setRampStep(float step)
{
rampStep = step;
}
void setHysteresis(float hyst)
{
hysteresis = hyst;
}
void setFunctionFromPoints(const BrightnessFunction &points)
{
if (!points.empty()) {
linearFunction.clear();
for (unsigned int i = 0; i < points.size(); ++i) {
FunctionSection section;
section.xBound = points[i].first;
if (i == 0) {
section.a = 0.0f;
section.b = points[i].second;
}
else {
section.a = (points[i - 1].second - points[i].second) / (points[i - 1].first - points[i].first);
section.b = points[i - 1].second - section.a * points[i - 1].first;
}
linearFunction.push_back(section);
}
}
}
void setRampState(float state)
{
rampState = state;
}
void setRampTarget(bsp::eink_frontlight::BrightnessPercentage value)
{
rampTarget = value;
}
void resetRampToTarget()
{
rampState = rampTarget;
}
bool isRampTargetReached()
{
return rampTargetReached;
}
bsp::eink_frontlight::BrightnessPercentage getRampState()
{
return rampState;
}
} // namespace screen_light_control::functions