Sequences are now passed in via the start method to avoid having to stop the PWM and restart it. Sequences continue to be constrained with the same lifetime of the Pwm object itself. The pwm_sequence example has been extended to illustrate multiple sequences being passed around.
68 lines
2.2 KiB
Rust
68 lines
2.2 KiB
Rust
#![no_std]
|
|
#![no_main]
|
|
#![feature(type_alias_impl_trait)]
|
|
#![feature(array_from_fn)]
|
|
|
|
#[path = "../example_common.rs"]
|
|
mod example_common;
|
|
use core::future::pending;
|
|
use defmt::*;
|
|
use embassy::executor::Spawner;
|
|
use embassy_nrf::gpio::{Input, NoPin, Pull};
|
|
use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
|
|
use embassy_nrf::ppi::Ppi;
|
|
use embassy_nrf::pwm::{Prescaler, SequenceConfig, SequenceMode, SequencePwm};
|
|
use embassy_nrf::Peripherals;
|
|
|
|
#[embassy::main]
|
|
async fn main(_spawner: Spawner, p: Peripherals) {
|
|
let seq_values: [u16; 5] = [1000, 250, 100, 50, 0];
|
|
|
|
let mut config = SequenceConfig::default();
|
|
config.prescaler = Prescaler::Div128;
|
|
// 1 period is 1000 * (128/16mhz = 0.000008s = 0.008ms) = 8ms
|
|
// but say we want to hold the value for 250ms 250ms/8 = 31.25 periods
|
|
// so round to 31 - 1 (we get the one period for free remember)
|
|
// thus our sequence takes 5 * 250ms or 1.25 seconds
|
|
config.refresh = 30;
|
|
|
|
let pwm = unwrap!(SequencePwm::new(
|
|
p.PWM0, p.P0_13, NoPin, NoPin, NoPin, config,
|
|
));
|
|
|
|
let _ = pwm.start(&seq_values, SequenceMode::Times(1));
|
|
// pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work
|
|
// so its going to have to start running in order load the configuration
|
|
|
|
let button1 = InputChannel::new(
|
|
p.GPIOTE_CH0,
|
|
Input::new(p.P0_11, Pull::Up),
|
|
InputChannelPolarity::HiToLo,
|
|
);
|
|
|
|
let button2 = InputChannel::new(
|
|
p.GPIOTE_CH1,
|
|
Input::new(p.P0_12, Pull::Up),
|
|
InputChannelPolarity::HiToLo,
|
|
);
|
|
|
|
// messing with the pwm tasks is ill advised
|
|
// Times::Ininite and Times even are seq0, Times odd is seq1
|
|
let start = unsafe { pwm.task_start_seq0() };
|
|
let stop = unsafe { pwm.task_stop() };
|
|
|
|
let mut ppi = Ppi::new_one_to_one(p.PPI_CH1, button1.event_in(), start);
|
|
ppi.enable();
|
|
|
|
let mut ppi2 = Ppi::new_one_to_one(p.PPI_CH0, button2.event_in(), stop);
|
|
ppi2.enable();
|
|
|
|
info!("PPI setup!");
|
|
info!("Press button 1 to start LED 1");
|
|
info!("Press button 2 to stop LED 1");
|
|
info!("Note! task_stop stops the sequence, but not the pin output");
|
|
|
|
// Block forever so the above drivers don't get dropped
|
|
pending::<()>().await;
|
|
}
|