@@ -17,37 +17,84 @@ class GigaDisplayRGB {
1717using namespace std ::chrono_literals;
1818using namespace std ::chrono;
1919
20+
2021class 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