crazyflie_lib/subsystems/memory/
led_driver.rs1use crate::{Error, Result, subsystems::memory::{MemoryBackend, memory_types}};
7use memory_types::{FromMemoryBackend, MemoryType};
8
9const NUM_LEDS: usize = 12;
10const LED_DATA_SIZE: usize = NUM_LEDS * 2; #[derive(Debug, Clone, Copy)]
14pub struct Led {
15 pub r: u8,
17 pub g: u8,
19 pub b: u8,
21 pub intensity: u8,
23}
24
25impl Default for Led {
26 fn default() -> Self {
27 Self {
28 r: 0,
29 g: 0,
30 b: 0,
31 intensity: 100,
32 }
33 }
34}
35
36impl Led {
37 pub fn set(&mut self, r: u8, g: u8, b: u8, intensity: Option<u8>) {
39 self.r = r;
40 self.g = g;
41 self.b = b;
42 if let Some(i) = intensity {
43 self.intensity = i;
44 }
45 }
46
47 fn to_rgb565(&self) -> u16 {
48 let intensity = self.intensity.min(100) as u32;
49 let r5 = ((((self.r as u32) * 249 + 1014) >> 11) & 0x1F) * intensity / 100;
50 let g6 = ((((self.g as u32) * 253 + 505) >> 10) & 0x3F) * intensity / 100;
51 let b5 = ((((self.b as u32) * 249 + 1014) >> 11) & 0x1F) * intensity / 100;
52 ((r5 << 11) | (g6 << 5) | b5) as u16
53 }
54}
55
56#[derive(Debug)]
62pub struct LedDriverMemory {
63 pub leds: [Led; NUM_LEDS],
65 memory: MemoryBackend,
66}
67
68impl LedDriverMemory {
69 fn from_backend(memory: MemoryBackend) -> Result<Self> {
70 if memory.memory_type == MemoryType::DriverLed {
71 Ok(Self {
72 leds: [Led::default(); NUM_LEDS],
73 memory,
74 })
75 } else {
76 Err(Error::MemoryError(format!(
77 "Expected DriverLed memory type, got {:?}",
78 memory.memory_type
79 )))
80 }
81 }
82
83 pub async fn write_leds(&self) -> Result<()> {
88 let mut data = Vec::with_capacity(LED_DATA_SIZE);
89 for led in &self.leds {
90 let rgb565 = led.to_rgb565();
91 data.push((rgb565 >> 8) as u8);
92 data.push((rgb565 & 0xFF) as u8);
93 }
94 self.memory.write::<fn(usize, usize)>(0x00, &data, None).await
95 }
96}
97
98impl FromMemoryBackend for LedDriverMemory {
99 async fn from_memory_backend(memory: MemoryBackend) -> Result<Self> {
100 Self::from_backend(memory)
101 }
102
103 async fn initialize_memory_backend(memory: MemoryBackend) -> Result<Self> {
104 Self::from_backend(memory)
105 }
106
107 fn close_memory(self) -> MemoryBackend {
108 self.memory
109 }
110}