diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-09-27 21:17:11 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2025-09-28 21:05:37 +0200 |
| commit | 6ee0d15f4975daa52a22c42e57c673f5ecc86b9d (patch) | |
| tree | b5acc97ce4f02dbd05f214fc3e269c733cd0857a /embassy-nrf/src | |
| parent | b552373f9a7c5491367d8f5a04111eb27b63f5e2 (diff) | |
nrf/pwm: erase instance generics
Diffstat (limited to 'embassy-nrf/src')
| -rw-r--r-- | embassy-nrf/src/pwm.rs | 147 |
1 files changed, 60 insertions, 87 deletions
diff --git a/embassy-nrf/src/pwm.rs b/embassy-nrf/src/pwm.rs index d6b40b5c0..d67cb546b 100644 --- a/embassy-nrf/src/pwm.rs +++ b/embassy-nrf/src/pwm.rs | |||
| @@ -15,8 +15,8 @@ use crate::{interrupt, pac}; | |||
| 15 | 15 | ||
| 16 | /// SimplePwm is the traditional pwm interface you're probably used to, allowing | 16 | /// SimplePwm is the traditional pwm interface you're probably used to, allowing |
| 17 | /// to simply set a duty cycle across up to four channels. | 17 | /// to simply set a duty cycle across up to four channels. |
| 18 | pub struct SimplePwm<'d, T: Instance> { | 18 | pub struct SimplePwm<'d> { |
| 19 | _peri: Peri<'d, T>, | 19 | r: pac::pwm::Pwm, |
| 20 | duty: [u16; 4], | 20 | duty: [u16; 4], |
| 21 | ch0: Option<Peri<'d, AnyPin>>, | 21 | ch0: Option<Peri<'d, AnyPin>>, |
| 22 | ch1: Option<Peri<'d, AnyPin>>, | 22 | ch1: Option<Peri<'d, AnyPin>>, |
| @@ -26,8 +26,8 @@ pub struct SimplePwm<'d, T: Instance> { | |||
| 26 | 26 | ||
| 27 | /// SequencePwm allows you to offload the updating of a sequence of duty cycles | 27 | /// SequencePwm allows you to offload the updating of a sequence of duty cycles |
| 28 | /// to up to four channels, as well as repeat that sequence n times. | 28 | /// to up to four channels, as well as repeat that sequence n times. |
| 29 | pub struct SequencePwm<'d, T: Instance> { | 29 | pub struct SequencePwm<'d> { |
| 30 | _peri: Peri<'d, T>, | 30 | r: pac::pwm::Pwm, |
| 31 | ch0: Option<Peri<'d, AnyPin>>, | 31 | ch0: Option<Peri<'d, AnyPin>>, |
| 32 | ch1: Option<Peri<'d, AnyPin>>, | 32 | ch1: Option<Peri<'d, AnyPin>>, |
| 33 | ch2: Option<Peri<'d, AnyPin>>, | 33 | ch2: Option<Peri<'d, AnyPin>>, |
| @@ -51,16 +51,16 @@ const MAX_SEQUENCE_LEN: usize = 32767; | |||
| 51 | /// The used pwm clock frequency | 51 | /// The used pwm clock frequency |
| 52 | pub const PWM_CLK_HZ: u32 = 16_000_000; | 52 | pub const PWM_CLK_HZ: u32 = 16_000_000; |
| 53 | 53 | ||
| 54 | impl<'d, T: Instance> SequencePwm<'d, T> { | 54 | impl<'d> SequencePwm<'d> { |
| 55 | /// Create a new 1-channel PWM | 55 | /// Create a new 1-channel PWM |
| 56 | #[allow(unused_unsafe)] | 56 | #[allow(unused_unsafe)] |
| 57 | pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> { | 57 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, config: Config) -> Result<Self, Error> { |
| 58 | Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) | 58 | Self::new_inner(pwm, Some(ch0.into()), None, None, None, config) |
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | /// Create a new 2-channel PWM | 61 | /// Create a new 2-channel PWM |
| 62 | #[allow(unused_unsafe)] | 62 | #[allow(unused_unsafe)] |
| 63 | pub fn new_2ch( | 63 | pub fn new_2ch<T: Instance>( |
| 64 | pwm: Peri<'d, T>, | 64 | pwm: Peri<'d, T>, |
| 65 | ch0: Peri<'d, impl GpioPin>, | 65 | ch0: Peri<'d, impl GpioPin>, |
| 66 | ch1: Peri<'d, impl GpioPin>, | 66 | ch1: Peri<'d, impl GpioPin>, |
| @@ -71,7 +71,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 71 | 71 | ||
| 72 | /// Create a new 3-channel PWM | 72 | /// Create a new 3-channel PWM |
| 73 | #[allow(unused_unsafe)] | 73 | #[allow(unused_unsafe)] |
| 74 | pub fn new_3ch( | 74 | pub fn new_3ch<T: Instance>( |
| 75 | pwm: Peri<'d, T>, | 75 | pwm: Peri<'d, T>, |
| 76 | ch0: Peri<'d, impl GpioPin>, | 76 | ch0: Peri<'d, impl GpioPin>, |
| 77 | ch1: Peri<'d, impl GpioPin>, | 77 | ch1: Peri<'d, impl GpioPin>, |
| @@ -83,7 +83,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 83 | 83 | ||
| 84 | /// Create a new 4-channel PWM | 84 | /// Create a new 4-channel PWM |
| 85 | #[allow(unused_unsafe)] | 85 | #[allow(unused_unsafe)] |
| 86 | pub fn new_4ch( | 86 | pub fn new_4ch<T: Instance>( |
| 87 | pwm: Peri<'d, T>, | 87 | pwm: Peri<'d, T>, |
| 88 | ch0: Peri<'d, impl GpioPin>, | 88 | ch0: Peri<'d, impl GpioPin>, |
| 89 | ch1: Peri<'d, impl GpioPin>, | 89 | ch1: Peri<'d, impl GpioPin>, |
| @@ -101,7 +101,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 101 | ) | 101 | ) |
| 102 | } | 102 | } |
| 103 | 103 | ||
| 104 | fn new_inner( | 104 | fn new_inner<T: Instance>( |
| 105 | _pwm: Peri<'d, T>, | 105 | _pwm: Peri<'d, T>, |
| 106 | ch0: Option<Peri<'d, AnyPin>>, | 106 | ch0: Option<Peri<'d, AnyPin>>, |
| 107 | ch1: Option<Peri<'d, AnyPin>>, | 107 | ch1: Option<Peri<'d, AnyPin>>, |
| @@ -174,7 +174,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 174 | r.countertop().write(|w| w.set_countertop(config.max_duty)); | 174 | r.countertop().write(|w| w.set_countertop(config.max_duty)); |
| 175 | 175 | ||
| 176 | Ok(Self { | 176 | Ok(Self { |
| 177 | _peri: _pwm, | 177 | r: T::regs(), |
| 178 | ch0, | 178 | ch0, |
| 179 | ch1, | 179 | ch1, |
| 180 | ch2, | 180 | ch2, |
| @@ -185,57 +185,43 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 185 | /// Returns reference to `Stopped` event endpoint for PPI. | 185 | /// Returns reference to `Stopped` event endpoint for PPI. |
| 186 | #[inline(always)] | 186 | #[inline(always)] |
| 187 | pub fn event_stopped(&self) -> Event<'d> { | 187 | pub fn event_stopped(&self) -> Event<'d> { |
| 188 | let r = T::regs(); | 188 | Event::from_reg(self.r.events_stopped()) |
| 189 | |||
| 190 | Event::from_reg(r.events_stopped()) | ||
| 191 | } | 189 | } |
| 192 | 190 | ||
| 193 | /// Returns reference to `LoopsDone` event endpoint for PPI. | 191 | /// Returns reference to `LoopsDone` event endpoint for PPI. |
| 194 | #[inline(always)] | 192 | #[inline(always)] |
| 195 | pub fn event_loops_done(&self) -> Event<'d> { | 193 | pub fn event_loops_done(&self) -> Event<'d> { |
| 196 | let r = T::regs(); | 194 | Event::from_reg(self.r.events_loopsdone()) |
| 197 | |||
| 198 | Event::from_reg(r.events_loopsdone()) | ||
| 199 | } | 195 | } |
| 200 | 196 | ||
| 201 | /// Returns reference to `PwmPeriodEnd` event endpoint for PPI. | 197 | /// Returns reference to `PwmPeriodEnd` event endpoint for PPI. |
| 202 | #[inline(always)] | 198 | #[inline(always)] |
| 203 | pub fn event_pwm_period_end(&self) -> Event<'d> { | 199 | pub fn event_pwm_period_end(&self) -> Event<'d> { |
| 204 | let r = T::regs(); | 200 | Event::from_reg(self.r.events_pwmperiodend()) |
| 205 | |||
| 206 | Event::from_reg(r.events_pwmperiodend()) | ||
| 207 | } | 201 | } |
| 208 | 202 | ||
| 209 | /// Returns reference to `Seq0 End` event endpoint for PPI. | 203 | /// Returns reference to `Seq0 End` event endpoint for PPI. |
| 210 | #[inline(always)] | 204 | #[inline(always)] |
| 211 | pub fn event_seq_end(&self) -> Event<'d> { | 205 | pub fn event_seq_end(&self) -> Event<'d> { |
| 212 | let r = T::regs(); | 206 | Event::from_reg(self.r.events_seqend(0)) |
| 213 | |||
| 214 | Event::from_reg(r.events_seqend(0)) | ||
| 215 | } | 207 | } |
| 216 | 208 | ||
| 217 | /// Returns reference to `Seq1 End` event endpoint for PPI. | 209 | /// Returns reference to `Seq1 End` event endpoint for PPI. |
| 218 | #[inline(always)] | 210 | #[inline(always)] |
| 219 | pub fn event_seq1_end(&self) -> Event<'d> { | 211 | pub fn event_seq1_end(&self) -> Event<'d> { |
| 220 | let r = T::regs(); | 212 | Event::from_reg(self.r.events_seqend(1)) |
| 221 | |||
| 222 | Event::from_reg(r.events_seqend(1)) | ||
| 223 | } | 213 | } |
| 224 | 214 | ||
| 225 | /// Returns reference to `Seq0 Started` event endpoint for PPI. | 215 | /// Returns reference to `Seq0 Started` event endpoint for PPI. |
| 226 | #[inline(always)] | 216 | #[inline(always)] |
| 227 | pub fn event_seq0_started(&self) -> Event<'d> { | 217 | pub fn event_seq0_started(&self) -> Event<'d> { |
| 228 | let r = T::regs(); | 218 | Event::from_reg(self.r.events_seqstarted(0)) |
| 229 | |||
| 230 | Event::from_reg(r.events_seqstarted(0)) | ||
| 231 | } | 219 | } |
| 232 | 220 | ||
| 233 | /// Returns reference to `Seq1 Started` event endpoint for PPI. | 221 | /// Returns reference to `Seq1 Started` event endpoint for PPI. |
| 234 | #[inline(always)] | 222 | #[inline(always)] |
| 235 | pub fn event_seq1_started(&self) -> Event<'d> { | 223 | pub fn event_seq1_started(&self) -> Event<'d> { |
| 236 | let r = T::regs(); | 224 | Event::from_reg(self.r.events_seqstarted(1)) |
| 237 | |||
| 238 | Event::from_reg(r.events_seqstarted(1)) | ||
| 239 | } | 225 | } |
| 240 | 226 | ||
| 241 | /// Returns reference to `Seq0 Start` task endpoint for PPI. | 227 | /// Returns reference to `Seq0 Start` task endpoint for PPI. |
| @@ -244,9 +230,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 244 | /// Interacting with the sequence while it runs puts it in an unknown state | 230 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 245 | #[inline(always)] | 231 | #[inline(always)] |
| 246 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { | 232 | pub unsafe fn task_start_seq0(&self) -> Task<'d> { |
| 247 | let r = T::regs(); | 233 | Task::from_reg(self.r.tasks_seqstart(0)) |
| 248 | |||
| 249 | Task::from_reg(r.tasks_seqstart(0)) | ||
| 250 | } | 234 | } |
| 251 | 235 | ||
| 252 | /// Returns reference to `Seq1 Started` task endpoint for PPI. | 236 | /// Returns reference to `Seq1 Started` task endpoint for PPI. |
| @@ -255,9 +239,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 255 | /// Interacting with the sequence while it runs puts it in an unknown state | 239 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 256 | #[inline(always)] | 240 | #[inline(always)] |
| 257 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { | 241 | pub unsafe fn task_start_seq1(&self) -> Task<'d> { |
| 258 | let r = T::regs(); | 242 | Task::from_reg(self.r.tasks_seqstart(1)) |
| 259 | |||
| 260 | Task::from_reg(r.tasks_seqstart(1)) | ||
| 261 | } | 243 | } |
| 262 | 244 | ||
| 263 | /// Returns reference to `NextStep` task endpoint for PPI. | 245 | /// Returns reference to `NextStep` task endpoint for PPI. |
| @@ -266,9 +248,7 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 266 | /// Interacting with the sequence while it runs puts it in an unknown state | 248 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 267 | #[inline(always)] | 249 | #[inline(always)] |
| 268 | pub unsafe fn task_next_step(&self) -> Task<'d> { | 250 | pub unsafe fn task_next_step(&self) -> Task<'d> { |
| 269 | let r = T::regs(); | 251 | Task::from_reg(self.r.tasks_nextstep()) |
| 270 | |||
| 271 | Task::from_reg(r.tasks_nextstep()) | ||
| 272 | } | 252 | } |
| 273 | 253 | ||
| 274 | /// Returns reference to `Stop` task endpoint for PPI. | 254 | /// Returns reference to `Stop` task endpoint for PPI. |
| @@ -277,36 +257,34 @@ impl<'d, T: Instance> SequencePwm<'d, T> { | |||
| 277 | /// Interacting with the sequence while it runs puts it in an unknown state | 257 | /// Interacting with the sequence while it runs puts it in an unknown state |
| 278 | #[inline(always)] | 258 | #[inline(always)] |
| 279 | pub unsafe fn task_stop(&self) -> Task<'d> { | 259 | pub unsafe fn task_stop(&self) -> Task<'d> { |
| 280 | let r = T::regs(); | 260 | Task::from_reg(self.r.tasks_stop()) |
| 281 | |||
| 282 | Task::from_reg(r.tasks_stop()) | ||
| 283 | } | 261 | } |
| 284 | } | 262 | } |
| 285 | 263 | ||
| 286 | impl<'a, T: Instance> Drop for SequencePwm<'a, T> { | 264 | impl<'a> Drop for SequencePwm<'a> { |
| 287 | fn drop(&mut self) { | 265 | fn drop(&mut self) { |
| 288 | let r = T::regs(); | ||
| 289 | |||
| 290 | if let Some(pin) = &self.ch0 { | 266 | if let Some(pin) = &self.ch0 { |
| 291 | pin.set_low(); | 267 | pin.set_low(); |
| 292 | pin.conf().write(|_| ()); | 268 | pin.conf().write(|_| ()); |
| 293 | r.psel().out(0).write_value(DISCONNECTED); | 269 | self.r.psel().out(0).write_value(DISCONNECTED); |
| 294 | } | 270 | } |
| 295 | if let Some(pin) = &self.ch1 { | 271 | if let Some(pin) = &self.ch1 { |
| 296 | pin.set_low(); | 272 | pin.set_low(); |
| 297 | pin.conf().write(|_| ()); | 273 | pin.conf().write(|_| ()); |
| 298 | r.psel().out(1).write_value(DISCONNECTED); | 274 | self.r.psel().out(1).write_value(DISCONNECTED); |
| 299 | } | 275 | } |
| 300 | if let Some(pin) = &self.ch2 { | 276 | if let Some(pin) = &self.ch2 { |
| 301 | pin.set_low(); | 277 | pin.set_low(); |
| 302 | pin.conf().write(|_| ()); | 278 | pin.conf().write(|_| ()); |
| 303 | r.psel().out(2).write_value(DISCONNECTED); | 279 | self.r.psel().out(2).write_value(DISCONNECTED); |
| 304 | } | 280 | } |
| 305 | if let Some(pin) = &self.ch3 { | 281 | if let Some(pin) = &self.ch3 { |
| 306 | pin.set_low(); | 282 | pin.set_low(); |
| 307 | pin.conf().write(|_| ()); | 283 | pin.conf().write(|_| ()); |
| 308 | r.psel().out(3).write_value(DISCONNECTED); | 284 | self.r.psel().out(3).write_value(DISCONNECTED); |
| 309 | } | 285 | } |
| 286 | |||
| 287 | self.r.enable().write(|w| w.set_enable(false)); | ||
| 310 | } | 288 | } |
| 311 | } | 289 | } |
| 312 | 290 | ||
| @@ -384,13 +362,13 @@ impl<'s> Sequence<'s> { | |||
| 384 | /// A single sequence that can be started and stopped. | 362 | /// A single sequence that can be started and stopped. |
| 385 | /// Takes one sequence along with its configuration. | 363 | /// Takes one sequence along with its configuration. |
| 386 | #[non_exhaustive] | 364 | #[non_exhaustive] |
| 387 | pub struct SingleSequencer<'d, 's, T: Instance> { | 365 | pub struct SingleSequencer<'d, 's> { |
| 388 | sequencer: Sequencer<'d, 's, T>, | 366 | sequencer: Sequencer<'d, 's>, |
| 389 | } | 367 | } |
| 390 | 368 | ||
| 391 | impl<'d, 's, T: Instance> SingleSequencer<'d, 's, T> { | 369 | impl<'d, 's> SingleSequencer<'d, 's> { |
| 392 | /// Create a new sequencer | 370 | /// Create a new sequencer |
| 393 | pub fn new(pwm: &'s mut SequencePwm<'d, T>, words: &'s [u16], config: SequenceConfig) -> Self { | 371 | pub fn new(pwm: &'s mut SequencePwm<'d>, words: &'s [u16], config: SequenceConfig) -> Self { |
| 394 | Self { | 372 | Self { |
| 395 | sequencer: Sequencer::new(pwm, Sequence::new(words, config), None), | 373 | sequencer: Sequencer::new(pwm, Sequence::new(words, config), None), |
| 396 | } | 374 | } |
| @@ -423,16 +401,16 @@ impl<'d, 's, T: Instance> SingleSequencer<'d, 's, T> { | |||
| 423 | /// In the case where no second sequence is provided then the first sequence | 401 | /// In the case where no second sequence is provided then the first sequence |
| 424 | /// is used. | 402 | /// is used. |
| 425 | #[non_exhaustive] | 403 | #[non_exhaustive] |
| 426 | pub struct Sequencer<'d, 's, T: Instance> { | 404 | pub struct Sequencer<'d, 's> { |
| 427 | _pwm: &'s mut SequencePwm<'d, T>, | 405 | _pwm: &'s mut SequencePwm<'d>, |
| 428 | sequence0: Sequence<'s>, | 406 | sequence0: Sequence<'s>, |
| 429 | sequence1: Option<Sequence<'s>>, | 407 | sequence1: Option<Sequence<'s>>, |
| 430 | } | 408 | } |
| 431 | 409 | ||
| 432 | impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | 410 | impl<'d, 's> Sequencer<'d, 's> { |
| 433 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 | 411 | /// Create a new double sequence. In the absence of sequence 1, sequence 0 |
| 434 | /// will be used twice in the one loop. | 412 | /// will be used twice in the one loop. |
| 435 | pub fn new(pwm: &'s mut SequencePwm<'d, T>, sequence0: Sequence<'s>, sequence1: Option<Sequence<'s>>) -> Self { | 413 | pub fn new(pwm: &'s mut SequencePwm<'d>, sequence0: Sequence<'s>, sequence1: Option<Sequence<'s>>) -> Self { |
| 436 | Sequencer { | 414 | Sequencer { |
| 437 | _pwm: pwm, | 415 | _pwm: pwm, |
| 438 | sequence0, | 416 | sequence0, |
| @@ -459,7 +437,7 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 459 | 437 | ||
| 460 | self.stop(); | 438 | self.stop(); |
| 461 | 439 | ||
| 462 | let r = T::regs(); | 440 | let r = self._pwm.r; |
| 463 | 441 | ||
| 464 | r.seq(0).refresh().write(|w| w.0 = sequence0.config.refresh); | 442 | r.seq(0).refresh().write(|w| w.0 = sequence0.config.refresh); |
| 465 | r.seq(0).enddelay().write(|w| w.0 = sequence0.config.end_delay); | 443 | r.seq(0).enddelay().write(|w| w.0 = sequence0.config.end_delay); |
| @@ -499,7 +477,7 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 499 | /// `start` so that they may be further mutated. | 477 | /// `start` so that they may be further mutated. |
| 500 | #[inline(always)] | 478 | #[inline(always)] |
| 501 | pub fn stop(&self) { | 479 | pub fn stop(&self) { |
| 502 | let r = T::regs(); | 480 | let r = self._pwm.r; |
| 503 | 481 | ||
| 504 | r.shorts().write(|_| ()); | 482 | r.shorts().write(|_| ()); |
| 505 | 483 | ||
| @@ -510,7 +488,7 @@ impl<'d, 's, T: Instance> Sequencer<'d, 's, T> { | |||
| 510 | } | 488 | } |
| 511 | } | 489 | } |
| 512 | 490 | ||
| 513 | impl<'d, 's, T: Instance> Drop for Sequencer<'d, 's, T> { | 491 | impl<'d, 's> Drop for Sequencer<'d, 's> { |
| 514 | fn drop(&mut self) { | 492 | fn drop(&mut self) { |
| 515 | self.stop(); | 493 | self.stop(); |
| 516 | } | 494 | } |
| @@ -589,22 +567,22 @@ pub enum CounterMode { | |||
| 589 | UpAndDown, | 567 | UpAndDown, |
| 590 | } | 568 | } |
| 591 | 569 | ||
| 592 | impl<'d, T: Instance> SimplePwm<'d, T> { | 570 | impl<'d> SimplePwm<'d> { |
| 593 | /// Create a new 1-channel PWM | 571 | /// Create a new 1-channel PWM |
| 594 | #[allow(unused_unsafe)] | 572 | #[allow(unused_unsafe)] |
| 595 | pub fn new_1ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self { | 573 | pub fn new_1ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>) -> Self { |
| 596 | unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) } | 574 | unsafe { Self::new_inner(pwm, Some(ch0.into()), None, None, None) } |
| 597 | } | 575 | } |
| 598 | 576 | ||
| 599 | /// Create a new 2-channel PWM | 577 | /// Create a new 2-channel PWM |
| 600 | #[allow(unused_unsafe)] | 578 | #[allow(unused_unsafe)] |
| 601 | pub fn new_2ch(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self { | 579 | pub fn new_2ch<T: Instance>(pwm: Peri<'d, T>, ch0: Peri<'d, impl GpioPin>, ch1: Peri<'d, impl GpioPin>) -> Self { |
| 602 | Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None) | 580 | Self::new_inner(pwm, Some(ch0.into()), Some(ch1.into()), None, None) |
| 603 | } | 581 | } |
| 604 | 582 | ||
| 605 | /// Create a new 3-channel PWM | 583 | /// Create a new 3-channel PWM |
| 606 | #[allow(unused_unsafe)] | 584 | #[allow(unused_unsafe)] |
| 607 | pub fn new_3ch( | 585 | pub fn new_3ch<T: Instance>( |
| 608 | pwm: Peri<'d, T>, | 586 | pwm: Peri<'d, T>, |
| 609 | ch0: Peri<'d, impl GpioPin>, | 587 | ch0: Peri<'d, impl GpioPin>, |
| 610 | ch1: Peri<'d, impl GpioPin>, | 588 | ch1: Peri<'d, impl GpioPin>, |
| @@ -615,7 +593,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 615 | 593 | ||
| 616 | /// Create a new 4-channel PWM | 594 | /// Create a new 4-channel PWM |
| 617 | #[allow(unused_unsafe)] | 595 | #[allow(unused_unsafe)] |
| 618 | pub fn new_4ch( | 596 | pub fn new_4ch<T: Instance>( |
| 619 | pwm: Peri<'d, T>, | 597 | pwm: Peri<'d, T>, |
| 620 | ch0: Peri<'d, impl GpioPin>, | 598 | ch0: Peri<'d, impl GpioPin>, |
| 621 | ch1: Peri<'d, impl GpioPin>, | 599 | ch1: Peri<'d, impl GpioPin>, |
| @@ -633,7 +611,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 633 | } | 611 | } |
| 634 | } | 612 | } |
| 635 | 613 | ||
| 636 | fn new_inner( | 614 | fn new_inner<T: Instance>( |
| 637 | _pwm: Peri<'d, T>, | 615 | _pwm: Peri<'d, T>, |
| 638 | ch0: Option<Peri<'d, AnyPin>>, | 616 | ch0: Option<Peri<'d, AnyPin>>, |
| 639 | ch1: Option<Peri<'d, AnyPin>>, | 617 | ch1: Option<Peri<'d, AnyPin>>, |
| @@ -656,7 +634,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 656 | } | 634 | } |
| 657 | 635 | ||
| 658 | let pwm = Self { | 636 | let pwm = Self { |
| 659 | _peri: _pwm, | 637 | r: T::regs(), |
| 660 | ch0, | 638 | ch0, |
| 661 | ch1, | 639 | ch1, |
| 662 | ch2, | 640 | ch2, |
| @@ -691,22 +669,19 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 691 | /// Returns the enable state of the pwm counter | 669 | /// Returns the enable state of the pwm counter |
| 692 | #[inline(always)] | 670 | #[inline(always)] |
| 693 | pub fn is_enabled(&self) -> bool { | 671 | pub fn is_enabled(&self) -> bool { |
| 694 | let r = T::regs(); | 672 | self.r.enable().read().enable() |
| 695 | r.enable().read().enable() | ||
| 696 | } | 673 | } |
| 697 | 674 | ||
| 698 | /// Enables the PWM generator. | 675 | /// Enables the PWM generator. |
| 699 | #[inline(always)] | 676 | #[inline(always)] |
| 700 | pub fn enable(&self) { | 677 | pub fn enable(&self) { |
| 701 | let r = T::regs(); | 678 | self.r.enable().write(|w| w.set_enable(true)); |
| 702 | r.enable().write(|w| w.set_enable(true)); | ||
| 703 | } | 679 | } |
| 704 | 680 | ||
| 705 | /// Disables the PWM generator. Does NOT clear the last duty cycle from the pin. | 681 | /// Disables the PWM generator. Does NOT clear the last duty cycle from the pin. |
| 706 | #[inline(always)] | 682 | #[inline(always)] |
| 707 | pub fn disable(&self) { | 683 | pub fn disable(&self) { |
| 708 | let r = T::regs(); | 684 | self.r.enable().write(|w| w.set_enable(false)); |
| 709 | r.enable().write(|w| w.set_enable(false)); | ||
| 710 | } | 685 | } |
| 711 | 686 | ||
| 712 | /// Returns the current duty of the channel | 687 | /// Returns the current duty of the channel |
| @@ -716,32 +691,30 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 716 | 691 | ||
| 717 | /// Sets duty cycle (15 bit) for a PWM channel. | 692 | /// Sets duty cycle (15 bit) for a PWM channel. |
| 718 | pub fn set_duty(&mut self, channel: usize, duty: u16) { | 693 | pub fn set_duty(&mut self, channel: usize, duty: u16) { |
| 719 | let r = T::regs(); | ||
| 720 | |||
| 721 | self.duty[channel] = duty & 0x7FFF; | 694 | self.duty[channel] = duty & 0x7FFF; |
| 722 | 695 | ||
| 723 | // reload ptr in case self was moved | 696 | // reload ptr in case self was moved |
| 724 | r.seq(0).ptr().write_value((self.duty).as_ptr() as u32); | 697 | self.r.seq(0).ptr().write_value((self.duty).as_ptr() as u32); |
| 725 | 698 | ||
| 726 | // defensive before seqstart | 699 | // defensive before seqstart |
| 727 | compiler_fence(Ordering::SeqCst); | 700 | compiler_fence(Ordering::SeqCst); |
| 728 | 701 | ||
| 729 | r.events_seqend(0).write_value(0); | 702 | self.r.events_seqend(0).write_value(0); |
| 730 | 703 | ||
| 731 | // tasks_seqstart() doesn't exist in all svds so write its bit instead | 704 | // tasks_seqstart() doesn't exist in all svds so write its bit instead |
| 732 | r.tasks_seqstart(0).write_value(1); | 705 | self.r.tasks_seqstart(0).write_value(1); |
| 733 | 706 | ||
| 734 | // defensive wait until waveform is loaded after seqstart so set_duty | 707 | // defensive wait until waveform is loaded after seqstart so set_duty |
| 735 | // can't be called again while dma is still reading | 708 | // can't be called again while dma is still reading |
| 736 | if self.is_enabled() { | 709 | if self.is_enabled() { |
| 737 | while r.events_seqend(0).read() == 0 {} | 710 | while self.r.events_seqend(0).read() == 0 {} |
| 738 | } | 711 | } |
| 739 | } | 712 | } |
| 740 | 713 | ||
| 741 | /// Sets the PWM clock prescaler. | 714 | /// Sets the PWM clock prescaler. |
| 742 | #[inline(always)] | 715 | #[inline(always)] |
| 743 | pub fn set_prescaler(&self, div: Prescaler) { | 716 | pub fn set_prescaler(&self, div: Prescaler) { |
| 744 | T::regs() | 717 | self.r |
| 745 | .prescaler() | 718 | .prescaler() |
| 746 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(div as u8))); | 719 | .write(|w| w.set_prescaler(vals::Prescaler::from_bits(div as u8))); |
| 747 | } | 720 | } |
| @@ -749,7 +722,7 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 749 | /// Gets the PWM clock prescaler. | 722 | /// Gets the PWM clock prescaler. |
| 750 | #[inline(always)] | 723 | #[inline(always)] |
| 751 | pub fn prescaler(&self) -> Prescaler { | 724 | pub fn prescaler(&self) -> Prescaler { |
| 752 | match T::regs().prescaler().read().prescaler().to_bits() { | 725 | match self.r.prescaler().read().prescaler().to_bits() { |
| 753 | 0 => Prescaler::Div1, | 726 | 0 => Prescaler::Div1, |
| 754 | 1 => Prescaler::Div2, | 727 | 1 => Prescaler::Div2, |
| 755 | 2 => Prescaler::Div4, | 728 | 2 => Prescaler::Div4, |
| @@ -765,13 +738,13 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 765 | /// Sets the maximum duty cycle value. | 738 | /// Sets the maximum duty cycle value. |
| 766 | #[inline(always)] | 739 | #[inline(always)] |
| 767 | pub fn set_max_duty(&self, duty: u16) { | 740 | pub fn set_max_duty(&self, duty: u16) { |
| 768 | T::regs().countertop().write(|w| w.set_countertop(duty.min(32767u16))); | 741 | self.r.countertop().write(|w| w.set_countertop(duty.min(32767u16))); |
| 769 | } | 742 | } |
| 770 | 743 | ||
| 771 | /// Returns the maximum duty cycle value. | 744 | /// Returns the maximum duty cycle value. |
| 772 | #[inline(always)] | 745 | #[inline(always)] |
| 773 | pub fn max_duty(&self) -> u16 { | 746 | pub fn max_duty(&self) -> u16 { |
| 774 | T::regs().countertop().read().countertop() | 747 | self.r.countertop().read().countertop() |
| 775 | } | 748 | } |
| 776 | 749 | ||
| 777 | /// Sets the PWM output frequency. | 750 | /// Sets the PWM output frequency. |
| @@ -823,9 +796,9 @@ impl<'d, T: Instance> SimplePwm<'d, T> { | |||
| 823 | } | 796 | } |
| 824 | } | 797 | } |
| 825 | 798 | ||
| 826 | impl<'a, T: Instance> Drop for SimplePwm<'a, T> { | 799 | impl<'a> Drop for SimplePwm<'a> { |
| 827 | fn drop(&mut self) { | 800 | fn drop(&mut self) { |
| 828 | let r = T::regs(); | 801 | let r = &self.r; |
| 829 | 802 | ||
| 830 | self.disable(); | 803 | self.disable(); |
| 831 | 804 | ||
