diff options
| author | pennae <[email protected]> | 2023-05-05 20:45:02 +0200 |
|---|---|---|
| committer | pennae <[email protected]> | 2023-05-06 11:52:25 +0200 |
| commit | 37b460637df0a20885ba8a0fbb0699e2d44ee4ec (patch) | |
| tree | 6eff5bfda3d5ccdfcdaad39dc48468fed01be4ff /embassy-rp | |
| parent | 41ec4170a5ae9920fe31327252ba1bba754b6d9f (diff) | |
rp/pio: add set-pin-{values,dirs} convenience functions
these are needed a lot during state machine setup, it makes sense to
provide convenience functions for them.
Diffstat (limited to 'embassy-rp')
| -rw-r--r-- | embassy-rp/src/pio.rs | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index f835fc8d9..8d0547907 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs | |||
| @@ -13,7 +13,7 @@ use pio::{SideSet, Wrap}; | |||
| 13 | 13 | ||
| 14 | use crate::dma::{Channel, Transfer, Word}; | 14 | use crate::dma::{Channel, Transfer, Word}; |
| 15 | use crate::gpio::sealed::Pin as SealedPin; | 15 | use crate::gpio::sealed::Pin as SealedPin; |
| 16 | use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate}; | 16 | use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate}; |
| 17 | use crate::pac::dma::vals::TreqSel; | 17 | use crate::pac::dma::vals::TreqSel; |
| 18 | use crate::relocate::RelocatedProgram; | 18 | use crate::relocate::RelocatedProgram; |
| 19 | use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt}; | 19 | use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt}; |
| @@ -54,6 +54,14 @@ pub enum ShiftDirection { | |||
| 54 | Left = 0, | 54 | Left = 0, |
| 55 | } | 55 | } |
| 56 | 56 | ||
| 57 | #[derive(Clone, Copy, PartialEq, Eq, Debug)] | ||
| 58 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 59 | #[repr(u8)] | ||
| 60 | pub enum Direction { | ||
| 61 | In = 0, | ||
| 62 | Out = 1, | ||
| 63 | } | ||
| 64 | |||
| 57 | const RXNEMPTY_MASK: u32 = 1 << 0; | 65 | const RXNEMPTY_MASK: u32 = 1 << 0; |
| 58 | const TXNFULL_MASK: u32 = 1 << 4; | 66 | const TXNFULL_MASK: u32 = 1 << 4; |
| 59 | const SMIRQ_MASK: u32 = 1 << 8; | 67 | const SMIRQ_MASK: u32 = 1 << 8; |
| @@ -533,6 +541,56 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { | |||
| 533 | } | 541 | } |
| 534 | } | 542 | } |
| 535 | 543 | ||
| 544 | fn with_paused(&mut self, f: impl FnOnce(&mut Self)) { | ||
| 545 | let enabled = self.is_enabled(); | ||
| 546 | self.set_enable(false); | ||
| 547 | let pincfg = unsafe { Self::this_sm().pinctrl().read() }; | ||
| 548 | let execcfg = unsafe { Self::this_sm().execctrl().read() }; | ||
| 549 | unsafe { | ||
| 550 | Self::this_sm().execctrl().write_clear(|w| w.set_out_sticky(true)); | ||
| 551 | } | ||
| 552 | f(self); | ||
| 553 | unsafe { | ||
| 554 | Self::this_sm().pinctrl().write_value(pincfg); | ||
| 555 | Self::this_sm().execctrl().write_value(execcfg); | ||
| 556 | } | ||
| 557 | self.set_enable(enabled); | ||
| 558 | } | ||
| 559 | |||
| 560 | /// Sets pin directions. This pauses the current state machine to run `SET` commands | ||
| 561 | /// and temporarily unsets the `OUT_STICKY` bit. | ||
| 562 | pub fn set_pin_dirs(&mut self, dir: Direction, pins: &[&Pin<'d, PIO>]) { | ||
| 563 | self.with_paused(|sm| { | ||
| 564 | for pin in pins { | ||
| 565 | unsafe { | ||
| 566 | Self::this_sm().pinctrl().write(|w| { | ||
| 567 | w.set_set_base(pin.pin()); | ||
| 568 | w.set_set_count(1); | ||
| 569 | }); | ||
| 570 | // SET PINDIRS, (dir) | ||
| 571 | sm.exec_instr(0b111_00000_100_00000 | dir as u16); | ||
| 572 | } | ||
| 573 | } | ||
| 574 | }); | ||
| 575 | } | ||
| 576 | |||
| 577 | /// Sets pin output values. This pauses the current state machine to run | ||
| 578 | /// `SET` commands and temporarily unsets the `OUT_STICKY` bit. | ||
| 579 | pub fn set_pins(&mut self, level: Level, pins: &[&Pin<'d, PIO>]) { | ||
| 580 | self.with_paused(|sm| { | ||
| 581 | for pin in pins { | ||
| 582 | unsafe { | ||
| 583 | Self::this_sm().pinctrl().write(|w| { | ||
| 584 | w.set_set_base(pin.pin()); | ||
| 585 | w.set_set_count(1); | ||
| 586 | }); | ||
| 587 | // SET PINS, (dir) | ||
| 588 | sm.exec_instr(0b111_00000_000_00000 | level as u16); | ||
| 589 | } | ||
| 590 | } | ||
| 591 | }); | ||
| 592 | } | ||
| 593 | |||
| 536 | pub fn set_jmp_pin(&mut self, pin: u8) { | 594 | pub fn set_jmp_pin(&mut self, pin: u8) { |
| 537 | unsafe { | 595 | unsafe { |
| 538 | Self::this_sm().execctrl().modify(|w| w.set_jmp_pin(pin)); | 596 | Self::this_sm().execctrl().modify(|w| w.set_jmp_pin(pin)); |
