Skip to content

Commit 0ee8484

Browse files
authored
Update GigaDisplayRGB.h: Prevent Digital Mode, Implemented PDM mode, to make the backlight dimming working
1 parent 66dd22c commit 0ee8484

File tree

1 file changed

+73
-26
lines changed

1 file changed

+73
-26
lines changed

src/GigaDisplayRGB.h

Lines changed: 73 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -17,37 +17,84 @@ class GigaDisplayRGB {
1717
using namespace std::chrono_literals;
1818
using namespace std::chrono;
1919

20+
2021
class GigaDisplayBacklight {
21-
public:
22-
GigaDisplayBacklight() {}
23-
void begin(int target_percent = 100) {
24-
pin = new mbed::DigitalOut(PB_12);
25-
ticker = new mbed::Ticker();
26-
ticker->attach(mbed::callback(this, &GigaDisplayBacklight::cb), 2ms);
27-
set(target_percent);
22+
private:
23+
mbed::Ticker* ticker = nullptr;
24+
mbed::DigitalOut* pin = nullptr;
25+
26+
// Exponential Lightness Model: This constants are determined
27+
// by Table II of the OSA report (exponent = 0.426, wikipedia: lightness)
28+
// and empirical measurement of Giga Display KD040WVFID026-01-C025A by Albertus Liberius
29+
static constexpr float min_pwm_percent = 3.36136f;
30+
static constexpr float max_pwm_percent = 100.f;
31+
static inline float pwm_percent_from_lightness_percent(float lightness_percent) {
32+
return min_pwm_percent * pow(max_pwm_percent / min_pwm_percent, lightness_percent / 100);
33+
}
34+
35+
// Specification by LED Driver chip LV52204MT
36+
inline static constexpr std::chrono::microseconds tick = 50us; // Ton(20us) < tick < Tw0(100us)
37+
// to prevent digital mode and goto pwm mode
38+
inline static constexpr uint16_t start_sequence_size = 50; // more than Tsel = 2.2ms
39+
// (mode selection determination time period)
40+
41+
// PDM counter
42+
uint16_t intensity = 0xFFFF; //maxIntensity
43+
uint16_t counter = 0;
44+
uint16_t start_seq_cnt = 0;
45+
46+
void callback() {
47+
if (start_sequence_size > start_seq_cnt) {
48+
*pin = start_seq_cnt++ & 1;
49+
} else {
50+
// PDM
51+
static uint16_t newcounter = 0;
52+
newcounter = (counter + intensity) & 0xFFFF;
53+
*pin = (counter > newcounter) ? 1 : 0;
54+
counter = newcounter;
2855
}
29-
void cb() {
30-
static int counter = 0;
31-
if (counter >= intensity) {
32-
*pin = 0;
33-
} else {
34-
*pin = 1;
35-
}
36-
counter += 10;
37-
if (counter == 100) {
38-
counter = 0;
39-
}
56+
}
57+
public:
58+
GigaDisplayBacklight() {}
59+
60+
void begin(float target_percent=100.f) {
61+
if (pin) delete pin;
62+
if (ticker) {
63+
ticker->detach();
64+
delete ticker;
4065
}
41-
void set(int target_percent) {
42-
intensity = target_percent;
66+
pin = new mbed::DigitalOut(PB_12);
67+
ticker = new mbed::Ticker();
68+
ticker->attach(mbed::callback(this, &GigaDisplayBacklight::callback), tick);
69+
set(target_percent);
70+
}
71+
72+
void set(float target_percent) {
73+
if (0 == intensity) start_seq_cnt = 0; // restart initialization sequence
74+
intensity = static_cast<uint16_t>(
75+
constrain(
76+
pwm_percent_from_lightness_percent(target_percent),
77+
min_pwm_percent,
78+
max_pwm_percent
79+
) / 100.f * 65535.f
80+
);
81+
}
82+
83+
void off() {
84+
intensity = 0; // if it is longer than 8.9ms, it is shutdown mode.
85+
}
86+
87+
inline virtual ~GigaDisplayBacklight() {
88+
if (ticker) {
89+
ticker->detach();
90+
delete ticker;
4391
}
44-
void off() {
45-
set(0);
92+
if (pin) {
93+
delete pin;
4694
}
47-
private:
48-
mbed::Ticker* ticker;
49-
mbed::DigitalOut* pin;
50-
int intensity;
95+
}
96+
5197
};
5298

99+
53100
#endif

0 commit comments

Comments
 (0)