Module rp2040_hal::pwm
source · Expand description
Pulse Width Modulation (PWM)
First you must create a Slices struct which contains all the pwm slices.
use rp2040_hal::{prelude::*, pwm::{InputHighRunning, Slices}};
let mut pac = rp2040_pac::Peripherals::take().unwrap();
// Init PWMs
let pwm_slices = Slices::new(pac.PWM, &mut pac.RESETS);
// Configure PWM4
let mut pwm = pwm_slices.pwm4;
pwm.set_ph_correct();
pwm.enable();
// Set to run when b channel is high
let pwm = pwm.into_mode::<InputHighRunning>();
Once you have the PWM slice struct, you can add individual pins:
use embedded_hal::PwmPin;
// Use B channel (which inputs from GPIO 25)
let mut channel_b = pwm.channel_b;
let channel_pin_b = channel_b.input_from(pins.gpio25);
// Use A channel (which outputs to GPIO 24)
let mut channel_a = pwm.channel_a;
let channel_pin_a = channel_a.output_to(pins.gpio24);
// Set duty cycle
channel_a.set_duty(0x00ff);
channel_a.get_duty();
channel_a.set_inverted(); // Invert the output
channel_a.clr_inverted(); // Don't invert the output
The following configuration options are also available:
pwm.set_ph_correct(); // Run in phase correct mode
pwm.clr_ph_correct(); // Don't run in phase correct mode
pwm.set_div_int(1u8); // To set integer part of clock divider
pwm.set_div_frac(0u8); // To set fractional part of clock divider
pwm.get_top(); // To get the TOP register
pwm.set_top(u16::MAX); // To set the TOP register
default_config() sets ph_correct to false, the clock divider to 1, does not invert the output, sets top to 65535, and resets the counter. min_config() leaves those registers in the state they were before it was called (Careful, this can lead to unexpected behavior) It’s recommended to only call min_config() after calling default_config() on a pin that shares a PWM block.
Re-exports
pub use dyn_slice::*;
Modules
Semi-internal enums mostly used in typelevel magic
Structs
A Channel from the Pwm subsystem.
Count once with each falling edge detected on the B pin
Count once with each rising edge detected on the B pin
Counter is free-running, and will count continuously whenever the slice is enabled
Count continuously when a high level is detected on the B pin
Stores the attached gpio pin.
Pwm slice
Enums
Channel A
Channel B
Slice ID representing slice 0
Slice ID representing slice 1
Slice ID representing slice 2
Slice ID representing slice 3
Slice ID representing slice 4
Slice ID representing slice 5
Slice ID representing slice 6
Slice ID representing slice 7
Traits
Used to pin traits to a specific channel (A or B)
Make sure we can’t free an GPIO pin while still keeping it attached to pwm
TODO: Maybe FunctionPWM should be private?
Type-level
enum
for slice IDsMode for slice
Marker trait for valid output pins
Marker trait for valid input pins (Channel B only)
Type-level marker for tracking which slice modes are valid for which slices
Type-level marker for tracking which slice modes are valid for which slices