aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-nrf/CHANGELOG.md1
-rw-r--r--embassy-nrf/src/pwm.rs58
2 files changed, 54 insertions, 5 deletions
diff --git a/embassy-nrf/CHANGELOG.md b/embassy-nrf/CHANGELOG.md
index 773a1a108..6f07a8c6d 100644
--- a/embassy-nrf/CHANGELOG.md
+++ b/embassy-nrf/CHANGELOG.md
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
24- spi: Add support for configuring bit order for bus 24- spi: Add support for configuring bit order for bus
25- pwm: Expose `pwm::PWM_CLK_HZ` and add `is_enabled` method 25- pwm: Expose `pwm::PWM_CLK_HZ` and add `is_enabled` method
26- gpio: Drop GPIO Pin generics (API break) 26- gpio: Drop GPIO Pin generics (API break)
27- pwm: Allow specifying OutputDrive for PWM channels
27 28
28## 0.1.0 - 2024-01-12 29## 0.1.0 - 2024-01-12
29 30
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs
index 12057f7dd..8e8f166d7 100644
--- a/embassy-nrf/src/pwm.rs
+++ b/embassy-nrf/src/pwm.rs
@@ -6,7 +6,7 @@ use core::sync::atomic::{compiler_fence, Ordering};
6 6
7use embassy_hal_internal::{into_ref, PeripheralRef}; 7use embassy_hal_internal::{into_ref, PeripheralRef};
8 8
9use crate::gpio::{AnyPin, Pin as GpioPin, PselBits, SealedPin as _}; 9use crate::gpio::{convert_drive, AnyPin, OutputDrive, Pin as GpioPin, PselBits, SealedPin as _};
10use crate::ppi::{Event, Task}; 10use crate::ppi::{Event, Task};
11use crate::util::slice_in_ram_or; 11use crate::util::slice_in_ram_or;
12use crate::{interrupt, pac, Peripheral}; 12use crate::{interrupt, pac, Peripheral};
@@ -128,19 +128,23 @@ impl<'d, T: Instance> SequencePwm<'d, T> {
128 128
129 if let Some(pin) = &ch0 { 129 if let Some(pin) = &ch0 {
130 pin.set_low(); 130 pin.set_low();
131 pin.conf().write(|w| w.dir().output()); 131 pin.conf()
132 .write(|w| w.dir().output().drive().variant(convert_drive(config.ch0_drive)));
132 } 133 }
133 if let Some(pin) = &ch1 { 134 if let Some(pin) = &ch1 {
134 pin.set_low(); 135 pin.set_low();
135 pin.conf().write(|w| w.dir().output()); 136 pin.conf()
137 .write(|w| w.dir().output().drive().variant(convert_drive(config.ch1_drive)));
136 } 138 }
137 if let Some(pin) = &ch2 { 139 if let Some(pin) = &ch2 {
138 pin.set_low(); 140 pin.set_low();
139 pin.conf().write(|w| w.dir().output()); 141 pin.conf()
142 .write(|w| w.dir().output().drive().variant(convert_drive(config.ch2_drive)));
140 } 143 }
141 if let Some(pin) = &ch3 { 144 if let Some(pin) = &ch3 {
142 pin.set_low(); 145 pin.set_low();
143 pin.conf().write(|w| w.dir().output()); 146 pin.conf()
147 .write(|w| w.dir().output().drive().variant(convert_drive(config.ch3_drive)));
144 } 148 }
145 149
146 r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) }); 150 r.psel.out[0].write(|w| unsafe { w.bits(ch0.psel_bits()) });
@@ -319,6 +323,14 @@ pub struct Config {
319 pub prescaler: Prescaler, 323 pub prescaler: Prescaler,
320 /// How a sequence is read from RAM and is spread to the compare register 324 /// How a sequence is read from RAM and is spread to the compare register
321 pub sequence_load: SequenceLoad, 325 pub sequence_load: SequenceLoad,
326 /// Drive strength for the channel 0 line.
327 pub ch0_drive: OutputDrive,
328 /// Drive strength for the channel 1 line.
329 pub ch1_drive: OutputDrive,
330 /// Drive strength for the channel 2 line.
331 pub ch2_drive: OutputDrive,
332 /// Drive strength for the channel 3 line.
333 pub ch3_drive: OutputDrive,
322} 334}
323 335
324impl Default for Config { 336impl Default for Config {
@@ -328,6 +340,10 @@ impl Default for Config {
328 max_duty: 1000, 340 max_duty: 1000,
329 prescaler: Prescaler::Div16, 341 prescaler: Prescaler::Div16,
330 sequence_load: SequenceLoad::Common, 342 sequence_load: SequenceLoad::Common,
343 ch0_drive: OutputDrive::Standard,
344 ch1_drive: OutputDrive::Standard,
345 ch2_drive: OutputDrive::Standard,
346 ch3_drive: OutputDrive::Standard,
331 } 347 }
332 } 348 }
333} 349}
@@ -815,6 +831,38 @@ impl<'d, T: Instance> SimplePwm<'d, T> {
815 let max_duty = self.max_duty() as u32; 831 let max_duty = self.max_duty() as u32;
816 clk / max_duty 832 clk / max_duty
817 } 833 }
834
835 /// Sets the PWM-Channel0 output drive strength
836 #[inline(always)]
837 pub fn set_ch0_drive(&self, drive: OutputDrive) {
838 if let Some(pin) = &self.ch0 {
839 pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
840 }
841 }
842
843 /// Sets the PWM-Channel1 output drive strength
844 #[inline(always)]
845 pub fn set_ch1_drive(&self, drive: OutputDrive) {
846 if let Some(pin) = &self.ch1 {
847 pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
848 }
849 }
850
851 /// Sets the PWM-Channel2 output drive strength
852 #[inline(always)]
853 pub fn set_ch2_drive(&self, drive: OutputDrive) {
854 if let Some(pin) = &self.ch2 {
855 pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
856 }
857 }
858
859 /// Sets the PWM-Channel3 output drive strength
860 #[inline(always)]
861 pub fn set_ch3_drive(&self, drive: OutputDrive) {
862 if let Some(pin) = &self.ch3 {
863 pin.conf().modify(|_, w| w.drive().variant(convert_drive(drive)));
864 }
865 }
818} 866}
819 867
820impl<'a, T: Instance> Drop for SimplePwm<'a, T> { 868impl<'a, T: Instance> Drop for SimplePwm<'a, T> {