@@ -6,7 +6,7 @@ use core::sync::atomic::{Ordering, compiler_fence};
66
77use embassy_hal_internal:: { Peri , PeripheralType } ;
88
9- use crate :: gpio:: { AnyPin , DISCONNECTED , OutputDrive , Pin as GpioPin , PselBits , SealedPin as _, convert_drive} ;
9+ use crate :: gpio:: { AnyPin , DISCONNECTED , Level , OutputDrive , Pin as GpioPin , PselBits , SealedPin as _, convert_drive} ;
1010use crate :: pac:: gpio:: vals as gpiovals;
1111use crate :: pac:: pwm:: vals;
1212use crate :: ppi:: { Event , Task } ;
@@ -53,13 +53,11 @@ pub const PWM_CLK_HZ: u32 = 16_000_000;
5353
5454impl < ' d > SequencePwm < ' d > {
5555 /// Create a new 1-channel PWM
56- #[ allow( unused_unsafe) ]
5756 pub fn new_1ch < T : Instance > ( pwm : Peri < ' d , T > , ch0 : Peri < ' d , impl GpioPin > , config : Config ) -> Result < Self , Error > {
5857 Self :: new_inner ( pwm, Some ( ch0. into ( ) ) , None , None , None , config)
5958 }
6059
6160 /// Create a new 2-channel PWM
62- #[ allow( unused_unsafe) ]
6361 pub fn new_2ch < T : Instance > (
6462 pwm : Peri < ' d , T > ,
6563 ch0 : Peri < ' d , impl GpioPin > ,
@@ -70,7 +68,6 @@ impl<'d> SequencePwm<'d> {
7068 }
7169
7270 /// Create a new 3-channel PWM
73- #[ allow( unused_unsafe) ]
7471 pub fn new_3ch < T : Instance > (
7572 pwm : Peri < ' d , T > ,
7673 ch0 : Peri < ' d , impl GpioPin > ,
@@ -82,7 +79,6 @@ impl<'d> SequencePwm<'d> {
8279 }
8380
8481 /// Create a new 4-channel PWM
85- #[ allow( unused_unsafe) ]
8682 pub fn new_4ch < T : Instance > (
8783 pwm : Peri < ' d , T > ,
8884 ch0 : Peri < ' d , impl GpioPin > ,
@@ -111,44 +107,27 @@ impl<'d> SequencePwm<'d> {
111107 ) -> Result < Self , Error > {
112108 let r = T :: regs ( ) ;
113109
114- if let Some ( pin) = & ch0 {
115- pin. set_low ( ) ;
116- pin. conf ( ) . write ( |w| {
117- w. set_dir ( gpiovals:: Dir :: OUTPUT ) ;
118- w. set_input ( gpiovals:: Input :: DISCONNECT ) ;
119- convert_drive ( w, config. ch0_drive ) ;
120- } ) ;
121- }
122- if let Some ( pin) = & ch1 {
123- pin. set_low ( ) ;
124- pin. conf ( ) . write ( |w| {
125- w. set_dir ( gpiovals:: Dir :: OUTPUT ) ;
126- w. set_input ( gpiovals:: Input :: DISCONNECT ) ;
127- convert_drive ( w, config. ch1_drive ) ;
128- } ) ;
129- }
130- if let Some ( pin) = & ch2 {
131- pin. set_low ( ) ;
132- pin. conf ( ) . write ( |w| {
133- w. set_dir ( gpiovals:: Dir :: OUTPUT ) ;
134- w. set_input ( gpiovals:: Input :: DISCONNECT ) ;
135- convert_drive ( w, config. ch2_drive ) ;
136- } ) ;
137- }
138- if let Some ( pin) = & ch3 {
139- pin. set_low ( ) ;
140- pin. conf ( ) . write ( |w| {
141- w. set_dir ( gpiovals:: Dir :: OUTPUT ) ;
142- w. set_input ( gpiovals:: Input :: DISCONNECT ) ;
143- convert_drive ( w, config. ch3_drive ) ;
144- } ) ;
110+ let channels = [
111+ ( & ch0, config. ch0_drive , config. ch0_idle_level ) ,
112+ ( & ch1, config. ch1_drive , config. ch1_idle_level ) ,
113+ ( & ch2, config. ch2_drive , config. ch2_idle_level ) ,
114+ ( & ch3, config. ch3_drive , config. ch3_idle_level ) ,
115+ ] ;
116+ for ( i, ( pin, drive, idle_level) ) in channels. into_iter ( ) . enumerate ( ) {
117+ if let Some ( pin) = pin {
118+ match idle_level {
119+ Level :: Low => pin. set_low ( ) ,
120+ Level :: High => pin. set_high ( ) ,
121+ }
122+ pin. conf ( ) . write ( |w| {
123+ w. set_dir ( gpiovals:: Dir :: OUTPUT ) ;
124+ w. set_input ( gpiovals:: Input :: DISCONNECT ) ;
125+ convert_drive ( w, drive) ;
126+ } ) ;
127+ }
128+ r. psel ( ) . out ( i) . write_value ( pin. psel_bits ( ) ) ;
145129 }
146130
147- r. psel ( ) . out ( 0 ) . write_value ( ch0. psel_bits ( ) ) ;
148- r. psel ( ) . out ( 1 ) . write_value ( ch1. psel_bits ( ) ) ;
149- r. psel ( ) . out ( 2 ) . write_value ( ch2. psel_bits ( ) ) ;
150- r. psel ( ) . out ( 3 ) . write_value ( ch3. psel_bits ( ) ) ;
151-
152131 // Disable all interrupts
153132 r. intenclr ( ) . write ( |w| w. 0 = 0xFFFF_FFFF ) ;
154133 r. shorts ( ) . write ( |_| ( ) ) ;
@@ -173,13 +152,7 @@ impl<'d> SequencePwm<'d> {
173152 . write ( |w| w. set_prescaler ( vals:: Prescaler :: from_bits ( config. prescaler as u8 ) ) ) ;
174153 r. countertop ( ) . write ( |w| w. set_countertop ( config. max_duty ) ) ;
175154
176- Ok ( Self {
177- r : T :: regs ( ) ,
178- ch0,
179- ch1,
180- ch2,
181- ch3,
182- } )
155+ Ok ( Self { r, ch0, ch1, ch2, ch3 } )
183156 }
184157
185158 /// Returns reference to `Stopped` event endpoint for PPI.
@@ -309,11 +282,19 @@ pub struct Config {
309282 pub ch2_drive : OutputDrive ,
310283 /// Drive strength for the channel 3 line.
311284 pub ch3_drive : OutputDrive ,
285+ /// Output level for the channel 0 line when PWM if disabled.
286+ pub ch0_idle_level : Level ,
287+ /// Output level for the channel 1 line when PWM if disabled.
288+ pub ch1_idle_level : Level ,
289+ /// Output level for the channel 2 line when PWM if disabled.
290+ pub ch2_idle_level : Level ,
291+ /// Output level for the channel 3 line when PWM if disabled.
292+ pub ch3_idle_level : Level ,
312293}
313294
314295impl Default for Config {
315- fn default ( ) -> Config {
316- Config {
296+ fn default ( ) -> Self {
297+ Self {
317298 counter_mode : CounterMode :: Up ,
318299 max_duty : 1000 ,
319300 prescaler : Prescaler :: Div16 ,
@@ -322,6 +303,10 @@ impl Default for Config {
322303 ch1_drive : OutputDrive :: Standard ,
323304 ch2_drive : OutputDrive :: Standard ,
324305 ch3_drive : OutputDrive :: Standard ,
306+ ch0_idle_level : Level :: Low ,
307+ ch1_idle_level : Level :: Low ,
308+ ch2_idle_level : Level :: Low ,
309+ ch3_idle_level : Level :: Low ,
325310 }
326311 }
327312}
0 commit comments