From f951518b57c4f5faa4035a4e95ce22ae0ca513b2 Mon Sep 17 00:00:00 2001
From: Savanni D'Gerinel <savanni@luminescent-dreams.com>
Date: Sun, 9 Mar 2025 00:08:39 -0500
Subject: [PATCH] Write a control that scans the light sensor

---
 pico-st7789/src/canvas.rs       |   4 +-
 pico-st7789/src/light_sensor.rs |  42 +++++++++
 pico-st7789/src/main.rs         | 158 +++++++++++++++++++++++++++-----
 3 files changed, 180 insertions(+), 24 deletions(-)
 create mode 100644 pico-st7789/src/light_sensor.rs

diff --git a/pico-st7789/src/canvas.rs b/pico-st7789/src/canvas.rs
index 7a16821..cb29b6b 100644
--- a/pico-st7789/src/canvas.rs
+++ b/pico-st7789/src/canvas.rs
@@ -20,8 +20,8 @@ pub trait Canvas {
     fn set_pixel(&mut self, x: usize, y: usize, color: &RGB);
 
     fn fill(&mut self, x1: usize, y1: usize, x2: usize, y2: usize, color: &RGB) {
-        for x in x1..x2 + 1 {
-            for y in y1..y2 + 1 {
+        for x in x1..x2 {
+            for y in y1..y2 {
                 self.set_pixel(x, y, color);
             }
         }
diff --git a/pico-st7789/src/light_sensor.rs b/pico-st7789/src/light_sensor.rs
new file mode 100644
index 0000000..9250f11
--- /dev/null
+++ b/pico-st7789/src/light_sensor.rs
@@ -0,0 +1,42 @@
+use embedded_hal::i2c::{I2c, Error};
+
+const ADDR: u8 = 0x39;
+
+pub struct LightSensor<I2C> {
+    i2c: I2C
+}
+
+impl <I2C: I2c> LightSensor<I2C> {
+    pub fn new(i2c: I2C) -> Self {
+        Self { i2c }
+    }
+
+    pub fn control(&mut self) -> Result<u8, I2C::Error> {
+        let mut ctrl = [0];
+        self.i2c.write_read(ADDR, &[0x80], &mut ctrl)?;
+        Ok(ctrl[0])
+    }
+
+    pub fn power_up(&mut self) -> Result<(), I2C::Error> {
+        self.i2c.write(ADDR, &[0x80, 0x03])?;
+        Ok(())
+    }
+
+    pub fn read_full_spectrum(&mut self) -> Result<u16, I2C::Error> {
+        let mut light_parts = [0, 0];
+        self.i2c.write_read(ADDR, &[0xAC], &mut light_parts)?;
+        let ll: u16 = light_parts[0].into();
+        let lh: u16 = light_parts[1].into();
+        let light: u16 = 256 * lh + ll;
+        Ok(light)
+    }
+
+    pub fn read_ir(&mut self) -> Result<u16, I2C::Error> {
+        let mut light_parts = [0, 0];
+        self.i2c.write_read(ADDR, &[0xAE], &mut light_parts)?;
+        let ll: u16 = light_parts[0].into();
+        let lh: u16 = light_parts[1].into();
+        let light: u16 = 256 * lh + ll;
+        Ok(light)
+    }
+}
diff --git a/pico-st7789/src/main.rs b/pico-st7789/src/main.rs
index ad3a90f..a2b3993 100644
--- a/pico-st7789/src/main.rs
+++ b/pico-st7789/src/main.rs
@@ -7,19 +7,31 @@ use alloc::fmt::format;
 use embedded_alloc::LlffHeap as Heap;
 use embedded_hal::{delay::DelayNs, digital::OutputPin};
 use fugit::RateExtU32;
+use light_sensor::LightSensor;
 use panic_halt as _;
 use rp_pico::{
     entry,
-    hal::{clocks::init_clocks_and_plls, spi::Spi, Clock, Sio, Timer, Watchdog},
+    hal::{
+        clocks::init_clocks_and_plls,
+        gpio::{
+            bank0::{Gpio20, Gpio21},
+            FunctionI2C, Pin, PullUp,
+        },
+        i2c::I2C,
+        spi::Spi,
+        Clock, Sio, Timer, Watchdog,
+    },
     pac, Pins,
 };
 
 mod canvas;
-use canvas::{Canvas, RGB, print};
+use canvas::{print, Canvas, RGB};
 
 mod font;
 use font::{BitmapFont, Font, Glyph, SevenSegmentFont, SixteenSegmentFont};
 
+mod light_sensor;
+
 mod st7789;
 use st7789::{ST7789Display, SETUP_PROGRAM};
 
@@ -116,6 +128,9 @@ unsafe fn main() -> ! {
     let mut data_command = pins.gpio15.into_function();
     let mut reset = pins.gpio14.into_function();
 
+    let i2c_clk: Pin<Gpio21, FunctionI2C, PullUp> = pins.gpio21.reconfigure();
+    let i2c_sdo: Pin<Gpio20, FunctionI2C, PullUp> = pins.gpio20.reconfigure();
+
     let _ = reset.set_low();
     let _ = board_select.set_high();
     let _ = data_command.set_high();
@@ -132,6 +147,17 @@ unsafe fn main() -> ! {
         embedded_hal::spi::MODE_3,
     );
 
+    let i2c = I2C::i2c0(
+        peripherals.I2C0,
+        i2c_sdo,
+        i2c_clk,
+        400.kHz(),
+        &mut peripherals.RESETS,
+        125_000_000.Hz(),
+    );
+
+    let mut light_sensor = LightSensor::new(i2c);
+
     let mut display = ST7789Display::new(board_select, data_command, spi);
 
     let _ = reset.set_high();
@@ -148,20 +174,116 @@ unsafe fn main() -> ! {
     let mut canvas = Canvas::new(&mut framebuf, COLUMNS);
     */
     let mut canvas = FrameBuf::new();
-    let white = RGB { r: 63, g: 63, b: 63 };
+    let white = RGB {
+        r: 63,
+        g: 63,
+        b: 63,
+    };
     let mut count = 0;
 
-    loop {
-        canvas.fill(0, 10, 170, 20, &RGB{r: 0, g: 0, b: 0 });
-        print(&mut canvas, &font_bitmap, 1, 10, &format(format_args!("COUNT: {:03}", count)), &RGB{ r: 32, g: 32, b: 63 });
-        print(&mut canvas, &font_bitmap, 1, 200, " !\"#$%&'<>*+,-./", &RGB{ r: 63, g: 63, b: 63 });
-        print(&mut canvas, &font_bitmap, 1, 220, "0123456789|: = ?", &RGB{ r: 63, g: 63, b: 63 });
-        print(&mut canvas, &font_bitmap, 1, 240, "@ABCDEFGHIJKLMNO", &RGB{ r: 63, g: 63, b: 63 });
-        print(&mut canvas, &font_bitmap, 1, 260, "PQRSTUVWXYZ[\\]^_", &RGB{ r: 63, g: 63, b: 63 });
-        print(&mut canvas, &font_bitmap, 1, 280, "`abcdefghijklmno", &RGB{ r: 63, g: 63, b: 63 });
-        print(&mut canvas, &font_bitmap, 1, 300, "pqrstuvwxyz{|}", &RGB{ r: 63, g: 63, b: 63 });
+    light_sensor.power_up();
+    match light_sensor.control() {
+        Ok(v) if v == 0 => print(
+            &mut canvas,
+            &font_bitmap,
+            1,
+            1,
+            &format(format_args!("POWER_DOWN")),
+            &RGB {
+                r: 63,
+                g: 16,
+                b: 16,
+            },
+        ),
+        Ok(_) => {}
+        Err(err) => print(
+            &mut canvas,
+            &font_bitmap,
+            1,
+            1,
+            &format(format_args!("ERROR: {:?}", err)),
+            &RGB {
+                r: 63,
+                g: 16,
+                b: 16,
+            },
+        ),
+    }
 
-        // canvas.square(10, 70, 160, 310, &white);
+    loop {
+        canvas.fill(0, 0, 170, 320, &RGB{ r: 0, g: 0, b: 0 });
+        print(&mut canvas, &font_bitmap, 1, 1, "A", &RGB{ r: 63, g: 63, b: 63 });
+        {
+            let display = display.acquire();
+            let _ = led.set_high();
+            timer.delay_ms(100);
+            display.send_buf(canvas.buf);
+            let _ = led.set_low();
+        }
+
+        match light_sensor.read_full_spectrum() {
+            Ok(full) => print(
+                &mut canvas,
+                &font_bitmap,
+                1,
+                10,
+                &format(format_args!("FULL: {}", full)),
+                &RGB {
+                    r: 63,
+                    g: 63,
+                    b: 63,
+                },
+            ),
+            Err(err) => print(
+                &mut canvas,
+                &font_bitmap,
+                1,
+                10,
+                &format(format_args!("FULL: {:?}", err)),
+                &RGB {
+                    r: 63,
+                    g: 16,
+                    b: 16,
+                },
+            ),
+        }
+        print(&mut canvas, &font_bitmap, 10, 1, "B", &RGB{ r: 63, g: 63, b: 63 });
+        {
+            let display = display.acquire();
+            let _ = led.set_high();
+            timer.delay_ms(100);
+            display.send_buf(canvas.buf);
+            let _ = led.set_low();
+        }
+
+        match light_sensor.read_ir() {
+            Ok(ir) => print(
+                &mut canvas,
+                &font_bitmap,
+                1,
+                20,
+                &format(format_args!("IR:   {}", ir)),
+                &RGB {
+                    r: 63,
+                    g: 63,
+                    b: 63,
+                },
+            ),
+            Err(err) => print(
+                &mut canvas,
+                &font_bitmap,
+                1,
+                20,
+                &format(format_args!("IR:   {:?}", err)),
+                &RGB {
+                    r: 63,
+                    g: 16,
+                    b: 16,
+                },
+            ),
+        }
+
+        print(&mut canvas, &font_bitmap, 20, 1, "C", &RGB{ r: 63, g: 63, b: 63 });
 
         {
             let display = display.acquire();
@@ -170,15 +292,7 @@ unsafe fn main() -> ! {
             display.send_buf(canvas.buf);
             let _ = led.set_low();
         }
-        count = count + 1;
-        /*
-        for x in 80..90 {
-            for y in 155..165 {
-                draw_pixel(&mut frame, x, y, (0, 0, 63));
-            }
-        }
-        */
 
-        timer.delay_ms(1000);
+        timer.delay_ms(100);
     }
 }