add interrupts for most handlers

This commit is contained in:
sigil-03 2025-08-21 11:08:26 -06:00
parent e3235b34a4
commit a71c7986e6
15 changed files with 1028 additions and 280 deletions

View file

@ -1,8 +1,6 @@
use adpcm_pwm_dac::dac;
use ch32_hal::timer::GeneralInstance16bit;
use ch32_hal::timer::simple_pwm::SimplePwm;
use ch32_hal::timer::Channel;
use ch32_hal::delay::Delay;
use crate::insert_coin::services::{DacService, LedService, TickService, TickServiceData, Service};
@ -40,9 +38,9 @@ impl<'d, T: GeneralInstance16bit> SimplePwmCore<'d, T> {
self.pwm.borrow_mut().set_duty(ch, dc);
}
pub fn disable(&self, ch: Channel) {
self.pwm.borrow_mut().disable(ch);
}
// pub fn disable(&self, ch: Channel) {
// self.pwm.borrow_mut().disable(ch);
// }
}
@ -61,7 +59,7 @@ impl CoreConfig {
#[derive(Default)]
struct Core {
tick: usize,
_tick: usize,
active: bool,
}
@ -73,7 +71,7 @@ pub struct InsertCoin<'a, T: GeneralInstance16bit> {
pub led1: LedService,
// led2: LedService,
dac: DacService<'a>,
pub dac: DacService<'a>,
}
impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> {
@ -82,25 +80,17 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> {
// LED0 servicer setup
let led0_blink_rate_hz = 9;
let led0_tick_per_service = (config.tick_rate_hz/(led0_blink_rate_hz * 2));
let led0_service_data = TickServiceData::new(led0_tick_per_service);
let led0 = LedService::new(ch32_hal::timer::Channel::Ch3, led0_service_data);
let led0 = LedService::new(ch32_hal::timer::Channel::Ch3);
// LED1 servicer setup
let led1_blink_rate_hz = 3;
let led1_tick_per_service = (config.tick_rate_hz/(led1_blink_rate_hz * 2));
let led1_service_data = TickServiceData::new(led1_tick_per_service);
let led1 = LedService::new(ch32_hal::timer::Channel::Ch1, led1_service_data);
let led1 = LedService::new(ch32_hal::timer::Channel::Ch1);
// DAC servicer setup
let dac_sample_rate_hz = 16000;
let dac_tick_per_service = (config.tick_rate_hz/(dac_sample_rate_hz));
let dac_tick_per_service = config.tick_rate_hz/(dac_sample_rate_hz);
let dac_service_data = TickServiceData::new(dac_tick_per_service);
let dac = DacService::new(ch32_hal::timer::Channel::Ch4, dac_service_data);
let data = include_bytes!("../../../../dpcm-encoder-decoder/sweep_dpcm_u4.raw");
dac.load_data(data);
Self {
config,
@ -110,11 +100,6 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> {
led1,
// led2,
dac,
// led1: Led {
// channel: hal::timer::Channel::Ch1,
// amplitude: 0,
// need_service: false,
// },
}
}
@ -144,55 +129,53 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> {
}
/// consumes self and runs
pub fn run(mut self) -> ! {
let mut delay = Delay;
let tick_interval_us = 1000000/self.config.tick_rate_hz;
// /// consumes self and runs
// pub fn run(mut self) -> ! {
// let mut delay = Delay;
// let tick_interval_us = 1000000/self.config.tick_rate_hz;
let mut led0_index = 0;
let led0_dcs = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8];
// let mut led0_index = 0;
// let led0_dcs = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8];
let mut led1_index = 0;
let led1_dcs = [0u8, 25u8, 50u8, 75u8, 100u8];
// let mut led1_index = 0;
// let led1_dcs = [0u8, 25u8, 50u8, 75u8, 100u8];
loop {
self.dac.tick();
// loop {
// self.dac.tick();
if(self.led0.need_service()) {
self.led0.set_amplitude(led0_dcs[led0_index]);
self.pwm_core.write_amplitude(self.led0.channel, self.led0.amplitude);
// if(self.led0.need_service()) {
// self.led0.set_amplitude(led0_dcs[led0_index]);
// self.pwm_core.write_amplitude(self.led0.channel, self.led0.amplitude);
led0_index += 1;
if led0_index > led0_dcs.len() - 1 {
led0_index = 0;
}
self.led0.service();
}
// led0_index += 1;
// if led0_index > led0_dcs.len() - 1 {
// led0_index = 0;
// }
// self.led0.service();
// }
if(self.led1.need_service()) {
self.led1.set_amplitude(led1_dcs[led1_index]);
self.pwm_core.write_amplitude(self.led1.channel, self.led1.amplitude);
// if(self.led1.need_service()) {
// self.led1.set_amplitude(led1_dcs[led1_index]);
// self.pwm_core.write_amplitude(self.led1.channel, self.led1.amplitude);
led1_index += 1;
if led1_index > led1_dcs.len() - 1 {
led1_index = 0;
}
self.led1.service();
}
// led1_index += 1;
// if led1_index > led1_dcs.len() - 1 {
// led1_index = 0;
// }
// self.led1.service();
// }
if(self.dac.need_service()) {
self.dac.service();
// TODO: adpcm-pwm-dac:e4c811653781e69e40b63fd27a8c1e20
self.pwm_core.write_amplitude(self.dac.channel, self.dac.get_amplitude() as u8);
}
// if(self.dac.need_service()) {
// self.dac.service();
// // TODO: adpcm-pwm-dac:e4c811653781e69e40b63fd27a8c1e20
// self.pwm_core.write_amplitude(self.dac.channel, self.dac.get_amplitude() as u8);
// }
delay.delay_us(tick_interval_us as u32);
}
}
// delay.delay_us(tick_interval_us as u32);
// }
// }
pub fn is_active(&self) -> bool {
self.core.active

View file

@ -1,8 +1,7 @@
mod insert_coin;
mod services;
use services::LedService;
pub use services::TickTimerService;
pub use services::{TickService, TickServiceData, Service};
pub use services::{TickService, TickServiceData};
pub use insert_coin::{InsertCoin, CoreConfig, SimplePwmCore};

View file

@ -1,7 +1,7 @@
use crate::insert_coin::services::{TickServiceData, TickService};
use adpcm_pwm_dac::{dac::{DpcmDac, DpcmDecoder}, interface::DacInterface};
use adpcm_pwm_dac::dac::DpcmDecoder;
use ch32_hal::timer::Channel;
pub struct DacService<'a> {
@ -23,6 +23,7 @@ impl<'a> DacService<'a> {
pub fn load_data(&self, data: &'a [u8]) {
self.dpcm_decoder.borrow_mut().load_data(data);
self.dpcm_decoder.borrow_mut().seek_to_sample(0);
}
pub fn set_amplitude(&self, amplitude: usize) {

View file

@ -1,6 +1,6 @@
use ch32_hal::timer::Channel;
use crate::insert_coin::services::{Service, TickService, TickServiceData};
use crate::insert_coin::services::{Service};
pub struct LedService {
// need_service: core::cell::RefCell<bool>,
@ -10,7 +10,7 @@ pub struct LedService {
}
impl LedService {
pub fn new(channel: Channel, service_data: TickServiceData) -> Self {
pub fn new(channel: Channel) -> Self {
Self {
// service_data: core::cell::RefCell::new(service_data),
need_service: false,

View file

@ -1,10 +1,8 @@
use ch32_hal::timer::Channel;
use crate::insert_coin::services::{TickServiceData, TickService};
pub struct TickTimerService {
service_data: core::cell::RefCell<TickServiceData>,
auto_reset: bool,
_auto_reset: bool,
enabled: bool,
}
@ -12,18 +10,18 @@ impl TickTimerService {
pub fn new(service_data: TickServiceData, auto_reset: bool) -> Self {
Self {
service_data: core::cell::RefCell::new(service_data),
auto_reset,
_auto_reset: auto_reset,
enabled: false,
}
}
pub fn is_enabled(&self) -> bool {
self.enabled
}
// pub fn is_enabled(&self) -> bool {
// self.enabled
// }
pub fn reset(&mut self) {
let mut sd = self.service_data.borrow_mut();
sd.ticks_per_service = sd.ticks_remaining;
sd.ticks_remaining = sd.ticks_per_service;
self.enabled = false;
}

View file

@ -4,85 +4,167 @@
#![feature(impl_trait_in_assoc_type)]
mod insert_coin;
use ch32_hal::{interrupt::typelevel::Handler, timer::low_level::OutputPolarity};
use insert_coin::{InsertCoin, SimplePwmCore, CoreConfig};
use adpcm_pwm_dac::dac::DpcmDac;
use {ch32_hal as hal};
use hal::peripherals::EXTI4;
use hal::{bind_interrupts, interrupt};
use hal::{bind_interrupts};
use hal::delay::Delay;
use hal::gpio::{AnyPin, Level, Input, Output, Pin, Pull};
use hal::gpio::{AnyPin, Input, Pin, Pull};
use hal::time::Hertz;
use hal::timer::low_level::CountingMode;
use hal::timer::simple_pwm::{PwmPin, SimplePwm};
use hal::timer::{Channel, GeneralInstance16bit};
// #[qingke_rt::interrupt]
// fn EXTI4(){
// unsafe{IRQ1_FLAG = true;};
// }
// bind_interrupts!(struct Irqs {
// EXTI4 => button_press();
// });
use hal::println;
use qingke::riscv;
// const DAC_DATA: [u8; 4] = [0x0, 0x80, 0xFF, 0x80];
const DAC_DATA: [u8; 8] = [0, 25, 50, 75, 100, 75, 50, 25];
struct DebouncedGPIO<'a> {
input: Input<'a>,
// value of the GPIO
value: bool,
// GPIO is ready (debounced)
ready: bool,
// debounce timer
timer: TickTimerService,
}
// DPCS DATA
// step size: 5
// 0
// + 25 -> [1, 0, 1, 1] -> 0xB
// + 25 -> 0xB
// + 25 -> 0xB
// + 25 -> 0xB
// - 25 -> 0xA
// - 25 -> 0xA
// - 25 -> 0xA
const DPCM_DAC_DATA: [u8; 4] = [0xBB, 0xBB, 0xAA, 0xAA];
impl<'a> DebouncedGPIO<'a> {
pub fn new(pin: AnyPin, system_tick_rate_hz: usize, debounce_time_ms: usize) -> Self {
// coin debounce timer (100ms)
Self {
input: Input::new(pin, Pull::Up),
value: false,
ready: false,
timer: TickTimerService::new(TickServiceData::new(system_tick_rate_hz * debounce_time_ms / 1000), false),
}
}
static mut IRQ1_FLAG: bool = false;
pub fn ready(&self) -> bool {
self.ready
}
pub fn value(&self) -> bool {
self.value
}
pub fn begin(&mut self) {
self.reset();
self.timer.enable(true);
}
pub fn reset(&mut self) {
self.timer.reset();
self.ready = false;
}
pub fn service(&mut self) {
self.timer.tick();
if self.timer.need_service() {
self.timer.reset();
self.value = self.input.is_high();
self.ready = true;
}
}
}
// struct SimplePwmHandle<'a, 'c, T: GeneralInstance16bit>{
// core: &'a SimplePwmCore<'c, T>,
// channel: Channel,
// }
// DeepSleep --coin button irq--> Active
// Active --2s button--> Idle
// Idle/Active --5s button--> DeepSleep
// impl<'a, 'c, T: GeneralInstance16bit> SimplePwmHandle<'a, 'c, T> {
// pub fn write_amplitude(&'a self, amplitude: u8) {
// self.core.write_amplitude(self.channel, amplitude);
// }
pub enum SystemState {
// system is asleep, waiting for wake from coin insertion
DeepSleep,
// system is in low-power mode, dimmed lights, waiting for interaction
Idle,
// system is active. on entry: play coin sound. on button press: play different sound
Active,
}
// pub fn disable(&'a self) {
// self.core.disable(self.channel);
// }
// }
unsafe fn init_gpio_irq(pin: u8, port: u8, rising: bool, falling: bool) {
critical_section::with(|_| {
println!("init_gpio_irq");
let exti = &hal::pac::EXTI;
let afio = &hal::pac::AFIO;
// struct SimplePwmDacHandle<'d, T: GeneralInstance16bit>{
// pin: core::cell::RefCell<SimplePwm<'d, T>>,
// ch: Channel,
// }
let port = port as u8;
let pin = pin as usize;
// let b = afio.exticr().read();
afio.exticr().modify(|w| w.set_exti(pin, port));
exti.intenr().modify(|w| w.set_mr(pin, true)); // enable interrupt
exti.rtenr().modify(|w| w.set_tr(pin, rising));
exti.ftenr().modify(|w| w.set_tr(pin, falling));
});
}
// use adpcm_pwm_dac::{interface::DacInterface, dac::Dac};
fn clear_interrupt (coin_pin: u8, button_pin: u8) {
let exti = &hal::pac::EXTI;
let coin_pin = coin_pin as usize;
let button_pin = button_pin as usize;
exti.intenr().modify(|w| w.set_mr(coin_pin, false)); // disable interrupt
exti.intenr().modify(|w| w.set_mr(button_pin, false)); // disable interrupt
let bits = exti.intfr().read();
// We don't handle or change any EXTI lines above 24.
let bits = bits.0 & 0x00FFFFFF;
// coin_flag
if (bits & (0x1 << coin_pin)) != 0x0 {
println!("coin irq!");
unsafe { INPUT_FLAGS.coin_flag = true; }
}
// button_flag
if (bits & (0x1 << button_pin)) != 0x0 {
println!("button irq!");
unsafe { INPUT_FLAGS.button_flag = true; }
}
// Clear pending - Clears the EXTI's line pending bits.
exti.intfr().write(|w| w.0 = bits);
exti.intenr().modify(|w| w.0 = w.0 & !bits);
exti.intenr().modify(|w| w.set_mr(coin_pin, true)); // enable interrupt
exti.intenr().modify(|w| w.set_mr(button_pin, true)); // enable interrupt
}
#[derive(Debug)]
struct InputFlags {
coin_flag: bool,
button_flag: bool,
}
static mut INPUT_FLAGS: InputFlags = InputFlags{coin_flag: false, button_flag: false};
struct Test {
}
impl Handler<hal::interrupt::typelevel::EXTI7_0> for Test {
unsafe fn on_interrupt() {
println!("on_interrupt()");
critical_section::with(|_| {
clear_interrupt(4, 6);
});
}
}
bind_interrupts!(struct Irqs {
EXTI7_0 => Test;
});
// impl<T> DacInterface for SimplePwmDacHandle<'_, T>
// where T: GeneralInstance16bit {
// fn write_amplitude(&mut self, amplitude: u8) {
// if !self.pin.borrow().is_enabled(self.ch) {
// self.pin.get_mut().enable(self.ch);
// }
// let max_duty = self.pin.borrow().get_max_duty();
// let dc = amplitude as u32 * max_duty / 100;
// self.pin.get_mut().set_duty(self.ch, dc);
// }
// fn disable(&mut self) {
// self.pin.get_mut().disable(self.ch);
// }
// }
// TODO: remove
use insert_coin::{TickService, TickServiceData};
@ -90,23 +172,28 @@ use insert_coin::TickTimerService;
#[qingke_rt::entry]
fn main() -> ! {
hal::debug::SDIPrint::enable();
let mut config = hal::Config::default();
config.rcc = hal::rcc::Config::SYSCLK_FREQ_48MHZ_HSE;
let p = hal::init(config);
// coin button input setup
let coin_button = Input::new(p.PD4, Pull::Up);
// delay to let the debugger attach
let mut delay = Delay;
delay.delay_ms(1000);
// p.EXTI4
// let ei = hal::exti::ExtiInput::new(p.PD4, p.EXTI4, Pull::Up);
// === output setup ===
// LED0 output setup
let mut led0_pin = PwmPin::new_ch3::<0>(p.PC3);
let led0_pin = PwmPin::new_ch3::<0>(p.PC3);
let led0_ch = hal::timer::Channel::Ch3;
// let mut led0_pin = Output::new(p.PC3, Level::High, Default::default());
// unsafe {
// LED = Some(led0_pin);
// }
// LED1 output setup
let mut led1_pin = PwmPin::new_ch1::<0>(p.PD2);
let led1_pin = PwmPin::new_ch1::<0>(p.PD2);
let led1_ch = hal::timer::Channel::Ch1;
@ -114,7 +201,7 @@ fn main() -> ! {
// DAC output setup
let dac_pin = PwmPin::new_ch4::<0>(p.PC4);
let dac_ch = hal::timer::Channel::Ch4;
// let dac_ch = hal::timer::Channel::Ch4;
@ -129,15 +216,38 @@ fn main() -> ! {
CountingMode::default(),
);
pwm.set_polarity(led0_ch, OutputPolarity::ActiveLow);
pwm.set_polarity(led1_ch, OutputPolarity::ActiveLow);
let sample_rate_hz = 16000;
let dac_tick_per_service = 5;
let tick_rate_hz = sample_rate_hz * dac_tick_per_service;
let config = CoreConfig::new(tick_rate_hz);
let core_config = CoreConfig::new(tick_rate_hz);
// === input setup ===
// definitions
let coin_pin = p.PD4;
let button_pin = p.PD6;
println!("coin pin: {} | coin port: {}", coin_pin.pin(), coin_pin.port());
println!("push pin: {} | push port: {}", button_pin.pin(), button_pin.port());
// set up interrupts
unsafe {init_gpio_irq(coin_pin.pin(), coin_pin.port(), false, true)};
unsafe {init_gpio_irq(button_pin.pin(), button_pin.port(), true, true)};
// coin debouncer (100ms)
let mut coin_input = DebouncedGPIO::new(coin_pin.degrade(), core_config.tick_rate_hz, 100);
// button debouncer (100ms)
let mut button_input = DebouncedGPIO::new(button_pin.degrade(), core_config.tick_rate_hz, 100);
let pwm_core = SimplePwmCore::new(pwm);
let mut interfaces = InsertCoin::new(config, pwm_core);
let mut interfaces = InsertCoin::new(core_config, pwm_core);
interfaces.set_active(true);
// insert_coin.init();
@ -149,22 +259,16 @@ fn main() -> ! {
// tick timer 0
let tt0_fire_rate_hz = 9;
let tt0_tick_per_service = (interfaces.config.tick_rate_hz/(tt0_fire_rate_hz * 2));
let tt0_tick_per_service = interfaces.config.tick_rate_hz/(tt0_fire_rate_hz * 2);
let tt0_service_data = TickServiceData::new(tt0_tick_per_service);
let mut tt0 = TickTimerService::new(tt0_service_data, true);
// tick timer 1
let tt1_fire_rate_hz = 3;
let tt1_tick_per_service = (interfaces.config.tick_rate_hz/(tt1_fire_rate_hz * 2));
let tt1_tick_per_service = interfaces.config.tick_rate_hz/(tt1_fire_rate_hz * 2);
let tt1_service_data = TickServiceData::new(tt1_tick_per_service);
let mut tt1 = TickTimerService::new(tt1_service_data, true);
// debounce timer
// let db_ticks = interfaces.config.tick_rate_hz / 100;
let db_ticks = interfaces.config.tick_rate_hz / 100;
let db_timer_data = TickServiceData::new(db_ticks);
let mut db_timer = TickTimerService::new(db_timer_data, false);
db_timer.reset();
// short press timer
let sp_ticks = 2 * interfaces.config.tick_rate_hz;
@ -179,49 +283,44 @@ fn main() -> ! {
lp_timer.reset();
let mut delay = Delay;
let tick_interval_us = 1000000/interfaces.config.tick_rate_hz;
interfaces.led0.set_amplitude(100);
interfaces.led1.set_amplitude(100);
let tick_interval_us = 1000000/interfaces.config.tick_rate_hz - 10;
// dac data
let coin_sound = include_bytes!("../audio/sweep_dpcm_u4.raw");
let button_sound = include_bytes!("../audio/sweep_dpcm_u4.raw");
let mut system_state = SystemState::DeepSleep;
interfaces.led0.set_amplitude(0);
interfaces.led1.set_amplitude(0);
interfaces.service();
unsafe {
use hal::pac::Interrupt;
qingke::pfic::enable_interrupt(Interrupt::EXTI7_0 as u8);
}
// MAIN APPLICATION
// process
// -depress big button (insert coin button) and it wakes up and turns on led one led at a fixed brightness
// -we will want one sound, the coin insert sound, to play when coin button is pressed. (This is when they insert a coin)
// -We will want a different sound or potentially multiple different sounds played in a rotating fashion when someone presses the button. Probably do some led blinking as well.(This is when they depress the big insert to play button)
// -depress the big button for approx 2s and it puts the led into low light mode. Just making it dimmer than usual.
// -depress the big button for 5s and it goes into deep sleep, everything off with the low sleep current draw
println!("begin");
loop {
// wait for button to be released if it's pressed
if (coin_button.is_low()) {
loop {
if coin_button.is_high() && !db_timer.is_enabled() {
db_timer.enable(true);
}
if db_timer.need_service() {
db_timer.reset();
if coin_button.is_high() {
break;
}
}
db_timer.tick();
delay.delay_us(tick_interval_us as u32);
}
}
// wait for button input
loop {
if coin_button.is_low() && !db_timer.is_enabled() {
db_timer.enable(true);
}
if db_timer.need_service() {
db_timer.reset();
if coin_button.is_low() {
break;
}
}
db_timer.tick();
delay.delay_us(tick_interval_us as u32);
}
match system_state {
SystemState::DeepSleep => {
// TODO: make this REALLY deep sleep
riscv::asm::wfi();
},
SystemState::Idle => {
let mut active = true;
tt0.enable(true);
tt1.enable(true);
loop {
if active {
},
SystemState::Active => {
tt0.tick();
tt1.tick();
@ -243,61 +342,102 @@ fn main() -> ! {
tt1.service()
}
}
interfaces.service();
},
}
// buttons
// SP
if coin_button.is_low() && !sp_timer.is_enabled() {
sp_timer.reset();
sp_timer.enable(true);
}
if sp_timer.need_service() {
sp_timer.reset();
if coin_button.is_low() {
active = false;
// TODO: fix polarity
interfaces.led0.set_amplitude(90);
interfaces.led1.set_amplitude(90);
{
// system input servicing
unsafe {
if INPUT_FLAGS.coin_flag {
println!("coin flag active");
INPUT_FLAGS.coin_flag = false;
coin_input.begin();
// enter the active state
system_state = SystemState::Active;
// todo: enter active
tt0.enable(true);
tt1.enable(true);
interfaces.dac.load_data(coin_sound);
}
if INPUT_FLAGS.button_flag {
println!("button flag active");
INPUT_FLAGS.button_flag = false;
button_input.begin();
}
}
if coin_button.is_high() && sp_timer.is_enabled() {
sp_timer.reset();
// debouncer
coin_input.service();
button_input.service();
if coin_input.ready() {
println!("debounced coin_input value: {}", coin_input.value());
coin_input.reset();
}
if button_input.ready() {
let value = button_input.value();
button_input.reset();
println!("debounced button_input value: {}", value);
if !value {
interfaces.dac.load_data(button_sound);
println!("reset hold timers + enable");
sp_timer.reset();
sp_timer.enable(true);
lp_timer.reset();
lp_timer.enable(true);
}
else {
sp_timer.reset();
lp_timer.reset();
}
}
// timers
sp_timer.tick();
// LP
if coin_button.is_low() && !lp_timer.is_enabled() {
lp_timer.reset();
lp_timer.enable(true);
}
if lp_timer.need_service() {
lp_timer.reset();
if coin_button.is_low() {
interfaces.led0.set_amplitude(100);
interfaces.led1.set_amplitude(100);
// break;
}
}
if coin_button.is_high() && lp_timer.is_enabled() {
lp_timer.reset();
}
lp_timer.tick();
interfaces.service();
delay.delay_us(tick_interval_us as u32);
if sp_timer.need_service() {
println!("sp detect!");
sp_timer.reset();
// todo enter idle
system_state = SystemState::Idle;
// TODO: fix polarity
interfaces.led0.set_amplitude(10);
interfaces.led1.set_amplitude(10);
interfaces.service();
}
if lp_timer.need_service() {
println!("lp detect!");
lp_timer.reset();
// todo enter deepsleep
system_state = SystemState::DeepSleep;
// TODO: fix polarity
interfaces.led0.set_amplitude(0);
interfaces.led1.set_amplitude(0);
interfaces.service();
}
}
delay.delay_us(tick_interval_us as u32);
}
// // DAC servicer setup
// let mut pwm_dac_interface = SimplePwmDacHandle{pin: core::cell::RefCell::new(pwm), ch: dac_ch};
// let mut dac = DpcmDac::new(pwm_dac_interface);
// let mut dac_active = true;
}
#[panic_handler]
fn panic(info: &core::panic::PanicInfo) -> ! {
fn panic(_info: &core::panic::PanicInfo) -> ! {
loop {}
}