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.
This commit is contained in:
parent
41ec4170a5
commit
37b460637d
@ -13,7 +13,7 @@ use pio::{SideSet, Wrap};
|
|||||||
|
|
||||||
use crate::dma::{Channel, Transfer, Word};
|
use crate::dma::{Channel, Transfer, Word};
|
||||||
use crate::gpio::sealed::Pin as SealedPin;
|
use crate::gpio::sealed::Pin as SealedPin;
|
||||||
use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate};
|
use crate::gpio::{self, AnyPin, Drive, Level, Pull, SlewRate};
|
||||||
use crate::pac::dma::vals::TreqSel;
|
use crate::pac::dma::vals::TreqSel;
|
||||||
use crate::relocate::RelocatedProgram;
|
use crate::relocate::RelocatedProgram;
|
||||||
use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt};
|
use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt};
|
||||||
@ -54,6 +54,14 @@ pub enum ShiftDirection {
|
|||||||
Left = 0,
|
Left = 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
|
||||||
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
|
#[repr(u8)]
|
||||||
|
pub enum Direction {
|
||||||
|
In = 0,
|
||||||
|
Out = 1,
|
||||||
|
}
|
||||||
|
|
||||||
const RXNEMPTY_MASK: u32 = 1 << 0;
|
const RXNEMPTY_MASK: u32 = 1 << 0;
|
||||||
const TXNFULL_MASK: u32 = 1 << 4;
|
const TXNFULL_MASK: u32 = 1 << 4;
|
||||||
const SMIRQ_MASK: u32 = 1 << 8;
|
const SMIRQ_MASK: u32 = 1 << 8;
|
||||||
@ -533,6 +541,56 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_paused(&mut self, f: impl FnOnce(&mut Self)) {
|
||||||
|
let enabled = self.is_enabled();
|
||||||
|
self.set_enable(false);
|
||||||
|
let pincfg = unsafe { Self::this_sm().pinctrl().read() };
|
||||||
|
let execcfg = unsafe { Self::this_sm().execctrl().read() };
|
||||||
|
unsafe {
|
||||||
|
Self::this_sm().execctrl().write_clear(|w| w.set_out_sticky(true));
|
||||||
|
}
|
||||||
|
f(self);
|
||||||
|
unsafe {
|
||||||
|
Self::this_sm().pinctrl().write_value(pincfg);
|
||||||
|
Self::this_sm().execctrl().write_value(execcfg);
|
||||||
|
}
|
||||||
|
self.set_enable(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets pin directions. This pauses the current state machine to run `SET` commands
|
||||||
|
/// and temporarily unsets the `OUT_STICKY` bit.
|
||||||
|
pub fn set_pin_dirs(&mut self, dir: Direction, pins: &[&Pin<'d, PIO>]) {
|
||||||
|
self.with_paused(|sm| {
|
||||||
|
for pin in pins {
|
||||||
|
unsafe {
|
||||||
|
Self::this_sm().pinctrl().write(|w| {
|
||||||
|
w.set_set_base(pin.pin());
|
||||||
|
w.set_set_count(1);
|
||||||
|
});
|
||||||
|
// SET PINDIRS, (dir)
|
||||||
|
sm.exec_instr(0b111_00000_100_00000 | dir as u16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sets pin output values. This pauses the current state machine to run
|
||||||
|
/// `SET` commands and temporarily unsets the `OUT_STICKY` bit.
|
||||||
|
pub fn set_pins(&mut self, level: Level, pins: &[&Pin<'d, PIO>]) {
|
||||||
|
self.with_paused(|sm| {
|
||||||
|
for pin in pins {
|
||||||
|
unsafe {
|
||||||
|
Self::this_sm().pinctrl().write(|w| {
|
||||||
|
w.set_set_base(pin.pin());
|
||||||
|
w.set_set_count(1);
|
||||||
|
});
|
||||||
|
// SET PINS, (dir)
|
||||||
|
sm.exec_instr(0b111_00000_000_00000 | level as u16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_jmp_pin(&mut self, pin: u8) {
|
pub fn set_jmp_pin(&mut self, pin: u8) {
|
||||||
unsafe {
|
unsafe {
|
||||||
Self::this_sm().execctrl().modify(|w| w.set_jmp_pin(pin));
|
Self::this_sm().execctrl().modify(|w| w.set_jmp_pin(pin));
|
||||||
|
@ -7,7 +7,7 @@ use core::fmt::Write;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::dma::{AnyChannel, Channel};
|
use embassy_rp::dma::{AnyChannel, Channel};
|
||||||
use embassy_rp::peripherals::PIO0;
|
use embassy_rp::peripherals::PIO0;
|
||||||
use embassy_rp::pio::{FifoJoin, Pio, PioPin, ShiftDirection, StateMachine};
|
use embassy_rp::pio::{Direction, FifoJoin, Pio, PioPin, ShiftDirection, StateMachine};
|
||||||
use embassy_rp::pwm::{Config, Pwm};
|
use embassy_rp::pwm::{Config, Pwm};
|
||||||
use embassy_rp::relocate::RelocatedProgram;
|
use embassy_rp::relocate::RelocatedProgram;
|
||||||
use embassy_rp::{into_ref, Peripheral, PeripheralRef};
|
use embassy_rp::{into_ref, Peripheral, PeripheralRef};
|
||||||
@ -115,12 +115,7 @@ impl<'l> HD44780<'l> {
|
|||||||
let db6 = common.make_pio_pin(db6);
|
let db6 = common.make_pio_pin(db6);
|
||||||
let db7 = common.make_pio_pin(db7);
|
let db7 = common.make_pio_pin(db7);
|
||||||
|
|
||||||
sm0.set_set_pins(&[&rs, &rw]);
|
sm0.set_pin_dirs(Direction::Out, &[&rs, &rw, &e, &db4, &db5, &db6, &db7]);
|
||||||
embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11);
|
|
||||||
sm0.set_set_pins(&[&e]);
|
|
||||||
embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b1);
|
|
||||||
sm0.set_set_pins(&[&db4, &db5, &db6, &db7]);
|
|
||||||
embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11111);
|
|
||||||
|
|
||||||
let relocated = RelocatedProgram::new(&prg.program);
|
let relocated = RelocatedProgram::new(&prg.program);
|
||||||
sm0.use_program(&common.load_program(&relocated), &[&e]);
|
sm0.use_program(&common.load_program(&relocated), &[&e]);
|
||||||
|
Loading…
Reference in New Issue
Block a user