aboutsummaryrefslogtreecommitdiff
path: root/embassy-rp
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-05-05 20:45:02 +0200
committerpennae <[email protected]>2023-05-06 11:52:25 +0200
commit37b460637df0a20885ba8a0fbb0699e2d44ee4ec (patch)
tree6eff5bfda3d5ccdfcdaad39dc48468fed01be4ff /embassy-rp
parent41ec4170a5ae9920fe31327252ba1bba754b6d9f (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.rs60
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
14use crate::dma::{Channel, Transfer, Word}; 14use crate::dma::{Channel, Transfer, Word};
15use crate::gpio::sealed::Pin as SealedPin; 15use crate::gpio::sealed::Pin as SealedPin;
16use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate}; 16use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate};
17use crate::pac::dma::vals::TreqSel; 17use crate::pac::dma::vals::TreqSel;
18use crate::relocate::RelocatedProgram; 18use crate::relocate::RelocatedProgram;
19use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt}; 19use 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)]
60pub enum Direction {
61 In = 0,
62 Out = 1,
63}
64
57const RXNEMPTY_MASK: u32 = 1 << 0; 65const RXNEMPTY_MASK: u32 = 1 << 0;
58const TXNFULL_MASK: u32 = 1 << 4; 66const TXNFULL_MASK: u32 = 1 << 4;
59const SMIRQ_MASK: u32 = 1 << 8; 67const 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));