use crate::{Error, Result, subsystems::memory::{MemoryBackend, memory_types}};
use memory_types::{FromMemoryBackend, MemoryType};
const NUM_LEDS: usize = 12;
const LED_DATA_SIZE: usize = NUM_LEDS * 2;
#[derive(Debug, Clone, Copy)]
pub struct Led {
pub r: u8,
pub g: u8,
pub b: u8,
pub intensity: u8,
}
impl Default for Led {
fn default() -> Self {
Self {
r: 0,
g: 0,
b: 0,
intensity: 100,
}
}
}
impl Led {
pub fn set(&mut self, r: u8, g: u8, b: u8, intensity: Option<u8>) {
self.r = r;
self.g = g;
self.b = b;
if let Some(i) = intensity {
self.intensity = i;
}
}
fn to_rgb565(&self) -> u16 {
let intensity = self.intensity.min(100) as u32;
let r5 = ((((self.r as u32) * 249 + 1014) >> 11) & 0x1F) * intensity / 100;
let g6 = ((((self.g as u32) * 253 + 505) >> 10) & 0x3F) * intensity / 100;
let b5 = ((((self.b as u32) * 249 + 1014) >> 11) & 0x1F) * intensity / 100;
((r5 << 11) | (g6 << 5) | b5) as u16
}
}
#[derive(Debug)]
pub struct LedDriverMemory {
pub leds: [Led; NUM_LEDS],
memory: MemoryBackend,
}
impl LedDriverMemory {
fn from_backend(memory: MemoryBackend) -> Result<Self> {
if memory.memory_type == MemoryType::DriverLed {
Ok(Self {
leds: [Led::default(); NUM_LEDS],
memory,
})
} else {
Err(Error::MemoryError(format!(
"Expected DriverLed memory type, got {:?}",
memory.memory_type
)))
}
}
pub async fn write_leds(&self) -> Result<()> {
let mut data = Vec::with_capacity(LED_DATA_SIZE);
for led in &self.leds {
let rgb565 = led.to_rgb565();
data.push((rgb565 >> 8) as u8);
data.push((rgb565 & 0xFF) as u8);
}
self.memory.write::<fn(usize, usize)>(0x00, &data, None).await
}
}
impl FromMemoryBackend for LedDriverMemory {
async fn from_memory_backend(memory: MemoryBackend) -> Result<Self> {
Self::from_backend(memory)
}
async fn initialize_memory_backend(memory: MemoryBackend) -> Result<Self> {
Self::from_backend(memory)
}
fn close_memory(self) -> MemoryBackend {
self.memory
}
}