#![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;

    }
}