broken embassy example. leds work, but break when you sample faster

This commit is contained in:
sigil-03 2025-08-10 17:53:49 -06:00
parent 5be93cc32e
commit 33a9fb175e
5 changed files with 100 additions and 157 deletions

View file

@ -8,10 +8,10 @@ target = "riscv32ec-unknown-none-elf.json"
# runner = "gdb -q -x openocd.gdb" # runner = "gdb -q -x openocd.gdb"
# runner = "wlink -v flash" # runner = "wlink -v flash"
# runner = "wlink -v flash --enable-sdi-print --watch-serial" runner = "wlink -v flash --enable-sdi-print --watch-serial"
# Flash and debug chip with probe-rs. https://probe.rs/ # Flash and debug chip with probe-rs. https://probe.rs/
runner = "probe-rs run --chip ch32v003" #runner = "probe-rs run --chip ch32v003"
[unstable] [unstable]
build-std = ["core"] build-std = ["core"]

View file

@ -18,27 +18,6 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61" checksum = "dc827186963e592360843fb5ba4b973e145841266c1357f7180c43526f2e5b61"
[[package]]
name = "bitfields"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcdbce6688e3ab66aff2ab413b762ccde9f37990e27bba0bb38a4b2ad1b5d877"
dependencies = [
"bitfields-impl",
]
[[package]]
name = "bitfields-impl"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57413e4b276d883b77fb368b7b33ae6a5eb97692852d49a5394d4f72ba961827"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.104",
"thiserror",
]
[[package]] [[package]]
name = "byteorder" name = "byteorder"
version = "1.5.0" version = "1.5.0"
@ -92,11 +71,13 @@ name = "ch32v-insert-coin"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"adpcm-pwm-dac", "adpcm-pwm-dac",
"bitfields",
"ch32-hal", "ch32-hal",
"critical-section",
"embassy-executor", "embassy-executor",
"embassy-time",
"embedded-hal 1.0.0", "embedded-hal 1.0.0",
"panic-halt", "panic-halt",
"qingke",
"qingke-rt", "qingke-rt",
] ]
@ -615,26 +596,6 @@ dependencies = [
"unicode-ident", "unicode-ident",
] ]
[[package]]
name = "thiserror"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.104",
]
[[package]] [[package]]
name = "unicode-ident" name = "unicode-ident"
version = "1.0.18" version = "1.0.18"

View file

@ -5,32 +5,37 @@ edition = "2024"
[dependencies] [dependencies]
ch32-hal = { path = "ext/ch32-hal/", features = [ ch32-hal = { path = "ext/ch32-hal/", features = [
"ch32v003f4u6", "ch32v003f4p6",
"memory-x", "memory-x",
"embassy", "embassy",
"time-driver-tim2", "time-driver-tim2",
"rt", "rt",
] } ] }
critical-section = "1.2.0"
embassy-executor = { version = "0.7.0", features = [ embassy-executor = { version = "0.7.0", features = [
"arch-spin", "arch-riscv32",
"executor-thread", "executor-thread",
"task-arena-size-128", # or better use nightly, but fails on recent Rust versions #"nightly",
"task-arena-size-512", # or better use nightly, but fails on recent Rust versions
] } ] }
embassy-time = "0.4.0"
panic-halt = "1.0" panic-halt = "1.0"
embedded-hal = "1.0.0" embedded-hal = "1.0.0"
qingke = "*"
qingke-rt = { version = "*", features = ["highcode"] } qingke-rt = { version = "*", features = ["highcode"] }
adpcm-pwm-dac = { path = "ext/adpcm-pwm-dac/" } adpcm-pwm-dac = { path = "ext/adpcm-pwm-dac/" }
bitfields = "1.0.0"
[profile.release] [profile.release]
strip = false # symbols are not flashed to the microcontroller, so don't strip them. strip = false # symbols are not flashed to the microcontroller, so don't strip them.
lto = true lto = true
opt-level = "s" # Optimize for size. opt-level = "z" # Optimize for size.
[profile.dev] [profile.dev]
overflow-checks = false overflow-checks = false

@ -1 +1 @@
Subproject commit e6114d2c521ef3a769bd2a52411e3a938b566908 Subproject commit 714715b4aae512d1384b7387e3d2f695ea9b348e

View file

