From 47aeab152fff59e64d8244475dfbec338e6f98e5 Mon Sep 17 00:00:00 2001 From: huntc Date: Tue, 25 Jan 2022 18:06:42 +1100 Subject: PWM WS2812B example and per sequence config Demonstrates how to set the colour of a WS2812B to blue using PWM, and the use of multiple sequences along with their own config. This required an API change. --- examples/nrf/src/bin/pwm_sequence.rs | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 56c865d1c..2dcbc7475 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -8,7 +8,7 @@ use defmt::*; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_nrf::gpio::NoPin; -use embassy_nrf::pwm::{Prescaler, SequenceConfig, SequenceMode, SequencePwm}; +use embassy_nrf::pwm::{Config, Prescaler, SequenceMode, SequencePwm}; use embassy_nrf::Peripherals; #[embassy::main] @@ -16,26 +16,39 @@ async fn main(_spawner: Spawner, p: Peripherals) { let seq_values_1: [u16; 5] = [1000, 250, 100, 50, 0]; let seq_values_2: [u16; 5] = [0, 50, 100, 250, 1000]; - let mut config = SequenceConfig::default(); + let mut config = Config::default(); config.prescaler = Prescaler::Div128; // 1 period is 1000 * (128/16mhz = 0.000008s = 0.008ms) = 8us // but say we want to hold the value for 5000ms // so we want to repeat our value as many times as necessary until 5000ms passes // want 5000/8 = 625 periods total to occur, so 624 (we get the one period for free remember) - config.refresh = 624; + let mut seq_config = Config::default(); + seq_config.refresh = 624; // thus our sequence takes 5 * 5000ms or 25 seconds let mut pwm = unwrap!(SequencePwm::new( p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let _ = pwm.start(&seq_values_1, SequenceMode::Infinite); + let _ = pwm.start( + &seq_values_1, + seq_config, + None, + None, + SeqSequenceMode::Infinite, + ); info!("pwm started!"); Timer::after(Duration::from_millis(20000)).await; info!("pwm starting with another sequence!"); - let _ = pwm.start(&seq_values_2, SequenceMode::Infinite); + let _ = pwm.start( + &seq_values_2, + seq_config, + None, + None, + SequenceMode::Infinite, + ); // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped -- cgit From 12ce02457438c1dd1566f3f3c43537ae4f54f699 Mon Sep 17 00:00:00 2001 From: huntc Date: Fri, 28 Jan 2022 13:38:20 +1100 Subject: Make the sequence a little nicer to pass around --- examples/nrf/src/bin/pwm_sequence.rs | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 2dcbc7475..78787d531 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -8,13 +8,13 @@ use defmt::*; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_nrf::gpio::NoPin; -use embassy_nrf::pwm::{Config, Prescaler, SequenceMode, SequencePwm}; +use embassy_nrf::pwm::{Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm}; use embassy_nrf::Peripherals; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { - let seq_values_1: [u16; 5] = [1000, 250, 100, 50, 0]; - let seq_values_2: [u16; 5] = [0, 50, 100, 250, 1000]; + let seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; + let seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; let mut config = Config::default(); config.prescaler = Prescaler::Div128; @@ -22,7 +22,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { // but say we want to hold the value for 5000ms // so we want to repeat our value as many times as necessary until 5000ms passes // want 5000/8 = 625 periods total to occur, so 624 (we get the one period for free remember) - let mut seq_config = Config::default(); + let mut seq_config = SequenceConfig::default(); seq_config.refresh = 624; // thus our sequence takes 5 * 5000ms or 25 seconds @@ -30,11 +30,9 @@ async fn main(_spawner: Spawner, p: Peripherals) { p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); let _ = pwm.start( - &seq_values_1, - seq_config, + Sequence::new(&seq_words_1, seq_config.clone()), None, - None, - SeqSequenceMode::Infinite, + SequenceMode::Infinite, ); info!("pwm started!"); @@ -43,9 +41,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { info!("pwm starting with another sequence!"); let _ = pwm.start( - &seq_values_2, - seq_config, - None, + Sequence::new(&seq_words_2, seq_config), None, SequenceMode::Infinite, ); -- cgit From 9ac52a768bbcd4bc8b753c64805fc23906b2c91f Mon Sep 17 00:00:00 2001 From: huntc Date: Fri, 28 Jan 2022 16:21:53 +1100 Subject: Now permits sequences to be mutated subsequently --- examples/nrf/src/bin/pwm_sequence.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 78787d531..6fb861e8f 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -13,8 +13,8 @@ use embassy_nrf::Peripherals; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { - let seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; - let seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; + let mut seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; + let mut seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; let mut config = Config::default(); config.prescaler = Prescaler::Div128; @@ -30,7 +30,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); let _ = pwm.start( - Sequence::new(&seq_words_1, seq_config.clone()), + Sequence::new(&mut seq_words_1, seq_config.clone()), None, SequenceMode::Infinite, ); @@ -41,7 +41,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { info!("pwm starting with another sequence!"); let _ = pwm.start( - Sequence::new(&seq_words_2, seq_config), + Sequence::new(&mut seq_words_2, seq_config), None, SequenceMode::Infinite, ); -- cgit From 482389a6911d8d3505872e6ad03d5b0af565eaf9 Mon Sep 17 00:00:00 2001 From: huntc Date: Sat, 29 Jan 2022 15:26:31 +1100 Subject: 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. --- examples/nrf/src/bin/pwm_sequence.rs | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') 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::*; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_nrf::gpio::NoPin; -use embassy_nrf::pwm::{Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm}; +use embassy_nrf::pwm::{ + Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, EMPTY_SEQ, +}; use embassy_nrf::Peripherals; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { - let mut seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; - let mut seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; - let mut config = Config::default(); config.prescaler = Prescaler::Div128; // 1 period is 1000 * (128/16mhz = 0.000008s = 0.008ms) = 8us @@ -26,25 +25,20 @@ async fn main(_spawner: Spawner, p: Peripherals) { seq_config.refresh = 624; // thus our sequence takes 5 * 5000ms or 25 seconds + let seq_1 = Sequence::new([1000, 250, 100, 50, 0], seq_config.clone()); + let seq_2 = Sequence::new([0, 50, 100, 250, 1000], seq_config); + let mut pwm = unwrap!(SequencePwm::new( p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let _ = pwm.start( - Sequence::new(&mut seq_words_1, seq_config.clone()), - None, - SequenceMode::Infinite, - ); + unwrap!(pwm.start(seq_1, EMPTY_SEQ, SequenceMode::Times(1))); info!("pwm started!"); Timer::after(Duration::from_millis(20000)).await; info!("pwm starting with another sequence!"); - let _ = pwm.start( - Sequence::new(&mut seq_words_2, seq_config), - None, - SequenceMode::Infinite, - ); + unwrap!(pwm.start(seq_2, EMPTY_SEQ, SequenceMode::Times(1))); // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped -- cgit From 1c67bd46433734d9280e976da33975cf5beb773e Mon Sep 17 00:00:00 2001 From: huntc Date: Sun, 30 Jan 2022 16:21:23 +1100 Subject: Revert "Own the sequence buffer" This reverts commit 482389a6911d8d3505872e6ad03d5b0af565eaf9. --- examples/nrf/src/bin/pwm_sequence.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 6fe957d24..6fb861e8f 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -8,13 +8,14 @@ use defmt::*; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_nrf::gpio::NoPin; -use embassy_nrf::pwm::{ - Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, EMPTY_SEQ, -}; +use embassy_nrf::pwm::{Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm}; use embassy_nrf::Peripherals; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { + let mut seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; + let mut seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; + let mut config = Config::default(); config.prescaler = Prescaler::Div128; // 1 period is 1000 * (128/16mhz = 0.000008s = 0.008ms) = 8us @@ -25,20 +26,25 @@ async fn main(_spawner: Spawner, p: Peripherals) { seq_config.refresh = 624; // thus our sequence takes 5 * 5000ms or 25 seconds - let seq_1 = Sequence::new([1000, 250, 100, 50, 0], seq_config.clone()); - let seq_2 = Sequence::new([0, 50, 100, 250, 1000], seq_config); - let mut pwm = unwrap!(SequencePwm::new( p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - unwrap!(pwm.start(seq_1, EMPTY_SEQ, SequenceMode::Times(1))); + let _ = pwm.start( + Sequence::new(&mut seq_words_1, seq_config.clone()), + None, + SequenceMode::Infinite, + ); info!("pwm started!"); Timer::after(Duration::from_millis(20000)).await; info!("pwm starting with another sequence!"); - unwrap!(pwm.start(seq_2, EMPTY_SEQ, SequenceMode::Times(1))); + let _ = pwm.start( + Sequence::new(&mut seq_words_2, seq_config), + None, + SequenceMode::Infinite, + ); // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped -- cgit From 986295998a3fa8c665364d7b4a5fc009d186dee9 Mon Sep 17 00:00:00 2001 From: huntc Date: Sun, 30 Jan 2022 16:26:09 +1100 Subject: Some more doco --- examples/nrf/src/bin/pwm_sequence.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 6fb861e8f..d3ddf558c 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -32,7 +32,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { let _ = pwm.start( Sequence::new(&mut seq_words_1, seq_config.clone()), None, - SequenceMode::Infinite, + SequenceMode::Times(1), ); info!("pwm started!"); @@ -43,7 +43,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { let _ = pwm.start( Sequence::new(&mut seq_words_2, seq_config), None, - SequenceMode::Infinite, + SequenceMode::Times(1), ); // we can abort a sequence if we need to before its complete with pwm.stop() -- cgit From 81f98c32aaec61171678ba6cbdd9c82860a1802f Mon Sep 17 00:00:00 2001 From: huntc Date: Fri, 4 Feb 2022 16:34:25 +1100 Subject: Update another example --- examples/nrf/src/bin/pwm_sequence.rs | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index d3ddf558c..b31c12a23 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -8,13 +8,15 @@ use defmt::*; use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_nrf::gpio::NoPin; -use embassy_nrf::pwm::{Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm}; +use embassy_nrf::pwm::{ + Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, Sequences, +}; use embassy_nrf::Peripherals; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { - let mut seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; - let mut seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; + let seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; + let seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; let mut config = Config::default(); config.prescaler = Prescaler::Div128; @@ -29,22 +31,21 @@ async fn main(_spawner: Spawner, p: Peripherals) { let mut pwm = unwrap!(SequencePwm::new( p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let _ = pwm.start( - Sequence::new(&mut seq_words_1, seq_config.clone()), - None, - SequenceMode::Times(1), - ); + + let sequence0 = Sequence::new(&seq_words_1, seq_config.clone()); + let sequences = Sequences::new(&mut pwm, sequence0, None); + unwrap!(sequences.start(SequenceMode::Times(1))); info!("pwm started!"); Timer::after(Duration::from_millis(20000)).await; info!("pwm starting with another sequence!"); - let _ = pwm.start( - Sequence::new(&mut seq_words_2, seq_config), - None, - SequenceMode::Times(1), - ); + drop(sequences); // This stops the previous sequence and returns pwm ownership back + + let sequence0 = Sequence::new(&seq_words_2, seq_config); + let sequences = Sequences::new(&mut pwm, sequence0, None); + unwrap!(sequences.start(SequenceMode::Times(1))); // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped -- cgit From 965a5f2c3fba365519bed1c2a955145783d6a05b Mon Sep 17 00:00:00 2001 From: huntc Date: Fri, 4 Feb 2022 19:11:15 +1100 Subject: Introduced the SingleSequencer and a more complex Sequencer --- examples/nrf/src/bin/pwm_sequence.rs | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index b31c12a23..761ac0f03 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -9,14 +9,13 @@ use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_nrf::gpio::NoPin; use embassy_nrf::pwm::{ - Config, Prescaler, Sequence, SequenceConfig, SequenceMode, SequencePwm, Sequences, + Config, Prescaler, Sequence, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer, }; use embassy_nrf::Peripherals; #[embassy::main] async fn main(_spawner: Spawner, p: Peripherals) { - let seq_words_1: [u16; 5] = [1000, 250, 100, 50, 0]; - let seq_words_2: [u16; 5] = [0, 50, 100, 250, 1000]; + let seq_words: [u16; 5] = [1000, 250, 100, 50, 0]; let mut config = Config::default(); config.prescaler = Prescaler::Div128; @@ -32,20 +31,9 @@ async fn main(_spawner: Spawner, p: Peripherals) { p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let sequence0 = Sequence::new(&seq_words_1, seq_config.clone()); - let sequences = Sequences::new(&mut pwm, sequence0, None); - unwrap!(sequences.start(SequenceMode::Times(1))); - - info!("pwm started!"); - - Timer::after(Duration::from_millis(20000)).await; - info!("pwm starting with another sequence!"); - - drop(sequences); // This stops the previous sequence and returns pwm ownership back - - let sequence0 = Sequence::new(&seq_words_2, seq_config); - let sequences = Sequences::new(&mut pwm, sequence0, None); - unwrap!(sequences.start(SequenceMode::Times(1))); + let sequence = Sequence::new(&seq_words, seq_config.clone()); + let sequencer = SingleSequencer::new(&mut pwm, sequence); + unwrap!(sequencer.start(SingleSequenceMode::Times(1))); // we can abort a sequence if we need to before its complete with pwm.stop() // or stop is also implicitly called when the pwm peripheral is dropped -- cgit From 81d31e43ebf947ff2cd91b3a6f6af092fcb7e2b7 Mon Sep 17 00:00:00 2001 From: huntc Date: Fri, 4 Feb 2022 19:18:10 +1100 Subject: Removed unrequired clone --- examples/nrf/src/bin/pwm_sequence.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index 761ac0f03..a76b1110b 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -31,7 +31,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let sequence = Sequence::new(&seq_words, seq_config.clone()); + let sequence = Sequence::new(&seq_words, seq_config); let sequencer = SingleSequencer::new(&mut pwm, sequence); unwrap!(sequencer.start(SingleSequenceMode::Times(1))); -- cgit From df5ba727f2c8bd3f2a67f51a3f43d7f47b011b1c Mon Sep 17 00:00:00 2001 From: huntc Date: Sat, 5 Feb 2022 08:05:23 +1100 Subject: Further API simplification for the single seq scenario --- examples/nrf/src/bin/pwm_sequence.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'examples/nrf/src/bin/pwm_sequence.rs') diff --git a/examples/nrf/src/bin/pwm_sequence.rs b/examples/nrf/src/bin/pwm_sequence.rs index a76b1110b..f06ea0b19 100644 --- a/examples/nrf/src/bin/pwm_sequence.rs +++ b/examples/nrf/src/bin/pwm_sequence.rs @@ -9,7 +9,7 @@ use embassy::executor::Spawner; use embassy::time::{Duration, Timer}; use embassy_nrf::gpio::NoPin; use embassy_nrf::pwm::{ - Config, Prescaler, Sequence, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer, + Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer, }; use embassy_nrf::Peripherals; @@ -31,8 +31,7 @@ async fn main(_spawner: Spawner, p: Peripherals) { p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config, )); - let sequence = Sequence::new(&seq_words, seq_config); - let sequencer = SingleSequencer::new(&mut pwm, sequence); + let sequencer = SingleSequencer::new(&mut pwm, &seq_words, seq_config); unwrap!(sequencer.start(SingleSequenceMode::Times(1))); // we can abort a sequence if we need to before its complete with pwm.stop() -- cgit