From 13a1b99cb540be75c8f8e5a99e53f5531a5e1c0a Mon Sep 17 00:00:00 2001 From: Ivan Li Date: Sat, 10 Sep 2022 16:10:13 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20Beep=20=E6=9C=89=E6=A6=82=E7=8E=87?= =?UTF-8?q?=E5=B4=A9=E6=BA=83=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/beep.rs | 57 +++++++++++++++++++++++++++----------------- src/eventloop.rs | 0 src/main.rs | 3 +-- src/message_queue.rs | 5 +--- 4 files changed, 37 insertions(+), 28 deletions(-) delete mode 100644 src/eventloop.rs diff --git a/src/beep.rs b/src/beep.rs index 82f7b59..7ab55b8 100644 --- a/src/beep.rs +++ b/src/beep.rs @@ -4,9 +4,9 @@ use esp_idf_hal::ledc::{config::TimerConfig, Channel, Timer}; use esp_idf_hal::ledc::{CHANNEL0, TIMER0}; use esp_idf_hal::prelude::*; use esp_idf_svc::timer::{EspTimer, EspTimerService}; -use esp_idf_sys::EspError; +use esp_idf_sys::{ledc_mode_t_LEDC_LOW_SPEED_MODE, ledc_set_freq, EspError}; use log::{info, warn}; -use std::sync::{Arc, Mutex}; +use std::sync::{Arc, Mutex, MutexGuard}; use std::time::Duration; type LedcChannel = Channel, P>; @@ -28,16 +28,28 @@ impl BeepState { } } +type BeepChannel = Channel, Gpio4>; + pub struct Beep { watch_timer: Option, state: BeepState, + channel: Arc>, } impl Beep { - pub fn new() -> Self { - return Beep { + pub fn new() -> anyhow::Result { + let pin = unsafe { Gpio4::::new() } + .into_output() + .map_err(|err| anyhow::anyhow!("Failed to set GPIO 4 as ledc output. {}", err))?; + let hw_timer = unsafe { TIMER0::new() }; + let hw_channel = unsafe { CHANNEL0::new() }; + let channel = Self::init_channel(pin, hw_timer, hw_channel, 1000.Hz().into()) + .map_err(|err| anyhow::anyhow!("Failed to initialize channel. {}", err))?; + + return anyhow::Ok(Beep { watch_timer: None, state: BeepState::new(), - }; + channel: Arc::new(Mutex::new(channel)), + }); } fn init_channel( pin: Gpio4, @@ -58,40 +70,37 @@ impl Beep { return Ok(()); } let state = Arc::new(Mutex::new(self.state)); - let mut timer = EspTimerService::new()?.timer(move || { - match state.lock().as_mut() { + let channel = self.channel.to_owned(); + let mut timer = EspTimerService::new()? + .timer(move || match state.lock().as_mut() { Ok(state) => { - if let Err(err) = Self::play_once(state) { + if let Err(err) = Self::play_once(state, channel.lock().unwrap()) { warn!("{}", err); } } Err(err) => { warn!("Failed to lock state. {}", err); } - } - }).map_err(|err| anyhow::anyhow!("Init Timer Failed. {}", err))?; + }) + .map_err(|err| anyhow::anyhow!("Init Timer Failed. {}", err))?; timer.every(Duration::from_millis(250))?; self.watch_timer = Some(timer); return anyhow::Ok(()); } - fn play_once(state: &mut BeepState) -> anyhow::Result<()> { - let pin = unsafe { Gpio4::::new() } - .into_output() - .map_err(|err| anyhow::anyhow!("Failed to set GPIO 4 as ledc output. {}", err))?; - let hw_timer = unsafe { TIMER0::new() }; - let hw_channel = unsafe { CHANNEL0::new() }; + fn play_once( + state: &mut BeepState, + mut channel: MutexGuard, + ) -> anyhow::Result<()> { if state.ringtone.len() <= state.beat as usize { state.beat = 0; } let curr = state.ringtone[state.beat as usize]; - let mut channel = Self::init_channel(pin, hw_timer, hw_channel, if curr < 1000 { 1000.Hz().into()} else {curr.Hz().into()} ) - .map_err(|err| anyhow::anyhow!("Failed to initialize channel. {}", err))?; - - if curr < 1000 { + if curr == 0 { channel.set_duty(0).expect("Failed to set duty"); } else { + unsafe { ledc_set_freq(ledc_mode_t_LEDC_LOW_SPEED_MODE, 0, curr); } channel.set_duty(60).expect("Failed to set duty"); } @@ -105,7 +114,11 @@ impl Beep { pub mod ringtone { pub type Type = [u32; 16]; pub const ADAPTER_DOWN: Type = [2300, 2000, 2250, 1950, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - pub const BATTERY_LOW: Type = [2000, 1950, 0, 0, 1980, 1900, 0, 0, 2000, 1900, 0, 0, 1980, 1900, 0, 0]; + pub const BATTERY_LOW: Type = [ + 2000, 1950, 0, 0, 1980, 1900, 0, 0, 2000, 1900, 0, 0, 1980, 1900, 0, 0, + ]; pub const SILENCE: Type = [0; 16]; - pub const SHUTDOWN: Type = [3450, 3500, 0, 3500, 3050, 3000, 0, 3000, 3050, 1000, 1000, 1000, 0, 0, 0, 0]; + pub const SHUTDOWN: Type = [ + 3450, 3500, 0, 3500, 3050, 3000, 0, 3000, 3050, 1000, 1000, 1000, 0, 0, 0, 0, + ]; } diff --git a/src/eventloop.rs b/src/eventloop.rs deleted file mode 100644 index e69de29..0000000 diff --git a/src/main.rs b/src/main.rs index ad82b7e..bf05b10 100644 --- a/src/main.rs +++ b/src/main.rs @@ -44,7 +44,6 @@ fn main() { let blink_pin = peripherals.pins.gpio5; - info!("About to start a background event loop"); match EspBackgroundEventLoop::new(&Default::default()) { Ok(eventloop) => unsafe { VOLTAGE_EVENTLOOP = Some(eventloop) }, Err(err) => error!("Init Event Loop failed. {:?}", err), @@ -72,7 +71,7 @@ fn main() { sleep(Duration::from_millis(100)); - let mut beep = Beep::new(); + let mut beep = Beep::new().unwrap(); let mut dc_out_controller = DcOutController::get_instance().expect("Can not get DcOutController instance"); diff --git a/src/message_queue.rs b/src/message_queue.rs index 5c95911..71f175b 100644 --- a/src/message_queue.rs +++ b/src/message_queue.rs @@ -9,10 +9,7 @@ use std::{ use anyhow::Result; use embedded_svc::mqtt::client::{utils::ConnState, Client, Connection, MessageImpl, Publish, QoS}; -use esp_idf_svc::{ - eventloop::{Background, EspEventLoop}, - mqtt::client::{EspMqttClient, MqttClientConfiguration}, -}; +use esp_idf_svc::mqtt::client::{EspMqttClient, MqttClientConfiguration}; use esp_idf_sys::EspError; use log::*;