initial working demo of PWM dac w/ sinusoidal data

This commit is contained in:
sigil-03 2025-07-27 14:58:39 -06:00
parent faa1622857
commit 0ac166bf5e
4 changed files with 79 additions and 6 deletions

View file

@ -6,7 +6,30 @@
use hal::delay::Delay;
use hal::gpio::{AnyPin, Level, Output, Pin};
use {ch32_hal as hal};
use hal::time::Hertz;
use hal::timer::low_level::CountingMode;
use hal::timer::simple_pwm::{PwmPin, SimplePwm};
use hal::timer::{Channel, GeneralInstance16bit};
// const DAC_DATA: [u8; 4] = [0x0, 0x80, 0xFF, 0x80];
const DAC_DATA: [u8; 8] = [0, 25, 50, 75, 100, 75, 50, 25];
struct SimplePwmDacPin<'d, T: GeneralInstance16bit>{
pin: SimplePwm<'d, T>,
ch: Channel,
}
use adpcm_pwm_dac::{interface::DacInterface, dac::Dac};
impl<T> DacInterface for SimplePwmDacPin<'_, T>
where T: GeneralInstance16bit {
fn write_amplitude(&mut self, amplitude: u8) {
let max_duty = self.pin.get_max_duty();
let dc = amplitude as u32 * max_duty / 100;
self.pin.set_duty(self.ch, dc);
}
}
fn blink(pin: AnyPin, interval_ms: u64) {
let mut led = Output::new(pin, Level::Low, Default::default());
@ -26,14 +49,61 @@ fn blink(pin: AnyPin, interval_ms: u64) {
}
}
fn pwm_blink<T: GeneralInstance16bit>(mut pwm_dac_pin: SimplePwmDacPin<'_, T>) {
let mut delay = Delay;
let interval_ms = 1000u32;
loop {
pwm_dac_pin.write_amplitude(75);
delay.delay_ms((interval_ms/2) as u32);
pwm_dac_pin.write_amplitude(50);
delay.delay_ms((interval_ms/2) as u32);
pwm_dac_pin.write_amplitude(25);
delay.delay_ms((interval_ms/2) as u32);
}
}
fn dac_run<T: DacInterface>(mut dac: Dac<'_, T>, sample_rate: usize) {
let mut delay = Delay;
dac.load_data(&DAC_DATA);
let interval_us = 1000000/sample_rate as u32;
loop {
dac.output_next();
delay.delay_us(interval_us);
}
}
#[qingke_rt::entry]
fn main() -> ! {
let mut config = hal::Config::default();
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSE;
let p = hal::init(config);
let mut delay = Delay;
let pin = PwmPin::new_ch4::<0>(p.PC4);
let ch = hal::timer::Channel::Ch4;
let mut pwm = SimplePwm::new(
p.TIM1,
None,
None,
None,
Some(pin),
Hertz::khz(24),
CountingMode::default(),
);
pwm.enable(ch);
let mut pwm_dac_pin = SimplePwmDacPin{pin: pwm, ch};
let mut dac = Dac::new(pwm_dac_pin);
let sample_rate_hz = 440 * DAC_DATA.len();
// pwm_blink(pwm_dac_pin);
dac_run(dac, sample_rate_hz);
blink(p.PD6.degrade(), 100);
loop{};
}