79 lines
2.5 KiB
Rust
79 lines
2.5 KiB
Rust
use esp_idf_hal::gpio::OutputPin;
|
|
use esp_idf_hal::ledc;
|
|
use esp_idf_hal::ledc::{config::TimerConfig, Channel, Timer};
|
|
use esp_idf_hal::prelude::*;
|
|
use esp_idf_sys::EspError;
|
|
use std::thread;
|
|
use std::time::Duration;
|
|
|
|
type LedcChannel<P, T, C> = Channel<C, T, Timer<T>, P>;
|
|
|
|
pub struct Beep<P: OutputPin, T: ledc::HwTimer, C: ledc::HwChannel> {
|
|
beat: u8,
|
|
ringtone: ringtone::Type,
|
|
channel: LedcChannel<P, T, C>,
|
|
duty: u32,
|
|
}
|
|
|
|
impl<P: OutputPin, T: ledc::HwTimer, C: ledc::HwChannel> Beep<P, T, C> {
|
|
pub fn new(pin: P, timer: T, channel: C) -> Result<Self, EspError> {
|
|
let channel = Self::init_channel(pin, timer, channel)?;
|
|
|
|
let max_duty = channel.get_max_duty();
|
|
return Ok(Beep {
|
|
channel,
|
|
beat: 0,
|
|
duty: max_duty * 3 / 4,
|
|
ringtone: ringtone::SILENCE,
|
|
});
|
|
}
|
|
|
|
fn init_channel(pin: P, timer: T, channel: C) -> Result<LedcChannel<P, T, C>, EspError> {
|
|
let config = TimerConfig::default().frequency(2.kHz().into());
|
|
let timer = Timer::new(timer, &config)?;
|
|
let channel: Channel<C, T, Timer<T>, P> = Channel::new(channel, timer, pin)?;
|
|
return Ok(channel);
|
|
}
|
|
|
|
pub fn play(&mut self, rx: &mut std::sync::mpsc::Receiver<ringtone::Type>) {
|
|
loop {
|
|
let curr_ringtone = rx.try_recv().unwrap_or_else(|_| self.ringtone);
|
|
if !curr_ringtone.eq(&mut self.ringtone) {
|
|
self.beat = 0;
|
|
self.ringtone = curr_ringtone;
|
|
}
|
|
|
|
let curr = curr_ringtone[self.beat as usize];
|
|
if curr {
|
|
self.channel.set_duty(self.duty).expect("Failed to set duty");
|
|
} else {
|
|
self.channel.set_duty(0).expect("Failed to set duty");
|
|
}
|
|
thread::sleep(Duration::from_millis(100));
|
|
|
|
self.beat += 1;
|
|
if self.beat == 16 {
|
|
self.beat = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
pub mod ringtone {
|
|
|
|
pub type Type = [bool; 16];
|
|
|
|
pub const ADAPTER_DOWN: Type = [
|
|
true, true, true, true, false, false, false, false, false, false, false, false, false,
|
|
false, false, false,
|
|
];
|
|
pub const BATTERY_LOW: Type = [
|
|
true, true, false, false, true, true, false, false, true, true, false, false, true, true,
|
|
false, false,
|
|
];
|
|
pub const SILENCE: Type = [false; 16];
|
|
pub const SHUTDOWN: Type = [
|
|
true, false, true, true, true, true, false, true, true, true, true, true, false, false,
|
|
false, false,
|
|
];
|
|
}
|