reduce complexity of loopmode

This commit is contained in:
Jacob Rosenthal 2021-11-01 08:45:07 -07:00
parent 48673e27cd
commit 90be851e4b
3 changed files with 26 additions and 20 deletions

View File

@ -56,8 +56,8 @@ pub struct Pwm<'d, T: Instance> {
#[derive(Debug, Eq, PartialEq, Clone, Copy)] #[derive(Debug, Eq, PartialEq, Clone, Copy)]
pub enum LoopMode { pub enum LoopMode {
/// Repeat n additional times after the first /// Run sequence n Times total
Additional(u16), Times(u16),
/// Repeat until `stop` is called. /// Repeat until `stop` is called.
Infinite, Infinite,
} }
@ -74,12 +74,12 @@ pub struct LoopingConfig<'a> {
pub sequence: &'a [u16], pub sequence: &'a [u16],
/// How a sequence is read from RAM and is spread to the compare register /// How a sequence is read from RAM and is spread to the compare register
pub sequence_load: SequenceLoad, pub sequence_load: SequenceLoad,
/// Number of additional PWM periods to delay between each sequence sample /// Number of Times PWM periods to delay between each sequence sample
pub refresh: u32, pub refresh: u32,
/// Number of additional PWM periods after the sequence ends before starting the next sequence /// Number of Times PWM periods after the sequence ends before starting the next sequence
pub end_delay: u32, pub end_delay: u32,
/// How many times to repeat the sequence /// How many times to play the sequence
pub additional_loops: LoopMode, pub times: LoopMode,
} }
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, Copy, PartialEq, Eq)]
@ -88,6 +88,8 @@ pub struct LoopingConfig<'a> {
pub enum Error { pub enum Error {
/// Max Sequence size is 32767 /// Max Sequence size is 32767
SequenceTooLong, SequenceTooLong,
/// Min Sequence size is 1
SequenceTooShort,
/// EasyDMA can only read from data memory, read only buffers in flash will fail. /// EasyDMA can only read from data memory, read only buffers in flash will fail.
DMABufferNotInDataMemory, DMABufferNotInDataMemory,
} }
@ -177,6 +179,9 @@ impl<'d, T: Instance> Pwm<'d, T> {
if config.sequence.len() > 32767 { if config.sequence.len() > 32767 {
return Err(Error::SequenceTooLong); return Err(Error::SequenceTooLong);
} }
if let LoopMode::Times(0) = config.times {
return Err(Error::SequenceTooShort);
}
unborrow!(ch0, ch1, ch2, ch3); unborrow!(ch0, ch1, ch2, ch3);
@ -243,27 +248,28 @@ impl<'d, T: Instance> Pwm<'d, T> {
.enddelay .enddelay
.write(|w| unsafe { w.bits(config.end_delay) }); .write(|w| unsafe { w.bits(config.end_delay) });
match config.additional_loops { match config.times {
// just the one time, no loop count // just the one time, no loop count
LoopMode::Additional(0) => { LoopMode::Times(1) => {
r.loop_.write(|w| w.cnt().disabled()); r.loop_.write(|w| w.cnt().disabled());
// tasks_seqstart doesnt exist in all svds so write its bit instead // tasks_seqstart doesnt exist in all svds so write its bit instead
r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) }); r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) });
} }
// loop count is how many times to play BOTH sequences // loop count is how many times to play BOTH sequences
// the one time + 1 = 2 total, play the sequence once starting from seq0 // 2 total (1 x 2)
// the one time + 2 = 3 total, playing the sequence twice would be too much, but we can start on seq1 to subtract one // 3 total, (2 x 2) - 1
// the one time + 3 = 4 total, play the sequence twice starting from seq0 LoopMode::Times(n) => {
LoopMode::Additional(n) => { let odd = n & 1 == 1;
let times = (n / 2) + 1; let times = if odd { (n / 2) + 1 } else { n / 2 };
r.loop_.write(|w| unsafe { w.cnt().bits(times) }); r.loop_.write(|w| unsafe { w.cnt().bits(times) });
if n & 1 == 1 { if odd {
// tasks_seqstart doesnt exist in all svds so write its bit instead
r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) });
} else {
// tasks_seqstart doesnt exist in all svds so write its bit instead // tasks_seqstart doesnt exist in all svds so write its bit instead
r.tasks_seqstart[1].write(|w| unsafe { w.bits(0x01) }); r.tasks_seqstart[1].write(|w| unsafe { w.bits(0x01) });
} else {
// tasks_seqstart doesnt exist in all svds so write its bit instead
r.tasks_seqstart[0].write(|w| unsafe { w.bits(0x01) });
} }
} }
// to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again // to play infinitely, repeat the sequence one time, then have loops done self trigger seq0 again

View File

@ -24,7 +24,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
sequence_load: SequenceLoad::Individual, sequence_load: SequenceLoad::Individual,
refresh: 0, refresh: 0,
end_delay: 0, end_delay: 0,
additional_loops: LoopMode::Additional(5), times: LoopMode::Times(5),
}; };
let _pwm = unwrap!(Pwm::simple_playback( let _pwm = unwrap!(Pwm::simple_playback(

View File

@ -27,8 +27,8 @@ async fn main(_spawner: Spawner, p: Peripherals) {
sequence: &seq_values, sequence: &seq_values,
sequence_load: SequenceLoad::Common, sequence_load: SequenceLoad::Common,
refresh: 0, refresh: 0,
end_delay: 1, end_delay: 0,
additional_loops: LoopMode::Infinite, times: LoopMode::Infinite,
}; };
let pwm = unwrap!(Pwm::simple_playback( let pwm = unwrap!(Pwm::simple_playback(