@ -3,7 +3,10 @@
#![feature(type_alias_impl_trait)] #![feature(type_alias_impl_trait)]
#![feature(impl_trait_in_assoc_type)] #![feature(impl_trait_in_assoc_type)]
use core::any::Any;
use adpcm_pwm_dac::dac::DpcmDac; use adpcm_pwm_dac::dac::DpcmDac;
use ch32_hal::{exti::ExtiInput, pac::systick::Systick};
use {ch32_hal as hal}; use {ch32_hal as hal};
use hal::peripherals::EXTI4; use hal::peripherals::EXTI4;
use hal::{bind_interrupts, interrupt}; use hal::{bind_interrupts, interrupt};
@ -14,6 +17,13 @@ use hal::timer::low_level::CountingMode;
use hal::timer::simple_pwm::{PwmPin, SimplePwm}; use hal::timer::simple_pwm::{PwmPin, SimplePwm};
use hal::timer::{Channel, GeneralInstance16bit}; use hal::timer::{Channel, GeneralInstance16bit};
// embassy shit
use embassy_executor::Spawner;
use embassy_time::{Duration, Timer};
// const DAC_DATA: [u8; 4] = [0x0, 0x80, 0xFF, 0x80]; // const DAC_DATA: [u8; 4] = [0x0, 0x80, 0xFF, 0x80];
const DAC_DATA: [u8; 8] = [0, 25, 50, 75, 100, 75, 50, 25]; const DAC_DATA: [u8; 8] = [0, 25, 50, 75, 100, 75, 50, 25];
@ -27,9 +37,11 @@ const DAC_DATA: [u8; 8] = [0, 25, 50, 75, 100, 75, 50, 25];
// - 25 -> 0xA // - 25 -> 0xA
// - 25 -> 0xA // - 25 -> 0xA
// - 25 -> 0xA // - 25 -> 0xA
const DPCM_DAC_DATA: [u8; 4] = [0xBB, 0xBB, 0xAA, 0xAA]; // const DPCM_DAC_DATA: [u8; 4] = [0xBB, 0xBB, 0xAA, 0xAA];
// const DATA2: [u8; 1] = [0x00u8]; // const DATA2: [u8; 1] = [0x00u8];
// const DAC_DATA_1: &'static [u8] = include_bytes!("../../../dpcm-encoder-decoder/sweep_dpcm_u4.raw");
static mut IRQ1_FLAG: bool = false; static mut IRQ1_FLAG: bool = false;
@ -45,101 +57,69 @@ use adpcm_pwm_dac::{interface::DacInterface, dac::Dac};
impl<T> DacInterface for SimplePwmDacPin<'_, T> impl<T> DacInterface for SimplePwmDacPin<'_, T>
where T: GeneralInstance16bit { where T: GeneralInstance16bit {
fn write_amplitude(&mut self, amplitude: u8) { fn write_amplitude(&mut self, amplitude: u8) {
if !self.pin.is_enabled(self.ch) {
self.pin.enable(self.ch);
}
let max_duty = self.pin.get_max_duty(); let max_duty = self.pin.get_max_duty();
let dc = amplitude as u32 * max_duty / 100; let dc = amplitude as u32 * max_duty / 100;
self.pin.set_duty(self.ch, dc); self.pin.set_duty(self.ch, dc);
} }
} fn disable(&mut self) {
self.pin.disable(self.ch);
fn blink(pin: AnyPin, interval_ms: u64) {
let mut led = Output::new(pin, Level::Low, Default::default());
let mut delay = Delay;
loop {
let hb_count = 3;
let hb_period_ms = 1000;
for _ in 0..hb_count {
led.set_low();
delay.delay_ms((interval_ms/2) as u32);
led.set_high();
delay.delay_ms((interval_ms/2) as u32);
}
delay.delay_ms((hb_period_ms - (interval_ms * hb_count)) as u32);
} }
} }
fn pwm_blink<T: GeneralInstance16bit>(mut pwm_dac_pin: SimplePwmDacPin<'_, T>) { #[embassy_executor::task(pool_size = 2)]
let mut delay = Delay; async fn led_task(mut pin: AnyPin, period: u64) {
let mut led = Output::new(pin, Level::High, Default::default());
let interval_ms = 1000u32;
loop { loop {
pwm_dac_pin.write_amplitude(75); led.toggle();
delay.delay_ms((interval_ms/2) as u32); Timer::after(Duration::from_millis(period)).await;
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) { // #[embassy_executor::task(pool_size = 1)]
// fn dac_run<T: DacInterface>(mut dac: DpcmDac<'_, T>, sample_rate: usize) { // async fn audio_task(mut dac: DpcmDac<'static, SimplePwmDacPin<'static, hal::peripherals::TIM1>>) {
// // // DAC servicer computations
// // let data = include_bytes!("../../../dpcm-encoder-decoder/sweep_dpcm_u4.raw");
// let mut dac_active = true;
// // let sample_rate_hz = 16000;
// let sample_rate_hz = 440;
// let tick_interval_us = 1000000/(sample_rate_hz);
// dac.load_data(&DAC_DATA);
// dac.load_data(data);
// // dac.load_data(&DAC_DATA);
// let interval_us = 1000000/sample_rate as u32;
// loop { // loop {
// dac.output_next();
// // if(dac_need_service && dac_active) {
// // dac_active = dac.output_next();
// // if !dac_active {
// // dac.disable_output();
// // }
// // }
// Timer::after(Duration::from_micros(tick_interval_us)).await;
// } // }
// } // }
#[embassy_executor::main(entry = "ch32_hal::entry")]
#[qingke_rt::interrupt] async fn main(spawner: Spawner) -> ! {
fn EXTI4(){
unsafe{IRQ1_FLAG = true;};
}
// bind_interrupts!(struct Irqs {
// EXTI4 => button_press();
// });
#[qingke_rt::entry]
fn main() -> ! {
let mut config = hal::Config::default(); let mut config = hal::Config::default();
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSE; config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSI;
let p = hal::init(config); let p = hal::init(config);
// button 1 setup
// let b1 = Input::new(p.PA2, Pull::Up);
// p.EXTI4 // p.EXTI4
let ei = hal::exti::ExtiInput::new(p.PD4, p.EXTI4, Pull::Up); let mut ei = hal::exti::ExtiInput::new(p.PD4, p.EXTI4, Pull::Up);
// let led_pin = PwmPin::new_ch4::<0>(p.PD0);
// let ch = hal::timer::Channel::Ch4;
// let mut pwm = SimplePwm::new(
// p.TIM1,
// None,
// None,
// None,
// Some(pin),
// Hertz::khz(100),
// CountingMode::default(),
// );
// pwm.enable(ch);
//
// LED output setup // LED output setup
let mut led = Output::new(p.PD0, Level::Low, Default::default()); // let mut led = Output::new(p.PD0, Level::Low, Default::default());
// LED1 output setup // LED1 output setup
let mut led1 = Output::new(p.PD6, Level::High, Default::default()); // let mut led1 = Output::new(p.PD6, Level::High, Default::default());
// PWM DAC output pin setup // PWM DAC output pin setup
@ -154,65 +134,62 @@ fn main() -> ! {
Hertz::khz(100), Hertz::khz(100),
CountingMode::default(), CountingMode::default(),
); );
pwm.enable(ch);
let mut pwm_dac_pin = SimplePwmDacPin{pin: pwm, ch}; let mut pwm_dac_pin = SimplePwmDacPin{pin: pwm, ch};
let mut delay = Delay;
// DAC setup // DAC setup
let mut dac = DpcmDac::new(pwm_dac_pin); let mut dac = DpcmDac::new(pwm_dac_pin);
let data = include_bytes!("../../../dpcm-encoder-decoder/sweep_dpcm_u4.raw"); // dac.load_data(data);
dac.load_data(data);
// DAC servicer computations // DAC servicer computations
let mut dac_active = true; let mut dac_active = true;
let sample_rate_hz = 16000; let sample_rate_hz = 16000;
let dac_tick_per_service = 5; let dac_tick_per_service = 1;
let tick_rate_hz = sample_rate_hz * dac_tick_per_service; let tick_rate_hz = sample_rate_hz * dac_tick_per_service;
let tick_interval = 1000000/(tick_rate_hz); let tick_interval_us = 1000000/(tick_rate_hz);
// LED servicer computations // // LED servicer computations
let mut led_active = true; // let mut led_active = true;
let led_blink_rate_hz = 3; // let led_blink_rate_hz = 3;
let led_tick_per_service = (tick_rate_hz/(led_blink_rate_hz * 2)); // let led_tick_per_service = (tick_rate_hz/(led_blink_rate_hz * 2));
// LED1 servicer vars // // LED1 servicer vars
let mut led1_need_service = false; // let mut led1_need_service = false;
// pwm_blink(pwm_dac_pin); // let mut tick: usize = 0;
let mut tick: usize = 0;
ei.wait_for_falling_edge().await;
spawner.spawn(led_task(p.PD6.degrade(), 250)).unwrap();
spawner.spawn(led_task(p.PD0.degrade(), 100)).unwrap();
// spawner.spawn(audio_task(dac)).unwrap();
loop{ loop{
// handle IRQ flags // let dac_need_service = ((tick % dac_tick_per_service) == 0);
unsafe { // if(dac_need_service && dac_active) {
if(IRQ1_FLAG) { // dac_active = dac.output_next();
led1_need_service = true; // if !dac_active {
// led_active = true; // dac.disable_output();
IRQ1_FLAG = false; // }
} // }
}
let dac_need_service = ((tick % dac_tick_per_service) == 0); dac.output_next();
if(dac_need_service && dac_active) {
dac_active = dac.output_next();
}
let led_need_service = ((tick % led_tick_per_service) == 0); // let led_need_service = ((tick % led_tick_per_service) == 0);
if(led_need_service && led_active) { // if(led_need_service && led_active) {
led.toggle(); // led.toggle();
} // }
// tick = tick.wrapping_add(1);
// delay.delay_us(tick_interval as u32);
// Timer::after_micros(tick_interval as u64).await;
// Timer::after_micros(1000000u64).await;
// Timer::after(Duration::from_millis(2000)).await;
Timer::after(Duration::from_micros(tick_interval_us)).await;
if led1_need_service {
led1.set_low();
led1_need_service = false;
}
tick = tick.wrapping_add(1);
delay.delay_us(tick_interval as u32);
}; };
} }