Skip to content

Commit f7f6570

Browse files
committed
Add FlexPWM output masking APIs
1 parent 183e1a6 commit f7f6570

File tree

2 files changed

+70
-1
lines changed

2 files changed

+70
-1
lines changed

examples/hal_pwm.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#![no_main]
1010

1111
use imxrt_hal as hal;
12+
use imxrt_hal::flexpwm::OutputMasks;
1213
use imxrt_hal::pit::Channel;
1314

1415
const PIT_DELAY_MS: u32 = board::PIT_FREQUENCY / 1_000 * 250;
@@ -52,8 +53,16 @@ fn main() -> ! {
5253
pwm.set_run(board::pwm::SM.mask());
5354

5455
loop {
56+
pwm.set_output_masks(OutputMasks::empty());
57+
led.set();
58+
59+
while !pit.is_elapsed(Channel::Chan0) {}
60+
pit.clear_elapsed(Channel::Chan0);
61+
62+
pwm.set_output_masks(OutputMasks::all());
63+
led.clear();
64+
5565
while !pit.is_elapsed(Channel::Chan0) {}
5666
pit.clear_elapsed(Channel::Chan0);
57-
led.toggle();
5867
}
5968
}

src/common/flexpwm.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -443,6 +443,66 @@ impl Pwm {
443443
pub fn set_turn_off(&self, sm: SM, channel: Channel, compare: i16) {
444444
self.set_value(sm, turn_off(channel), compare);
445445
}
446+
447+
/// Read the output masks for the PWM module.
448+
pub fn output_masks(&self) -> OutputMasks {
449+
// Masks are four bits wide. They fit within a u8.
450+
let (pwm_a, pwm_b) = crate::ral::read_reg!(pwm, self.pwm, MASK, MASKA, MASKB);
451+
OutputMasks {
452+
pwm_a: Mask::from_bits_truncate(pwm_a as u8),
453+
pwm_b: Mask::from_bits_truncate(pwm_b as u8),
454+
}
455+
}
456+
457+
/// Set the output masks for the PWM module.
458+
///
459+
/// See [`OutputMasks`] to learn about output masking. The masking takes
460+
/// effect at the next reload opportunity. (Although some MCUs might support
461+
/// forced update, it's not standard across all MCUs, so it's not exported.)
462+
///
463+
/// This call performs a single write. It does not read the existing mask
464+
/// bits to maintain them. If you need to perform these incremental updates,
465+
/// use [`output_masks`](Self::output_masks) to understand the prior state.
466+
pub fn set_output_masks(&self, masks: OutputMasks) {
467+
crate::ral::write_reg!(pwm, self.pwm, MASK,
468+
MASKA: masks.pwm_a.bits() as u16,
469+
MASKB: masks.pwm_b.bits() as u16,
470+
);
471+
}
472+
}
473+
474+
/// The mask state of PWM outputs.
475+
///
476+
/// If a bit is high, the output is masked. Formally, it's diven to logic level 0
477+
/// in the IP block (before considering output polarity).
478+
#[derive(Clone, Copy, PartialEq, Eq)]
479+
#[non_exhaustive] // Leave option for pwm_x
480+
pub struct OutputMasks {
481+
/// The PWM A outputs of a given submodule.
482+
pub pwm_a: Mask,
483+
/// The PWM B outputs of a given submodule.
484+
pub pwm_b: Mask,
485+
}
486+
487+
impl OutputMasks {
488+
/// Returns a mask set with no outputs masked.
489+
///
490+
/// After construction (in a constant context), you're free to manipulate
491+
/// the mask bits.
492+
pub const fn empty() -> Self {
493+
Self {
494+
pwm_a: Mask::empty(),
495+
pwm_b: Mask::empty(),
496+
}
497+
}
498+
499+
/// Returns a mask set with all outputs masks.
500+
pub const fn all() -> Self {
501+
Self {
502+
pwm_a: Mask::all(),
503+
pwm_b: Mask::all(),
504+
}
505+
}
446506
}
447507

448508
#[inline(never)]

0 commit comments

Comments
 (0)