diff options
| -rw-r--r-- | embassy-rp/src/pio.rs | 60 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_hd44780.rs | 9 |
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 | ||
| 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)); |
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; | |||
| 7 | use embassy_executor::Spawner; | 7 | use embassy_executor::Spawner; |
| 8 | use embassy_rp::dma::{AnyChannel, Channel}; | 8 | use embassy_rp::dma::{AnyChannel, Channel}; |
| 9 | use embassy_rp::peripherals::PIO0; | 9 | use embassy_rp::peripherals::PIO0; |
| 10 | use embassy_rp::pio::{FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; | 10 | use embassy_rp::pio::{Direction, FifoJoin, Pio, PioPin, ShiftDirection, StateMachine}; |
| 11 | use embassy_rp::pwm::{Config, Pwm}; | 11 | use embassy_rp::pwm::{Config, Pwm}; |
| 12 | use embassy_rp::relocate::RelocatedProgram; | 12 | use embassy_rp::relocate::RelocatedProgram; |
| 13 | use embassy_rp::{into_ref, Peripheral, PeripheralRef}; | 13 | use 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]); |
