#![no_std]
#![no_main]

use esp_backtrace as _;
use esp_hal::analog::adc::{Adc, AdcConfig, Attenuation};
use esp_hal::clock::CpuClock;
use esp_hal::delay::Delay;
use esp_hal::ledc::channel::config::PinConfig;
use esp_hal::ledc::channel::{self, ChannelIFace};
use esp_hal::ledc::timer::LSClockSource;
use esp_hal::ledc::{Ledc, LowSpeed, channel::config::Config as ChannelConfig};
use esp_hal::ledc::timer::{Number, TimerIFace, config::{Config as  TimerConfig, Duty}};
use esp_hal::main;
use esp_hal::time::RateExtU32;
use log::info;

#[main]
fn main() -> ! {
    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 delay = Delay::new();

    let led = peripherals.GPIO0;
    let potentiometer = peripherals.GPIO1;

    let mut adc_config = AdcConfig::new();
    let mut adc_potentiometer = adc_config.enable_pin(potentiometer, Attenuation::_11dB);
    let mut adc = Adc::new(peripherals.ADC1, adc_config);

    let ledc = Ledc::new(peripherals.LEDC);

    let mut timer = ledc.timer::<LowSpeed>(Number::Timer0);
    timer.configure(TimerConfig {
        duty: Duty::Duty14Bit,
        clock_source: LSClockSource::APBClk,
        frequency: 1u32.kHz()
    }).expect("error configuring ledc timer");

    let mut channel = ledc.channel(channel::Number::Channel0, led);
    channel.configure(ChannelConfig{
        timer: &timer,
        duty_pct: 0,
        pin_config: PinConfig::PushPull
    }).expect("error configuring ledc channel");

    let min_duty = 0_u8;

    loop {
        let sample = adc.read_oneshot(&mut adc_potentiometer).unwrap();
        let scaled_sample = ((sample as u32 * 100) / 4095 as u32) as u8;

        for duty in min_duty..scaled_sample {
            match channel.set_duty(duty) {
                Err(_err) => info!("error duty cycle"),
                _ => {}
            }
        }

    }
}