diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-05-21 21:48:21 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-05-21 21:48:21 +0000 |
| commit | 9a4c4fe2c770b6881e0b93ff6d618b1fdf377a66 (patch) | |
| tree | 170749acb73c7ababe3f5aa8a53005490c040dc7 | |
| parent | ba7ef3c91984b1b7bbbc65a3b86162be6304ba98 (diff) | |
| parent | e55f31bdc6882b6a6ac78a59aabf42ff9433f48d (diff) | |
Merge pull request #2781 from ismet55555/pwm-change
Remove Generics from `embassy-rp` `Pwm` struct
| -rw-r--r-- | embassy-rp/src/pwm.rs | 107 | ||||
| -rw-r--r-- | examples/rp/src/bin/interrupt.rs | 3 |
2 files changed, 59 insertions, 51 deletions
diff --git a/embassy-rp/src/pwm.rs b/embassy-rp/src/pwm.rs index a1f400cfb..20b5c4d58 100644 --- a/embassy-rp/src/pwm.rs +++ b/embassy-rp/src/pwm.rs | |||
| @@ -81,24 +81,22 @@ impl From<InputMode> for Divmode { | |||
| 81 | } | 81 | } |
| 82 | 82 | ||
| 83 | /// PWM driver. | 83 | /// PWM driver. |
| 84 | pub struct Pwm<'d, T: Slice> { | 84 | pub struct Pwm<'d> { |
| 85 | inner: PeripheralRef<'d, T>, | ||
| 86 | pin_a: Option<PeripheralRef<'d, AnyPin>>, | 85 | pin_a: Option<PeripheralRef<'d, AnyPin>>, |
| 87 | pin_b: Option<PeripheralRef<'d, AnyPin>>, | 86 | pin_b: Option<PeripheralRef<'d, AnyPin>>, |
| 87 | slice: usize, | ||
| 88 | } | 88 | } |
| 89 | 89 | ||
| 90 | impl<'d, T: Slice> Pwm<'d, T> { | 90 | impl<'d> Pwm<'d> { |
| 91 | fn new_inner( | 91 | fn new_inner( |
| 92 | inner: impl Peripheral<P = T> + 'd, | 92 | slice: usize, |
| 93 | a: Option<PeripheralRef<'d, AnyPin>>, | 93 | a: Option<PeripheralRef<'d, AnyPin>>, |
| 94 | b: Option<PeripheralRef<'d, AnyPin>>, | 94 | b: Option<PeripheralRef<'d, AnyPin>>, |
| 95 | b_pull: Pull, | 95 | b_pull: Pull, |
| 96 | config: Config, | 96 | config: Config, |
| 97 | divmode: Divmode, | 97 | divmode: Divmode, |
| 98 | ) -> Self { | 98 | ) -> Self { |
| 99 | into_ref!(inner); | 99 | let p = pac::PWM.ch(slice); |
| 100 | |||
| 101 | let p = inner.regs(); | ||
| 102 | p.csr().modify(|w| { | 100 | p.csr().modify(|w| { |
| 103 | w.set_divmode(divmode); | 101 | w.set_divmode(divmode); |
| 104 | w.set_en(false); | 102 | w.set_en(false); |
| @@ -117,51 +115,67 @@ impl<'d, T: Slice> Pwm<'d, T> { | |||
| 117 | }); | 115 | }); |
| 118 | } | 116 | } |
| 119 | Self { | 117 | Self { |
| 120 | inner, | 118 | // inner: p.into(), |
| 121 | pin_a: a, | 119 | pin_a: a, |
| 122 | pin_b: b, | 120 | pin_b: b, |
| 121 | slice, | ||
| 123 | } | 122 | } |
| 124 | } | 123 | } |
| 125 | 124 | ||
| 126 | /// Create PWM driver without any configured pins. | 125 | /// Create PWM driver without any configured pins. |
| 127 | #[inline] | 126 | #[inline] |
| 128 | pub fn new_free(inner: impl Peripheral<P = T> + 'd, config: Config) -> Self { | 127 | pub fn new_free<T: Slice>(slice: impl Peripheral<P = T> + 'd, config: Config) -> Self { |
| 129 | Self::new_inner(inner, None, None, Pull::None, config, Divmode::DIV) | 128 | into_ref!(slice); |
| 129 | Self::new_inner(slice.number(), None, None, Pull::None, config, Divmode::DIV) | ||
| 130 | } | 130 | } |
| 131 | 131 | ||
| 132 | /// Create PWM driver with a single 'a' as output. | 132 | /// Create PWM driver with a single 'a' as output. |
| 133 | #[inline] | 133 | #[inline] |
| 134 | pub fn new_output_a( | 134 | pub fn new_output_a<T: Slice>( |
| 135 | inner: impl Peripheral<P = T> + 'd, | 135 | slice: impl Peripheral<P = T> + 'd, |
| 136 | a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, | 136 | a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, |
| 137 | config: Config, | 137 | config: Config, |
| 138 | ) -> Self { | 138 | ) -> Self { |
| 139 | into_ref!(a); | 139 | into_ref!(slice, a); |
| 140 | Self::new_inner(inner, Some(a.map_into()), None, Pull::None, config, Divmode::DIV) | 140 | Self::new_inner( |
| 141 | slice.number(), | ||
| 142 | Some(a.map_into()), | ||
| 143 | None, | ||
| 144 | Pull::None, | ||
| 145 | config, | ||
| 146 | Divmode::DIV, | ||
| 147 | ) | ||
| 141 | } | 148 | } |
| 142 | 149 | ||
| 143 | /// Create PWM driver with a single 'b' pin as output. | 150 | /// Create PWM driver with a single 'b' pin as output. |
| 144 | #[inline] | 151 | #[inline] |
| 145 | pub fn new_output_b( | 152 | pub fn new_output_b<T: Slice>( |
| 146 | inner: impl Peripheral<P = T> + 'd, | 153 | slice: impl Peripheral<P = T> + 'd, |
| 147 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, | 154 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, |
| 148 | config: Config, | 155 | config: Config, |
| 149 | ) -> Self { | 156 | ) -> Self { |
| 150 | into_ref!(b); | 157 | into_ref!(slice, b); |
| 151 | Self::new_inner(inner, None, Some(b.map_into()), Pull::None, config, Divmode::DIV) | 158 | Self::new_inner( |
| 159 | slice.number(), | ||
| 160 | None, | ||
| 161 | Some(b.map_into()), | ||
| 162 | Pull::None, | ||
| 163 | config, | ||
| 164 | Divmode::DIV, | ||
| 165 | ) | ||
| 152 | } | 166 | } |
| 153 | 167 | ||
| 154 | /// Create PWM driver with a 'a' and 'b' pins as output. | 168 | /// Create PWM driver with a 'a' and 'b' pins as output. |
| 155 | #[inline] | 169 | #[inline] |
| 156 | pub fn new_output_ab( | 170 | pub fn new_output_ab<T: Slice>( |
| 157 | inner: impl Peripheral<P = T> + 'd, | 171 | slice: impl Peripheral<P = T> + 'd, |
| 158 | a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, | 172 | a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, |
| 159 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, | 173 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, |
| 160 | config: Config, | 174 | config: Config, |
| 161 | ) -> Self { | 175 | ) -> Self { |
| 162 | into_ref!(a, b); | 176 | into_ref!(slice, a, b); |
| 163 | Self::new_inner( | 177 | Self::new_inner( |
| 164 | inner, | 178 | slice.number(), |
| 165 | Some(a.map_into()), | 179 | Some(a.map_into()), |
| 166 | Some(b.map_into()), | 180 | Some(b.map_into()), |
| 167 | Pull::None, | 181 | Pull::None, |
| @@ -172,30 +186,30 @@ impl<'d, T: Slice> Pwm<'d, T> { | |||
| 172 | 186 | ||
| 173 | /// Create PWM driver with a single 'b' as input pin. | 187 | /// Create PWM driver with a single 'b' as input pin. |
| 174 | #[inline] | 188 | #[inline] |
| 175 | pub fn new_input( | 189 | pub fn new_input<T: Slice>( |
| 176 | inner: impl Peripheral<P = T> + 'd, | 190 | slice: impl Peripheral<P = T> + 'd, |
| 177 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, | 191 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, |
| 178 | b_pull: Pull, | 192 | b_pull: Pull, |
| 179 | mode: InputMode, | 193 | mode: InputMode, |
| 180 | config: Config, | 194 | config: Config, |
| 181 | ) -> Self { | 195 | ) -> Self { |
| 182 | into_ref!(b); | 196 | into_ref!(slice, b); |
| 183 | Self::new_inner(inner, None, Some(b.map_into()), b_pull, config, mode.into()) | 197 | Self::new_inner(slice.number(), None, Some(b.map_into()), b_pull, config, mode.into()) |
| 184 | } | 198 | } |
| 185 | 199 | ||
| 186 | /// Create PWM driver with a 'a' and 'b' pins in the desired input mode. | 200 | /// Create PWM driver with a 'a' and 'b' pins in the desired input mode. |
| 187 | #[inline] | 201 | #[inline] |
| 188 | pub fn new_output_input( | 202 | pub fn new_output_input<T: Slice>( |
| 189 | inner: impl Peripheral<P = T> + 'd, | 203 | slice: impl Peripheral<P = T> + 'd, |
| 190 | a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, | 204 | a: impl Peripheral<P = impl ChannelAPin<T>> + 'd, |
| 191 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, | 205 | b: impl Peripheral<P = impl ChannelBPin<T>> + 'd, |
| 192 | b_pull: Pull, | 206 | b_pull: Pull, |
| 193 | mode: InputMode, | 207 | mode: InputMode, |
| 194 | config: Config, | 208 | config: Config, |
| 195 | ) -> Self { | 209 | ) -> Self { |
| 196 | into_ref!(a, b); | 210 | into_ref!(slice, a, b); |
| 197 | Self::new_inner( | 211 | Self::new_inner( |
| 198 | inner, | 212 | slice.number(), |
| 199 | Some(a.map_into()), | 213 | Some(a.map_into()), |
| 200 | Some(b.map_into()), | 214 | Some(b.map_into()), |
| 201 | b_pull, | 215 | b_pull, |
| @@ -206,7 +220,7 @@ impl<'d, T: Slice> Pwm<'d, T> { | |||
| 206 | 220 | ||
| 207 | /// Set the PWM config. | 221 | /// Set the PWM config. |
| 208 | pub fn set_config(&mut self, config: &Config) { | 222 | pub fn set_config(&mut self, config: &Config) { |
| 209 | Self::configure(self.inner.regs(), config); | 223 | Self::configure(pac::PWM.ch(self.slice), config); |
| 210 | } | 224 | } |
| 211 | 225 | ||
| 212 | fn configure(p: pac::pwm::Channel, config: &Config) { | 226 | fn configure(p: pac::pwm::Channel, config: &Config) { |
| @@ -228,22 +242,22 @@ impl<'d, T: Slice> Pwm<'d, T> { | |||
| 228 | }); | 242 | }); |
| 229 | } | 243 | } |
| 230 | 244 | ||
| 231 | /// Advances a slice’s output phase by one count while it is running | 245 | /// Advances a slice's output phase by one count while it is running |
| 232 | /// by inserting a pulse into the clock enable. The counter | 246 | /// by inserting a pulse into the clock enable. The counter |
| 233 | /// will not count faster than once per cycle. | 247 | /// will not count faster than once per cycle. |
| 234 | #[inline] | 248 | #[inline] |
| 235 | pub fn phase_advance(&mut self) { | 249 | pub fn phase_advance(&mut self) { |
| 236 | let p = self.inner.regs(); | 250 | let p = pac::PWM.ch(self.slice); |
| 237 | p.csr().write_set(|w| w.set_ph_adv(true)); | 251 | p.csr().write_set(|w| w.set_ph_adv(true)); |
| 238 | while p.csr().read().ph_adv() {} | 252 | while p.csr().read().ph_adv() {} |
| 239 | } | 253 | } |
| 240 | 254 | ||
| 241 | /// Retards a slice’s output phase by one count while it is running | 255 | /// Retards a slice's output phase by one count while it is running |
| 242 | /// by deleting a pulse from the clock enable. The counter will not | 256 | /// by deleting a pulse from the clock enable. The counter will not |
| 243 | /// count backward when clock enable is permenantly low. | 257 | /// count backward when clock enable is permanently low. |
| 244 | #[inline] | 258 | #[inline] |
| 245 | pub fn phase_retard(&mut self) { | 259 | pub fn phase_retard(&mut self) { |
| 246 | let p = self.inner.regs(); | 260 | let p = pac::PWM.ch(self.slice); |
| 247 | p.csr().write_set(|w| w.set_ph_ret(true)); | 261 | p.csr().write_set(|w| w.set_ph_ret(true)); |
| 248 | while p.csr().read().ph_ret() {} | 262 | while p.csr().read().ph_ret() {} |
| 249 | } | 263 | } |
| @@ -251,13 +265,13 @@ impl<'d, T: Slice> Pwm<'d, T> { | |||
| 251 | /// Read PWM counter. | 265 | /// Read PWM counter. |
| 252 | #[inline] | 266 | #[inline] |
| 253 | pub fn counter(&self) -> u16 { | 267 | pub fn counter(&self) -> u16 { |
| 254 | self.inner.regs().ctr().read().ctr() | 268 | pac::PWM.ch(self.slice).ctr().read().ctr() |
| 255 | } | 269 | } |
| 256 | 270 | ||
| 257 | /// Write PWM counter. | 271 | /// Write PWM counter. |
| 258 | #[inline] | 272 | #[inline] |
| 259 | pub fn set_counter(&self, ctr: u16) { | 273 | pub fn set_counter(&self, ctr: u16) { |
| 260 | self.inner.regs().ctr().write(|w| w.set_ctr(ctr)) | 274 | pac::PWM.ch(self.slice).ctr().write(|w| w.set_ctr(ctr)) |
| 261 | } | 275 | } |
| 262 | 276 | ||
| 263 | /// Wait for channel interrupt. | 277 | /// Wait for channel interrupt. |
| @@ -281,7 +295,7 @@ impl<'d, T: Slice> Pwm<'d, T> { | |||
| 281 | 295 | ||
| 282 | #[inline] | 296 | #[inline] |
| 283 | fn bit(&self) -> u32 { | 297 | fn bit(&self) -> u32 { |
| 284 | 1 << self.inner.number() as usize | 298 | 1 << self.slice as usize |
| 285 | } | 299 | } |
| 286 | } | 300 | } |
| 287 | 301 | ||
| @@ -291,7 +305,7 @@ pub struct PwmBatch(u32); | |||
| 291 | impl PwmBatch { | 305 | impl PwmBatch { |
| 292 | #[inline] | 306 | #[inline] |
| 293 | /// Enable a PWM slice in this batch. | 307 | /// Enable a PWM slice in this batch. |
| 294 | pub fn enable(&mut self, pwm: &Pwm<'_, impl Slice>) { | 308 | pub fn enable(&mut self, pwm: &Pwm<'_>) { |
| 295 | self.0 |= pwm.bit(); | 309 | self.0 |= pwm.bit(); |
| 296 | } | 310 | } |
| 297 | 311 | ||
| @@ -308,9 +322,9 @@ impl PwmBatch { | |||
| 308 | } | 322 | } |
| 309 | } | 323 | } |
| 310 | 324 | ||
| 311 | impl<'d, T: Slice> Drop for Pwm<'d, T> { | 325 | impl<'d> Drop for Pwm<'d> { |
| 312 | fn drop(&mut self) { | 326 | fn drop(&mut self) { |
| 313 | self.inner.regs().csr().write_clear(|w| w.set_en(false)); | 327 | pac::PWM.ch(self.slice).csr().write_clear(|w| w.set_en(false)); |
| 314 | if let Some(pin) = &self.pin_a { | 328 | if let Some(pin) = &self.pin_a { |
| 315 | pin.gpio().ctrl().write(|w| w.set_funcsel(31)); | 329 | pin.gpio().ctrl().write(|w| w.set_funcsel(31)); |
| 316 | } | 330 | } |
| @@ -326,19 +340,14 @@ trait SealedSlice {} | |||
| 326 | #[allow(private_bounds)] | 340 | #[allow(private_bounds)] |
| 327 | pub trait Slice: Peripheral<P = Self> + SealedSlice + Sized + 'static { | 341 | pub trait Slice: Peripheral<P = Self> + SealedSlice + Sized + 'static { |
| 328 | /// Slice number. | 342 | /// Slice number. |
| 329 | fn number(&self) -> u8; | 343 | fn number(&self) -> usize; |
| 330 | |||
| 331 | /// Slice register block. | ||
| 332 | fn regs(&self) -> pac::pwm::Channel { | ||
| 333 | pac::PWM.ch(self.number() as _) | ||
| 334 | } | ||
| 335 | } | 344 | } |
| 336 | 345 | ||
| 337 | macro_rules! slice { | 346 | macro_rules! slice { |
| 338 | ($name:ident, $num:expr) => { | 347 | ($name:ident, $num:expr) => { |
| 339 | impl SealedSlice for peripherals::$name {} | 348 | impl SealedSlice for peripherals::$name {} |
| 340 | impl Slice for peripherals::$name { | 349 | impl Slice for peripherals::$name { |
| 341 | fn number(&self) -> u8 { | 350 | fn number(&self) -> usize { |
| 342 | $num | 351 | $num |
| 343 | } | 352 | } |
| 344 | } | 353 | } |
diff --git a/examples/rp/src/bin/interrupt.rs b/examples/rp/src/bin/interrupt.rs index d334d35d7..5b9d7027e 100644 --- a/examples/rp/src/bin/interrupt.rs +++ b/examples/rp/src/bin/interrupt.rs | |||
| @@ -15,7 +15,6 @@ use embassy_executor::Spawner; | |||
| 15 | use embassy_rp::adc::{self, Adc, Blocking}; | 15 | use embassy_rp::adc::{self, Adc, Blocking}; |
| 16 | use embassy_rp::gpio::Pull; | 16 | use embassy_rp::gpio::Pull; |
| 17 | use embassy_rp::interrupt; | 17 | use embassy_rp::interrupt; |
| 18 | use embassy_rp::peripherals::PWM_SLICE4; | ||
| 19 | use embassy_rp::pwm::{Config, Pwm}; | 18 | use embassy_rp::pwm::{Config, Pwm}; |
| 20 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; | 19 | use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex; |
| 21 | use embassy_sync::blocking_mutex::Mutex; | 20 | use embassy_sync::blocking_mutex::Mutex; |
| @@ -26,7 +25,7 @@ use static_cell::StaticCell; | |||
| 26 | use {defmt_rtt as _, panic_probe as _}; | 25 | use {defmt_rtt as _, panic_probe as _}; |
| 27 | 26 | ||
| 28 | static COUNTER: AtomicU32 = AtomicU32::new(0); | 27 | static COUNTER: AtomicU32 = AtomicU32::new(0); |
| 29 | static PWM: Mutex<CriticalSectionRawMutex, RefCell<Option<Pwm<PWM_SLICE4>>>> = Mutex::new(RefCell::new(None)); | 28 | static PWM: Mutex<CriticalSectionRawMutex, RefCell<Option<Pwm>>> = Mutex::new(RefCell::new(None)); |
| 30 | static ADC: Mutex<CriticalSectionRawMutex, RefCell<Option<(Adc<Blocking>, adc::Channel)>>> = | 29 | static ADC: Mutex<CriticalSectionRawMutex, RefCell<Option<(Adc<Blocking>, adc::Channel)>>> = |
| 31 | Mutex::new(RefCell::new(None)); | 30 | Mutex::new(RefCell::new(None)); |
| 32 | static ADC_VALUES: Channel<CriticalSectionRawMutex, u16, 2048> = Channel::new(); | 31 | static ADC_VALUES: Channel<CriticalSectionRawMutex, u16, 2048> = Channel::new(); |
