#![no_std]
#![no_main]
use embassy_executor::Spawner;
use embassy_time::{Duration, Timer};
use esp_backtrace as _;
use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay;
use esp_hal::{
rmt::{PulseCode, Rmt, TxChannelAsync, TxChannelConfig, TxChannelCreatorAsync},
time::RateExtU32,
timer::timg::TimerGroup,
};
use log::info;
const T0H_NS: u32 = 400;
const T0L_NS: u32 = 850;
const T1H_NS: u32 = 800;
const T1L_NS: u32 = 450;
// Calculate clock cycles for a given pulse duration
fn duration_to_clock_cycles(duration_ns: u32, clock_frequency_hz: u32) -> u16 {
let clock_period_ns = 1_000_000_000 / clock_frequency_hz; // Period in nanoseconds
((duration_ns + clock_period_ns - 1) / clock_period_ns) as u16 // Round up to the nearest cycle
}
// Toggle the RGB lights controlled via GPIO48
#[esp_hal_embassy::main]
async fn main(_spawner: Spawner) {
let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
let peripherals = esp_hal::init(config);
esp_println::logger::init_logger_from_env();
let timg0 = TimerGroup::new(peripherals.TIMG0);
esp_hal_embassy::init(timg0.timer0);
let delay = Delay::new();
let freq = 80.MHz();
let rmt = Rmt::new(peripherals.RMT, freq).unwrap().into_async();
let mut channel = rmt
.channel0
.configure(
peripherals.GPIO48,
TxChannelConfig {
clk_divider: 255,
..TxChannelConfig::default()
},
)
.unwrap();
// Desired pulse duration
let clock_frequency_hz = 80_000_000;
// Calculate clock cycles
let t1h_cycle = duration_to_clock_cycles(T1H_NS, clock_frequency_hz);
let t1l_cycle = duration_to_clock_cycles(T1L_NS, clock_frequency_hz);
let t0h_cycle = duration_to_clock_cycles(T0H_NS, clock_frequency_hz);
let t0l_cycle = duration_to_clock_cycles(T0L_NS, clock_frequency_hz);
// Send repeated patterns indicating color RED
// i.e. 0b000000001111111100000000
// Create the pulse
loop {
let mut data = [PulseCode::empty(); 24];
let pattern = 0b000000001111111100000000;
for i in 0..23 {
let bit = (pattern >> (23 - i)) & 1;
let pulse = if bit == 1 {
PulseCode::new(true, t1h_cycle, false, t1l_cycle)
} else {
PulseCode::new(true, t0h_cycle, false, t0l_cycle)
};
data[i] = pulse;
}
channel.transmit(&data).await.unwrap();
Timer::after(Duration::from_millis(10)).await;
}
}