1use esp_hal::Async;
8use esp_hal::gpio::Level;
9use esp_hal::peripherals::GPIO21;
10use esp_hal::rmt::{Channel, ConfigError, Error, PulseCode, Tx, TxChannelConfig, TxChannelCreator};
11
12pub const RMT_MHZ: u32 = 80;
14
15const T0H: u16 = 32;
18const T0L: u16 = 68;
19const T1H: u16 = 64;
20const T1L: u16 = 36;
21
22pub struct RgbLed<'d> {
24 ch: Channel<'d, Async, Tx>,
25}
26
27impl<'d> RgbLed<'d> {
28 pub fn new(
31 channel: impl TxChannelCreator<'d, Async>,
32 pin: GPIO21<'d>,
33 ) -> Result<Self, ConfigError> {
34 let config = TxChannelConfig::default()
35 .with_clk_divider(1)
36 .with_idle_output(true)
37 .with_idle_output_level(Level::Low);
38 Ok(Self {
39 ch: channel.configure_tx(&config)?.with_pin(pin),
40 })
41 }
42
43 pub async fn set(&mut self, red: u8, green: u8, blue: u8) -> Result<(), Error> {
46 let mut codes = [PulseCode::end_marker(); 25];
47 let grb = u32::from_be_bytes([0, green, red, blue]);
49 for (i, code) in codes[..24].iter_mut().enumerate() {
50 *code = if grb >> (23 - i) & 1 == 1 {
51 PulseCode::new(Level::High, T1H, Level::Low, T1L)
52 } else {
53 PulseCode::new(Level::High, T0H, Level::Low, T0L)
54 };
55 }
56 self.ch.transmit(&codes).await
59 }
60
61 pub async fn off(&mut self) -> Result<(), Error> {
63 self.set(0, 0, 0).await
64 }
65}