use esp_hal::Async;
use esp_hal::gpio::Level;
use esp_hal::peripherals::GPIO21;
use esp_hal::rmt::{Channel, ConfigError, Error, PulseCode, Tx, TxChannelConfig, TxChannelCreator};
pub const RMT_MHZ: u32 = 80;
const T0H: u16 = 32;
const T0L: u16 = 68;
const T1H: u16 = 64;
const T1L: u16 = 36;
pub struct RgbLed<'d> {
ch: Channel<'d, Async, Tx>,
}
impl<'d> RgbLed<'d> {
pub fn new(
channel: impl TxChannelCreator<'d, Async>,
pin: GPIO21<'d>,
) -> Result<Self, ConfigError> {
let config = TxChannelConfig::default()
.with_clk_divider(1)
.with_idle_output(true)
.with_idle_output_level(Level::Low);
Ok(Self {
ch: channel.configure_tx(&config)?.with_pin(pin),
})
}
pub async fn set(&mut self, red: u8, green: u8, blue: u8) -> Result<(), Error> {
let mut codes = [PulseCode::end_marker(); 25];
let grb = u32::from_be_bytes([0, green, red, blue]);
for (i, code) in codes[..24].iter_mut().enumerate() {
*code = if grb >> (23 - i) & 1 == 1 {
PulseCode::new(Level::High, T1H, Level::Low, T1L)
} else {
PulseCode::new(Level::High, T0H, Level::Low, T0L)
};
}
self.ch.transmit(&codes).await
}
pub async fn off(&mut self) -> Result<(), Error> {
self.set(0, 0, 0).await
}
}