From 852b419a34d79cc61cdce76a2134fd6116c89341 Mon Sep 17 00:00:00 2001
From: Stephen D <webmaster@scd31.com>
Date: Mon, 25 Mar 2024 22:59:47 -0300
Subject: [PATCH] improve keyboard backlight logic

---
 src/main.rs | 49 ++++++++++++++++++++++++-------------------------
 1 file changed, 24 insertions(+), 25 deletions(-)

diff --git a/src/main.rs b/src/main.rs
index cd12f29..4c13cdf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -29,7 +29,7 @@ mod app {
     use display_interface_spi::SPIInterface;
     use embedded_graphics::{pixelcolor::Rgb565, prelude::RgbColor};
     use embedded_hal::{digital::v2::OutputPin, PwmPin};
-    use fugit::RateExtU32;
+    use fugit::{Duration, RateExtU32};
     use hal::{
         gpio::{
             bank0::{
@@ -42,7 +42,7 @@ mod app {
         pac::{I2C1, SPI1},
         pwm::{self, Channel, FreeRunning, Pwm4, Pwm5, Slice},
         spi,
-        timer::{monotonic::Monotonic, Timer},
+        timer::{monotonic::Monotonic, Instant, Timer},
         Adc, Clock, I2C,
     };
     use mipidsi::{models::ST7789, Builder, Orientation};
@@ -52,6 +52,8 @@ mod app {
     const XTAL_FREQ_HZ: u32 = 12_000_000u32;
     const WIDTH: usize = 320;
     const HEIGHT: usize = 240;
+    const BACKLIGHT_DELAY_TIME_SECS: u64 = 5;
+    const BACKLIGHT_FADE_TIME_SECS: u64 = 2;
 
     type KeyboardBl = Channel<Slice<Pwm4, FreeRunning>, pwm::B>;
 
@@ -76,24 +78,6 @@ mod app {
         Pin<Gpio7, FunctionSio<SioOutput>, PullDown>,
     >;
 
-    type Lcd = mipidsi::Display<
-        SPIInterface<
-            spi::Spi<
-                spi::Enabled,
-                SPI1,
-                (
-                    Pin<Gpio15, FunctionSpi, PullDown>,
-                    Pin<Gpio12, FunctionSpi, PullDown>,
-                    Pin<Gpio14, FunctionSpi, PullDown>,
-                ),
-            >,
-            Pin<Gpio16, FunctionSio<SioOutput>, PullDown>,
-            Pin<Gpio13, FunctionSio<SioOutput>, PullDown>,
-        >,
-        ST7789,
-        Pin<Gpio4, FunctionSio<SioOutput>, PullDown>,
-    >;
-
     type MyBufferedDisplay = BufferedDisplay<
         { WIDTH * HEIGHT },
         SPIInterface<
@@ -130,6 +114,7 @@ mod app {
         keyboard_bl: KeyboardBl,
         display: MyBufferedDisplay,
         display_bl: DisplayBl,
+        last_key_press: Instant,
     }
 
     #[init]
@@ -278,7 +263,7 @@ mod app {
         display_update::spawn().unwrap();
         keyboard_update::spawn().unwrap();
 
-        let mono = Monotonic::new(timer, timer.alarm_0().unwrap());
+        let mut mono = Monotonic::new(timer, timer.alarm_0().unwrap());
 
         (
             Shared { gui },
@@ -288,12 +273,13 @@ mod app {
                 keyboard,
                 display,
                 display_bl,
+                last_key_press: mono.now(),
             },
             init::Monotonics(mono),
         )
     }
 
-    #[task(priority = 2, local = [display_bl, keyboard_bl, touchpad, keyboard], shared = [gui])]
+    #[task(priority = 2, local = [display_bl, keyboard_bl, touchpad, keyboard, last_key_press], shared = [gui])]
     fn keyboard_update(mut ctx: keyboard_update::Context) {
         //while usb_dev.poll(&mut [&mut serial]) {}
 
@@ -302,6 +288,7 @@ mod app {
             keyboard_bl,
             touchpad,
             keyboard,
+            last_key_press,
         } = ctx.local;
 
         let max_duty = keyboard_bl.get_max_duty();
@@ -309,13 +296,11 @@ mod app {
 
         let state = keyboard.read_state();
         if state > 0 {
-            keyboard_bl.set_duty(max_duty);
+            *last_key_press = monotonics::now();
 
             if let Some(k) = keyboard.pushed_key() {
                 ctx.shared.gui.lock(|g| g.key_push(k));
             }
-        } else {
-            keyboard_bl.set_duty(0);
         }
 
         let (x, y) = touchpad.get_delta_motion().unwrap();
@@ -332,6 +317,20 @@ mod app {
 
         display_bl.set_duty(cur_duty.min(display_bl.get_max_duty()));
 
+        // keyboard backlight logic
+        let delta = monotonics::now() - *last_key_press;
+        if let Some(fade_delta) = delta.checked_sub(BACKLIGHT_DELAY_TIME_SECS.secs::<1, 1>()) {
+            let fade_delta = fade_delta.to_millis();
+            let fade_time_ms = BACKLIGHT_FADE_TIME_SECS * 1000;
+            let frac = u64::from(keyboard_bl.get_max_duty())
+                * (fade_time_ms.saturating_sub(fade_delta))
+                / fade_time_ms;
+            keyboard_bl.set_duty(frac.try_into().unwrap());
+        } else {
+            keyboard_bl.set_duty(keyboard_bl.get_max_duty());
+        }
+
+        // re-enqueue ourselves
         keyboard_update::spawn_after(5.millis()).unwrap();
     }
 
-- 
GitLab