diff options
| author | huntc <[email protected]> | 2022-01-29 15:26:31 +1100 |
|---|---|---|
| committer | huntc <[email protected]> | 2022-01-29 18:01:06 +1100 |
| commit | 482389a6911d8d3505872e6ad03d5b0af565eaf9 (patch) | |
| tree | d23d5bb09378d223485e40073717b48ac3a398c2 /examples | |
| parent | 9ac52a768bbcd4bc8b753c64805fc23906b2c91f (diff) | |
Own the sequence buffer
This approach owns the sequence buffers which, while introducing an extra move, it eliminates the need to guard the lifetime of the sequence buffer. Given ownership, the buffer will be retained until the PWM sequence task is stopped.
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/nrf/src/bin/pwm_sequence.rs | 22 | ||||
| -rw-r--r-- | examples/nrf/src/bin/pwm_sequence_ppi.rs | 13 | ||||
| -rw-r--r-- | examples/nrf/src/bin/pwm_sequence_ws2812b.rs | 33 |
3 files changed, 32 insertions, 36 deletions
diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 6fb861e8f..6fe957d24 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs | |||
| @@ -8,14 +8,13 @@ use defmt::*; | |||
| 8 | use embassy::executor::Spawner; | 8 | use embassy::executor::Spawner; |
| 9 | use embassy::time::{Duration, Timer}; | 9 | use embassy::time::{Duration, Timer}; |
| 10 | use embassy_nrf::gpio::NoPin; | 10 | use embassy_nrf::gpio::NoPin; |
| 11 | use embassy_nrf::pwm::{Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm}; | 11 | use embassy_nrf::pwm::{ |
| 12 | Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, EMPTY_SEQ, | ||
| 13 | }; | ||
| 12 | use embassy_nrf::Peripherals; | 14 | use embassy_nrf::Peripherals; |
| 13 | 15 | ||
| 14 | #[embassy::main] | 16 | #[embassy::main] |
| 15 | async fn main(_spawner: Spawner, p: Peripherals) { | 17 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 16 | let mut seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; | ||
| 17 | let mut seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; | ||
| 18 | |||
| 19 | let mut config = Config::default(); | 18 | let mut config = Config::default(); |
| 20 | config.prescaler = Prescaler::Div128; | 19 | config.prescaler = Prescaler::Div128; |
| 21 | // 1 period is 1000 * (128/16mhz = 0.000008s = 0.008ms) = 8us | 20 | // 1 period is 1000 * (128/16mhz = 0.000008s = 0.008ms) = 8us |
| @@ -26,25 +25,20 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 26 | seq_config.refresh = 624; | 25 | seq_config.refresh = 624; |
| 27 | // thus our sequence takes 5 * 5000ms or 25 seconds | 26 | // thus our sequence takes 5 * 5000ms or 25 seconds |
| 28 | 27 | ||
| 28 | let seq_1 = Sequence::new([1000, 250, 100, 50, 0], seq_config.clone()); | ||
| 29 | let seq_2 = Sequence::new([0, 50, 100, 250, 1000], seq_config); | ||
| 30 | |||
| 29 | let mut pwm = unwrap!(SequencePwm::new( | 31 | let mut pwm = unwrap!(SequencePwm::new( |
| 30 | p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, | 32 | p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, |
| 31 | )); | 33 | )); |
| 32 | let _ = pwm.start( | 34 | unwrap!(pwm.start(seq_1, EMPTY_SEQ, SequenceMode::Times(1))); |
| 33 | Sequence::new(&mut seq_words_1, seq_config.clone()), | ||
| 34 | None, | ||
| 35 | SequenceMode::Infinite, | ||
| 36 | ); | ||
| 37 | 35 | ||
| 38 | info!("pwm started!"); | 36 | info!("pwm started!"); |
| 39 | 37 | ||
| 40 | Timer::after(Duration::from_millis(20000)).await; | 38 | Timer::after(Duration::from_millis(20000)).await; |
| 41 | info!("pwm starting with another sequence!"); | 39 | info!("pwm starting with another sequence!"); |
| 42 | 40 | ||
| 43 | let _ = pwm.start( | 41 | unwrap!(pwm.start(seq_2, EMPTY_SEQ, SequenceMode::Times(1))); |
| 44 | Sequence::new(&mut seq_words_2, seq_config), | ||
| 45 | None, | ||
| 46 | SequenceMode::Infinite, | ||
| 47 | ); | ||
| 48 | 42 | ||
| 49 | // we can abort a sequence if we need to before its complete with pwm.stop() | 43 | // we can abort a sequence if we need to before its complete with pwm.stop() |
| 50 | // or stop is also implicitly called when the pwm peripheral is dropped | 44 | // or stop is also implicitly called when the pwm peripheral is dropped |
diff --git a/examples/nrf/src/bin/pwm_sequence_ppi.rs b/examples/nrf/src/bin/pwm_sequence_ppi.rs index f5d734bb1..4883222a8 100644 --- a/examples/nrf/src/bin/pwm_sequence_ppi.rs +++ b/examples/nrf/src/bin/pwm_sequence_ppi.rs | |||
| @@ -16,7 +16,7 @@ use embassy_nrf::Peripherals; | |||
| 16 | 16 | ||
| 17 | #[embassy::main] | 17 | #[embassy::main] |
| 18 | async fn main(_spawner: Spawner, p: Peripherals) { | 18 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 19 | let mut seq_words: [u16; 5] = [1000, 250, 100, 50, 0]; | 19 | let seq_words: [u16; 5] = [1000, 250, 100, 50, 0]; |
| 20 | 20 | ||
| 21 | let mut config = Config::default(); | 21 | let mut config = Config::default(); |
| 22 | config.prescaler = Prescaler::Div128; | 22 | config.prescaler = Prescaler::Div128; |
| @@ -31,11 +31,12 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 31 | p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, | 31 | p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, |
| 32 | )); | 32 | )); |
| 33 | 33 | ||
| 34 | let _ = pwm.start( | 34 | // If we loop in any way i.e. not Times(1), then we must provide |
| 35 | Sequence::new(&mut seq_words, seq_config), | 35 | // the PWM peripheral with two sequences. |
| 36 | None, | 36 | let seq_0 = Sequence::new(seq_words, seq_config); |
| 37 | SequenceMode::Infinite, | 37 | let seq_1 = seq_0.clone(); |
| 38 | ); | 38 | |
| 39 | unwrap!(pwm.start(seq_0, seq_1, SequenceMode::Infinite)); | ||
| 39 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work | 40 | // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work |
| 40 | // so its going to have to start running in order load the configuration | 41 | // so its going to have to start running in order load the configuration |
| 41 | 42 | ||
diff --git a/examples/nrf/src/bin/pwm_sequence_ws2812b.rs b/examples/nrf/src/bin/pwm_sequence_ws2812b.rs index 0ce79cbe0..8acb209cc 100644 --- a/examples/nrf/src/bin/pwm_sequence_ws2812b.rs +++ b/examples/nrf/src/bin/pwm_sequence_ws2812b.rs | |||
| @@ -30,19 +30,6 @@ const RES: u16 = 0x8000; | |||
| 30 | // line is assumed to be P1_05. | 30 | // line is assumed to be P1_05. |
| 31 | #[embassy::main] | 31 | #[embassy::main] |
| 32 | async fn main(_spawner: Spawner, p: Peripherals) { | 32 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 33 | // Declare the bits of 24 bits | ||
| 34 | let mut color_seq_words = [ | ||
| 35 | T0H, T0H, T0H, T0H, T0H, T0H, T0H, T0H, // G | ||
| 36 | T0H, T0H, T0H, T0H, T0H, T0H, T0H, T0H, // R | ||
| 37 | T1H, T1H, T1H, T1H, T1H, T1H, T1H, T1H, // B | ||
| 38 | ]; | ||
| 39 | let color_seq = Sequence::new(&mut color_seq_words, SequenceConfig::default()); | ||
| 40 | |||
| 41 | let mut reset_seq_words = [RES; 1]; | ||
| 42 | let mut reset_seq_config = SequenceConfig::default(); | ||
| 43 | reset_seq_config.end_delay = 799; // 50us (20 ticks * 40) - 1 tick because we've already got one RES; | ||
| 44 | let reset_seq = Sequence::new(&mut reset_seq_words, reset_seq_config); | ||
| 45 | |||
| 46 | let mut config = Config::default(); | 33 | let mut config = Config::default(); |
| 47 | config.sequence_load = SequenceLoad::Common; | 34 | config.sequence_load = SequenceLoad::Common; |
| 48 | config.prescaler = Prescaler::Div1; | 35 | config.prescaler = Prescaler::Div1; |
| @@ -51,7 +38,21 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 51 | p.PWM0, p.P1_05, NoPin, NoPin, NoPin, config, | 38 | p.PWM0, p.P1_05, NoPin, NoPin, NoPin, config, |
| 52 | )); | 39 | )); |
| 53 | 40 | ||
| 54 | unwrap!(pwm.start(color_seq, Some(reset_seq), SequenceMode::Times(2))); | 41 | // Declare the bits of 24 bits |
| 42 | let color_seq = Sequence::new( | ||
| 43 | [ | ||
| 44 | T0H, T0H, T0H, T0H, T0H, T0H, T0H, T0H, // G | ||
| 45 | T0H, T0H, T0H, T0H, T0H, T0H, T0H, T0H, // R | ||
| 46 | T1H, T1H, T1H, T1H, T1H, T1H, T1H, T1H, // B | ||
| 47 | ], | ||
| 48 | SequenceConfig::default(), | ||
| 49 | ); | ||
| 50 | |||
| 51 | let mut reset_seq_config = SequenceConfig::default(); | ||
| 52 | reset_seq_config.end_delay = 799; // 50us (20 ticks * 40) - 1 tick because we've already got one RES; | ||
| 53 | let reset_seq = Sequence::new([RES], reset_seq_config); | ||
| 54 | |||
| 55 | unwrap!(pwm.start(color_seq, reset_seq, SequenceMode::Times(2))); | ||
| 55 | 56 | ||
| 56 | Timer::after(Duration::from_millis(1000)).await; | 57 | Timer::after(Duration::from_millis(1000)).await; |
| 57 | 58 | ||
| @@ -59,9 +60,9 @@ async fn main(_spawner: Spawner, p: Peripherals) { | |||
| 59 | let mut bit_value = T0H; | 60 | let mut bit_value = T0H; |
| 60 | 61 | ||
| 61 | loop { | 62 | loop { |
| 62 | if let (Some(color_seq), Some(reset_seq)) = pwm.stop() { | 63 | if let (Some(mut color_seq), Some(reset_seq)) = pwm.stop() { |
| 63 | color_seq.words[color_bit] = bit_value; | 64 | color_seq.words[color_bit] = bit_value; |
| 64 | unwrap!(pwm.start(color_seq, Some(reset_seq), SequenceMode::Times(2))); | 65 | unwrap!(pwm.start(color_seq, reset_seq, SequenceMode::Times(2))); |
| 65 | } | 66 | } |
| 66 | 67 | ||
| 67 | Timer::after(Duration::from_millis(50)).await; | 68 | Timer::after(Duration::from_millis(50)).await; |
