add tick timer and re-factor for app vs interface
This commit is contained in:
parent
51af5c3343
commit
1a714bd907
8 changed files with 164 additions and 27 deletions
|
|
@ -4,9 +4,15 @@ use ch32_hal::timer::simple_pwm::SimplePwm;
|
||||||
use ch32_hal::timer::Channel;
|
use ch32_hal::timer::Channel;
|
||||||
use ch32_hal::delay::Delay;
|
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> {
|
pub struct SimplePwmCore<'d, T: GeneralInstance16bit> {
|
||||||
pwm: core::cell::RefCell<SimplePwm<'d, T>>,
|
pwm: core::cell::RefCell<SimplePwm<'d, T>>,
|
||||||
}
|
}
|
||||||
|
|
@ -43,7 +49,7 @@ impl<'d, T: GeneralInstance16bit> SimplePwmCore<'d, T> {
|
||||||
|
|
||||||
|
|
||||||
pub struct CoreConfig {
|
pub struct CoreConfig {
|
||||||
tick_rate_hz: usize,
|
pub tick_rate_hz: usize,
|
||||||
}
|
}
|
||||||
impl CoreConfig {
|
impl CoreConfig {
|
||||||
pub fn new(tick_rate_hz: usize) -> Self {
|
pub fn new(tick_rate_hz: usize) -> Self {
|
||||||
|
|
@ -56,14 +62,15 @@ impl CoreConfig {
|
||||||
#[derive(Default)]
|
#[derive(Default)]
|
||||||
struct Core {
|
struct Core {
|
||||||
tick: usize,
|
tick: usize,
|
||||||
|
active: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InsertCoin<'a, T: GeneralInstance16bit> {
|
pub struct InsertCoin<'a, T: GeneralInstance16bit> {
|
||||||
core: Core,
|
core: Core,
|
||||||
config: CoreConfig,
|
pub config: CoreConfig,
|
||||||
pwm_core: SimplePwmCore<'a, T>,
|
pwm_core: SimplePwmCore<'a, T>,
|
||||||
led0: LedService,
|
pub led0: LedService,
|
||||||
led1: LedService,
|
pub led1: LedService,
|
||||||
// led2: LedService,
|
// led2: LedService,
|
||||||
|
|
||||||
dac: DacService<'a>,
|
dac: DacService<'a>,
|
||||||
|
|
@ -77,20 +84,20 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> {
|
||||||
// LED0 servicer setup
|
// LED0 servicer setup
|
||||||
let led0_blink_rate_hz = 9;
|
let led0_blink_rate_hz = 9;
|
||||||
let led0_tick_per_service = (config.tick_rate_hz/(led0_blink_rate_hz * 2));
|
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);
|
let led0 = LedService::new(ch32_hal::timer::Channel::Ch3, led0_service_data);
|
||||||
|
|
||||||
// LED1 servicer setup
|
// LED1 servicer setup
|
||||||
let led1_blink_rate_hz = 3;
|
let led1_blink_rate_hz = 3;
|
||||||
let led1_tick_per_service = (config.tick_rate_hz/(led1_blink_rate_hz * 2));
|
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);
|
let led1 = LedService::new(ch32_hal::timer::Channel::Ch1, led1_service_data);
|
||||||
|
|
||||||
|
|
||||||
// DAC servicer setup
|
// DAC servicer setup
|
||||||
let dac_sample_rate_hz = 16000;
|
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 = 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 dac = DacService::new(ch32_hal::timer::Channel::Ch4, dac_service_data);
|
||||||
let data = include_bytes!("../../../../dpcm-encoder-decoder/sweep_dpcm_u4.raw");
|
let data = include_bytes!("../../../../dpcm-encoder-decoder/sweep_dpcm_u4.raw");
|
||||||
dac.load_data(data);
|
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
|
/// consumes self and runs
|
||||||
pub fn run(mut self) -> ! {
|
pub fn run(mut self) -> ! {
|
||||||
let mut delay = Delay;
|
let mut delay = Delay;
|
||||||
|
|
@ -162,4 +197,12 @@ impl<'a, T: GeneralInstance16bit> InsertCoin<'a, T> {
|
||||||
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
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn set_active(&mut self, active: bool) {
|
||||||
|
self.core.active = active;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2,4 +2,7 @@ mod insert_coin;
|
||||||
mod services;
|
mod services;
|
||||||
use services::LedService;
|
use services::LedService;
|
||||||
|
|
||||||
|
pub use services::TickTimerService;
|
||||||
|
|
||||||
|
pub use services::{TickService, TickServiceData};
|
||||||
pub use insert_coin::{InsertCoin, CoreConfig, SimplePwmCore};
|
pub use insert_coin::{InsertCoin, CoreConfig, SimplePwmCore};
|
||||||
|
|
@ -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 adpcm_pwm_dac::{dac::{DpcmDac, DpcmDecoder}, interface::DacInterface};
|
||||||
use ch32_hal::timer::Channel;
|
use ch32_hal::timer::Channel;
|
||||||
|
|
||||||
pub struct DacService<'a> {
|
pub struct DacService<'a> {
|
||||||
service_data: core::cell::RefCell<ServiceData>,
|
service_data: core::cell::RefCell<TickServiceData>,
|
||||||
dpcm_decoder: core::cell::RefCell<DpcmDecoder<'a>>,
|
dpcm_decoder: core::cell::RefCell<DpcmDecoder<'a>>,
|
||||||
amplitude: core::cell::RefCell<usize>,
|
amplitude: core::cell::RefCell<usize>,
|
||||||
pub channel: Channel,
|
pub channel: Channel,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> DacService<'a> {
|
impl<'a> DacService<'a> {
|
||||||
pub fn new(channel: Channel, service_data: ServiceData) -> Self {
|
pub fn new(channel: Channel, service_data: TickServiceData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service_data: core::cell::RefCell::new(service_data),
|
service_data: core::cell::RefCell::new(service_data),
|
||||||
dpcm_decoder: core::cell::RefCell::new(DpcmDecoder::new()),
|
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) {
|
fn tick(&self) {
|
||||||
let mut tc = self.service_data.borrow_mut();
|
let mut tc = self.service_data.borrow_mut();
|
||||||
tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1);
|
tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1);
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
use ch32_hal::timer::Channel;
|
use ch32_hal::timer::Channel;
|
||||||
|
|
||||||
use crate::insert_coin::services::{ServiceData, Service};
|
use crate::insert_coin::services::{TickServiceData, TickService};
|
||||||
|
|
||||||
pub struct LedService {
|
pub struct LedService {
|
||||||
service_data: core::cell::RefCell<ServiceData>,
|
service_data: core::cell::RefCell<TickServiceData>,
|
||||||
pub channel: Channel,
|
pub channel: Channel,
|
||||||
pub amplitude: u8,
|
pub amplitude: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LedService {
|
impl LedService {
|
||||||
pub fn new(channel: Channel, service_data: ServiceData) -> Self {
|
pub fn new(channel: Channel, service_data: TickServiceData) -> Self {
|
||||||
Self {
|
Self {
|
||||||
service_data: core::cell::RefCell::new(service_data),
|
service_data: core::cell::RefCell::new(service_data),
|
||||||
channel,
|
channel,
|
||||||
|
|
@ -23,7 +23,7 @@ impl LedService {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl Service for LedService {
|
impl TickService for LedService {
|
||||||
fn tick(&self) {
|
fn tick(&self) {
|
||||||
let mut tc = self.service_data.borrow_mut();
|
let mut tc = self.service_data.borrow_mut();
|
||||||
tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1);
|
tc.ticks_remaining = tc.ticks_remaining.saturating_sub(1);
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
mod services;
|
mod services;
|
||||||
pub use services::{Service, ServiceData};
|
pub use services::{TickService, TickServiceData};
|
||||||
|
|
||||||
mod led;
|
mod led;
|
||||||
pub use led::LedService;
|
pub use led::LedService;
|
||||||
|
|
||||||
mod dac;
|
mod dac;
|
||||||
pub use dac::DacService;
|
pub use dac::DacService;
|
||||||
|
|
||||||
|
mod tick_timer;
|
||||||
|
pub use tick_timer::TickTimerService;
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
pub struct ServiceData {
|
pub struct TickServiceData {
|
||||||
pub ticks_per_service: usize,
|
pub ticks_per_service: usize,
|
||||||
pub ticks_remaining: usize,
|
pub ticks_remaining: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServiceData {
|
impl TickServiceData {
|
||||||
pub fn new(ticks_per_service: usize) -> Self {
|
pub fn new(ticks_per_service: usize) -> Self {
|
||||||
Self {
|
Self {
|
||||||
ticks_per_service,
|
ticks_per_service,
|
||||||
|
|
@ -12,7 +12,7 @@ impl ServiceData {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Service {
|
pub trait TickService {
|
||||||
/// indicate to the service that a tick has occurred
|
/// indicate to the service that a tick has occurred
|
||||||
fn tick(&self);
|
fn tick(&self);
|
||||||
|
|
||||||
|
|
|
||||||
34
ch32v-insert-coin/src/insert_coin/services/tick_timer.rs
Normal file
34
ch32v-insert-coin/src/insert_coin/services/tick_timer.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
use ch32_hal::timer::Channel;
|
||||||
|
|
||||||
|
use crate::insert_coin::services::{TickServiceData, TickService};
|
||||||
|
|
||||||
|
pub struct TickTimerService {
|
||||||
|
service_data: core::cell::RefCell<TickServiceData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -84,14 +84,18 @@ static mut IRQ1_FLAG: bool = false;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// TODO: remove
|
||||||
|
use insert_coin::{TickService, TickServiceData};
|
||||||
|
use insert_coin::TickTimerService;
|
||||||
|
|
||||||
#[qingke_rt::entry]
|
#[qingke_rt::entry]
|
||||||
fn main() -> ! {
|
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_HSE;
|
||||||
let p = hal::init(config);
|
let p = hal::init(config);
|
||||||
|
|
||||||
// button 1 setup
|
// coin button input setup
|
||||||
// let b1 = Input::new(p.PA2, Pull::Up);
|
let b1 = Input::new(p.PD4, Pull::Up);
|
||||||
|
|
||||||
// p.EXTI4
|
// p.EXTI4
|
||||||
// let ei = hal::exti::ExtiInput::new(p.PD4, p.EXTI4, Pull::Up);
|
// 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 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();
|
// 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
|
// // DAC servicer setup
|
||||||
// let mut pwm_dac_interface = SimplePwmDacHandle{pin: core::cell::RefCell::new(pwm), ch: dac_ch};
|
// 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 = DpcmDac::new(pwm_dac_interface);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue