diff --git a/ch32v-insert-coin/src/insert_coin/insert_coin.rs b/ch32v-insert-coin/src/insert_coin/insert_coin.rs index b67200d..6487029 100644 --- a/ch32v-insert-coin/src/insert_coin/insert_coin.rs +++ b/ch32v-insert-coin/src/insert_coin/insert_coin.rs @@ -4,9 +4,15 @@ use ch32_hal::timer::simple_pwm::SimplePwm; use ch32_hal::timer::Channel; use ch32_hal::delay::Delay; -use crate::insert_coin::services::{DacService, LedService, Service, ServiceData}; +use crate::insert_coin::services::{DacService, LedService, TickService, TickServiceData}; +// static mut led0_index: usize = 0; +// static LED0: [u8; 8] = [0u8, 25u8, 50u8, 75u8, 100u8, 75u8, 50u8, 25u8]; + +// static mut LED1_INDEX: usize = 0; +// static LED1_DCS: [u8; 5] = [0u8, 25u8, 50u8, 75u8, 100u8]; + pub struct SimplePwmCore<'d, T: GeneralInstance16bit> { pwm: core::cell::RefCell>, } @@ -43,7 +49,7 @@ impl<'d, T: GeneralInstance16bit> SimplePwmCore<'d, T> { pub struct CoreConfig { - tick_rate_hz: usize, + pub tick_rate_hz: usize, } impl CoreConfig { pub fn new(tick_rate_hz: usize) -> Self { @@ -56,14 +62,15 @@ impl CoreConfig { #[derive(Default)] struct Core { tick: usize, + active: bool, } pub struct InsertCoin<'a, T: GeneralInstance16bit> { core: Core, - config: CoreConfig, + pub config: CoreConfig, pwm_core: SimplePwmCore<'a, T>, - led0: LedService, - led1: LedService, + pub led0: LedService, + pub led1: LedService, // led2: LedService, dac: DacService<'a>, @@ -77,20 +84,20 @@ 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 = ServiceData::new(led0_tick_per_service); + let led0_service_data = TickServiceData::new(led0_tick_per_service); let led0 = LedService::new(ch32_hal::timer::Channel::Ch3, led0_service_data); // 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 = ServiceData::new(led1_tick_per_service); + let led1_service_data = TickServiceData::new(led1_tick_per_service); let led1 = LedService::new(ch32_hal::timer::Channel::Ch1, led1_service_data); // DAC servicer setup let dac_sample_rate_hz = 16000; let dac_tick_per_service = (config.tick_rate_hz/(dac_sample_rate_hz)); - let dac_service_data = ServiceData::new(dac_tick_per_service); + 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); @@ -111,6 +118,34 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> { } } + /// takes self reference and runs + pub fn service(&mut self) { + + if self.is_active() { + self.led0.tick(); + self.led1.tick(); + self.dac.tick(); + + + if self.led0.need_service() { + self.pwm_core.write_amplitude(self.led0.channel, self.led0.amplitude); + self.led0.service(); + } + + if self.led1.need_service() { + self.pwm_core.write_amplitude(self.led1.channel, self.led1.amplitude); + 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); + } + } + + } + /// consumes self and runs pub fn run(mut self) -> ! { let mut delay = Delay; @@ -162,4 +197,12 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> { delay.delay_us(tick_interval_us as u32); } } + + pub fn is_active(&self) -> bool { + self.core.active + } + + pub fn set_active(&mut self, active: bool) { + self.core.active = active; + } } \ No newline at end of file diff --git a/ch32v-insert-coin/src/insert_coin/mod.rs b/ch32v-insert-coin/src/insert_coin/mod.rs index a4bc002..c97fd60 100644 --- a/ch32v-insert-coin/src/insert_coin/mod.rs +++ b/ch32v-insert-coin/src/insert_coin/mod.rs @@ -2,4 +2,7 @@ mod insert_coin; mod services; use services::LedService; +pub use services::TickTimerService; + +pub use services::{TickService, TickServiceData}; pub use insert_coin::{InsertCoin, CoreConfig, SimplePwmCore}; \ No newline at end of file diff --git a/ch32v-insert-coin/src/insert_coin/services/dac.rs b/ch32v-insert-coin/src/insert_coin/services/dac.rs index ec2ee85..22681de 100644 --- a/ch32v-insert-coin/src/insert_coin/services/dac.rs +++ b/ch32v-insert-coin/src/insert_coin/services/dac.rs @@ -1,18 +1,18 @@ -use crate::insert_coin::services::{ServiceData, Service}; +use crate::insert_coin::services::{TickServiceData, TickService}; use adpcm_pwm_dac::{dac::{DpcmDac, DpcmDecoder}, interface::DacInterface}; use ch32_hal::timer::Channel; pub struct DacService<'a> { - service_data: core::cell::RefCell, + service_data: core::cell::RefCell, dpcm_decoder: core::cell::RefCell>, amplitude: core::cell::RefCell, pub channel: Channel, } impl<'a> DacService<'a> { - pub fn new(channel: Channel, service_data: ServiceData) -> Self { + pub fn new(channel: Channel, service_data: TickServiceData) -> Self { Self { service_data: core::cell::RefCell::new(service_data), dpcm_decoder: core::cell::RefCell::new(DpcmDecoder::new()), @@ -33,7 +33,7 @@ impl<'a> DacService<'a> { } } -impl<'a> Service for DacService<'a> { +impl<'a> TickService for DacService<'a> { fn tick(&self) { let mut tc = self.service_data.borrow_mut(); tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1); diff --git a/ch32v-insert-coin/src/insert_coin/services/led.rs b/ch32v-insert-coin/src/insert_coin/services/led.rs index f63934b..b11e9d8 100644 --- a/ch32v-insert-coin/src/insert_coin/services/led.rs +++ b/ch32v-insert-coin/src/insert_coin/services/led.rs @@ -1,15 +1,15 @@ use ch32_hal::timer::Channel; -use crate::insert_coin::services::{ServiceData, Service}; +use crate::insert_coin::services::{TickServiceData, TickService}; pub struct LedService { - service_data: core::cell::RefCell, + service_data: core::cell::RefCell, pub channel: Channel, pub amplitude: u8, } impl LedService { - pub fn new(channel: Channel, service_data: ServiceData) -> Self { + pub fn new(channel: Channel, service_data: TickServiceData) -> Self { Self { service_data: core::cell::RefCell::new(service_data), channel, @@ -23,7 +23,7 @@ impl LedService { } -impl Service for LedService { +impl TickService for LedService { fn tick(&self) { let mut tc = self.service_data.borrow_mut(); tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1); diff --git a/ch32v-insert-coin/src/insert_coin/services/mod.rs b/ch32v-insert-coin/src/insert_coin/services/mod.rs index ba70192..730c651 100644 --- a/ch32v-insert-coin/src/insert_coin/services/mod.rs +++ b/ch32v-insert-coin/src/insert_coin/services/mod.rs @@ -1,8 +1,11 @@ mod services; -pub use services::{Service, ServiceData}; +pub use services::{TickService, TickServiceData}; mod led; pub use led::LedService; mod dac; -pub use dac::DacService; \ No newline at end of file +pub use dac::DacService; + +mod tick_timer; +pub use tick_timer::TickTimerService; \ No newline at end of file diff --git a/ch32v-insert-coin/src/insert_coin/services/services.rs b/ch32v-insert-coin/src/insert_coin/services/services.rs index 002edca..45e0ac0 100644 --- a/ch32v-insert-coin/src/insert_coin/services/services.rs +++ b/ch32v-insert-coin/src/insert_coin/services/services.rs @@ -1,9 +1,9 @@ -pub struct ServiceData { +pub struct TickServiceData { pub ticks_per_service: usize, pub ticks_remaining: usize, } -impl ServiceData { +impl TickServiceData { pub fn new(ticks_per_service: usize) -> Self { Self { ticks_per_service, @@ -12,7 +12,7 @@ impl ServiceData { } } -pub trait Service { +pub trait TickService { /// indicate to the service that a tick has occurred fn tick(&self); diff --git a/ch32v-insert-coin/src/insert_coin/services/tick_timer.rs b/ch32v-insert-coin/src/insert_coin/services/tick_timer.rs new file mode 100644 index 0000000..c740c6b --- /dev/null +++ b/ch32v-insert-coin/src/insert_coin/services/tick_timer.rs @@ -0,0 +1,34 @@ +use ch32_hal::timer::Channel; + +use crate::insert_coin::services::{TickServiceData, TickService}; + +pub struct TickTimerService { + service_data: core::cell::RefCell, +} + +impl TickTimerService { + pub fn new(service_data: TickServiceData) -> Self { + Self { + service_data: core::cell::RefCell::new(service_data), + } + } +} + + +impl TickService for TickTimerService { + fn tick(&self) { + let mut tc = self.service_data.borrow_mut(); + tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1); + } + + fn need_service(&self) -> bool { + self.service_data.borrow().ticks_remaining == 0 + } + + fn service(&self) { + let mut tc = self.service_data.borrow_mut(); + tc.ticks_remaining = tc.ticks_per_service; + } +} + + diff --git a/ch32v-insert-coin/src/main.rs b/ch32v-insert-coin/src/main.rs index a2131af..aaab104 100644 --- a/ch32v-insert-coin/src/main.rs +++ b/ch32v-insert-coin/src/main.rs @@ -84,14 +84,18 @@ static mut IRQ1_FLAG: bool = false; // } // } +// TODO: remove +use insert_coin::{TickService, TickServiceData}; +use insert_coin::TickTimerService; + #[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); - // button 1 setup - // let b1 = Input::new(p.PA2, Pull::Up); + // coin button input setup + let b1 = Input::new(p.PD4, Pull::Up); // p.EXTI4 // let ei = hal::exti::ExtiInput::new(p.PD4, p.EXTI4, Pull::Up); @@ -133,12 +137,62 @@ fn main() -> ! { let pwm_core = SimplePwmCore::new(pwm); - let app = InsertCoin::new(config, pwm_core); - + let mut interfaces = InsertCoin::new(config, pwm_core); + interfaces.set_active(true); // insert_coin.init(); - - app.run(); + 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]; + + // 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_service_data = TickServiceData::new(tt0_tick_per_service); + let tt0 = TickTimerService::new(tt0_service_data); + + // 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_service_data = TickServiceData::new(tt1_tick_per_service); + let tt1 = TickTimerService::new(tt1_service_data); + + + let mut delay = Delay; + let tick_interval_us = 1000000/interfaces.config.tick_rate_hz; + + loop { + + tt0.tick(); + tt1.tick(); + // TODO: timer + // if app.led0.need_service() { + if tt0.need_service() { + interfaces.led0.set_amplitude(led0_dcs[led0_index]); + led0_index += 1; + if led0_index > led0_dcs.len() - 1 { + led0_index = 0; + } + tt0.service(); + } + // } + + // if app.led1.need_service() { + if tt1.need_service() { + interfaces.led1.set_amplitude(led1_dcs[led1_index]); + led1_index += 1; + if led1_index > led1_dcs.len() - 1 { + led1_index = 0; + } + tt1.service() + } + + 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);