aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/pio.rs60
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs9
2 files changed, 61 insertions, 8 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));
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs
index c3466b554..40dee1c4d 100644
--- a/examples/rp/src/bin/pio_hd44780.rs
+++ b/examples/rp/src/bin/pio_hd44780.rs
@@ -7,7 +7,7 @@ use core::fmt::Write;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_rp::dma::{AnyChannel, Channel}; 8use embassy_rp::dma::{AnyChannel, Channel};
9use embassy_rp::peripherals::PIO0; 9use embassy_rp::peripherals::PIO0;
10use embassy_rp::pio::{FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; 10use embassy_rp::pio::{Direction, FifoJoin, Pio, PioPin, ShiftDirection, StateMachine};
11use embassy_rp::pwm::{Config, Pwm}; 11use embassy_rp::pwm::{Config, Pwm};
12use embassy_rp::relocate::RelocatedProgram; 12use embassy_rp::relocate::RelocatedProgram;
13use embassy_rp::{into_ref, Peripheral, PeripheralRef}; 13use embassy_rp::{into_ref, Peripheral, PeripheralRef};
@@ -115,12 +115,7 @@ impl<'l> HD44780<'l> {
115 let db6 = common.make_pio_pin(db6); 115 let db6 = common.make_pio_pin(db6);
116 let db7 = common.make_pio_pin(db7); 116 let db7 = common.make_pio_pin(db7);
117 117
118 sm0.set_set_pins(&[&rs, &rw]); 118 sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]);
119 embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11);
120 sm0.set_set_pins(&[&e]);
121 embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b1);
122 sm0.set_set_pins(&[&db4, &db5, &db6, &db7]);
123 embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11111);
124 119
125 let relocated = RelocatedProgram::new(&prg.program); 120 let relocated = RelocatedProgram::new(&prg.program);
126 sm0.use_program(&common.load_program(&relocated), &[&e]); 121 sm0.use_program(&common.load_program(&relocated), &[&e]);