aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf/src
diff options
context:
space:
mode:
authorhuntc <[email protected]>2022-01-29 15:26:31 +1100
committerhuntc <[email protected]>2022-01-29 18:01:06 +1100
commit482389a6911d8d3505872e6ad03d5b0af565eaf9 (patch)
treed23d5bb09378d223485e40073717b48ac3a398c2 /examples/nrf/src
parent9ac52a768bbcd4bc8b753c64805fc23906b2c91f (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/nrf/src')
-rw-r--r--examples/nrf/src/bin/pwm_sequence.rs22
-rw-r--r--examples/nrf/src/bin/pwm_sequence_ppi.rs13
-rw-r--r--examples/nrf/src/bin/pwm_sequence_ws2812b.rs33
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::*;
8use embassy::executor::Spawner; 8use embassy::executor::Spawner;
9use embassy::time::{Duration, Timer}; 9use embassy::time::{Duration, Timer};
10use embassy_nrf::gpio::NoPin; 10use embassy_nrf::gpio::NoPin;
11use embassy_nrf::pwm::{Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm}; 11use embassy_nrf::pwm::{
12 Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, EMPTY_SEQ,
13};
12use embassy_nrf::Peripherals; 14use embassy_nrf::Peripherals;
13 15
14#[embassy::main] 16#[embassy::main]
15async fn main(_spawner: Spawner, p: Peripherals) { 17async 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]
18async fn main(_spawner: Spawner, p: Peripherals) { 18async 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]
32async fn main(_spawner: Spawner, p: Peripherals) { 32async 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;