From 4200a09d094eb9a4fcfbab77af8d1ee799dec701 Mon Sep 17 00:00:00 2001 From: Lucas Schumacher Date: Tue, 26 Sep 2023 14:13:50 -0400 Subject: [PATCH] LedC works up to 2.5MHz --- src/main.rs | 88 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/src/main.rs b/src/main.rs index 35aa487..da62636 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,13 +4,19 @@ extern crate alloc; use core::mem::MaybeUninit; use esp_backtrace as _; -//use esp_println::println; use embedded_hal::serial::Read; use hal::{clock::ClockControl, i2c::I2C, peripherals::Peripherals, prelude::*}; -use hal::{uart, Uart /*Delay*/, IO}; +use hal::{ + ledc::{ + channel::{self, ChannelIFace}, + timer::{self, TimerIFace}, + HighSpeed, LEDC, + }, + uart, Uart, /*Delay*/ + IO, +}; -use si5351; use si5351::{Si5351, Si5351Device}; #[global_allocator] @@ -62,13 +68,41 @@ fn main() -> ! { log::info!("Si5351 Initialized succesfully"); main_loop(clock, serial); } - Err(si5351::Error::CommunicationError) => { - log::info!("Could not initialize Si5351: CommunicationError"); - main_loop(Dummy {}, serial); - } - Err(si5351::Error::InvalidParameter) => { - log::info!("Could not initialize Si5351: InvalidParameter"); - main_loop(Dummy {}, serial); + Err(e) => { + match e { + si5351::Error::InvalidParameter => { + log::warn!("Could not initialize Si5351; Using LedC PWM") + } + si5351::Error::CommunicationError => { + log::info!("Could not find Si5351 device; Using LedC PWM") + } + } + let ledc = LEDC::new( + peripherals.LEDC, + &clocks, + &mut system.peripheral_clock_control, + ); + let led = io.pins.gpio4.into_push_pull_output(); + + let mut hstimer0 = ledc.get_timer::(timer::Number::Timer0); + hstimer0 + .configure(timer::config::Config { + duty: timer::config::Duty::Duty5Bit, + clock_source: timer::HSClockSource::APBClk, + frequency: 1u32.MHz(), + }) + .unwrap(); + + let mut channel0 = ledc.get_channel(channel::Number::Channel0, led); + channel0 + .configure(channel::config::Config { + timer: &hstimer0, + duty_pct: 50, + pin_config: channel::config::PinConfig::PushPull, + }) + .unwrap(); + + main_loop(ledc, serial); } } } @@ -87,9 +121,27 @@ fn main_loop(mut clock: T, mut serial: trait Clockable { fn set_freq(&mut self, freq: u32) -> Result<(), ()>; } -impl Clockable for T + +impl Clockable for LEDC<'_> { + fn set_freq(&mut self, freq: u32) -> Result<(), ()> { + let mut hstimer0 = self.get_timer::(timer::Number::Timer0); + + let res = hstimer0.configure(timer::config::Config { + duty: timer::config::Duty::Duty5Bit, + clock_source: timer::HSClockSource::APBClk, + frequency: freq.Hz(), + }); + + match res { + Ok(_) => Ok(()), + Err(_) => Err(()), + } + } +} + +impl Clockable for Si5351Device where - T: Si5351, + Si5351Device: Si5351, { fn set_freq(&mut self, freq: u32) -> Result<(), ()> { match self.set_frequency(si5351::PLL::A, si5351::ClockOutput::Clk0, freq) { @@ -130,28 +182,28 @@ fn read_freq(serial: &mut Uart<'_, T>) -> u32 { loop { match nb::block!(serial.read()) { Ok(input) if input >= b'0' && input <= b'9' => { - log::info!("Got char: {}", char::from(input)); + log::debug!("Got char: {}", char::from(input)); freq = (freq * 10) + (input - b'0') as u32; } Ok(input) if invalid && (input == b'\n' || input == b'\r') => { - log::info!("Got bad end: {}", char::from(input)); + log::debug!("Got bad end: {}", char::from(input)); freq = 0; invalid = false; } Ok(input) if !invalid && (input == b'\n' || input == b'\r') => { - log::info!("Got end: {}", char::from(input)); + log::debug!("Got end: {}", char::from(input)); break; } Ok(input) if input == b'.' || input == b',' || input == b'_' => { - log::info!("Got ignor: {}", char::from(input)); + log::debug!("Got ignor: {}", char::from(input)); continue; } Ok(input) => { - log::info!("Got inval: {}", char::from(input)); + log::debug!("Got inval: {}", char::from(input)); invalid = true; } Err(e) => { - log::info!("Got error: {:?}", e); + log::debug!("Got error: {:?}", e); } } }