rp/pio: make PioCommon a struct
the PioCommon trait does not serve much of a purpose; there can be only two implementations and they only differ in a few associated constants.
This commit is contained in:
parent
8839f3f62a
commit
a167c77d39
@ -792,7 +792,7 @@ pub trait PioStateMachine: sealed::PioStateMachine + Sized + Unpin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PioCommonInstance<'d, PIO: PioInstance> {
|
pub struct PioCommon<'d, PIO: PioInstance> {
|
||||||
instructions_used: u32,
|
instructions_used: u32,
|
||||||
pio: PhantomData<&'d PIO>,
|
pio: PhantomData<&'d PIO>,
|
||||||
}
|
}
|
||||||
@ -802,11 +802,8 @@ pub struct PioInstanceMemory<'d, PIO: PioInstance> {
|
|||||||
pio: PhantomData<&'d PIO>,
|
pio: PhantomData<&'d PIO>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, PIO: PioInstance> sealed::PioCommon for PioCommonInstance<'d, PIO> {
|
impl<'d, PIO: PioInstance> PioCommon<'d, PIO> {
|
||||||
type Pio = PIO;
|
pub fn write_instr<I>(&mut self, start: usize, instrs: I) -> PioInstanceMemory<'d, PIO>
|
||||||
}
|
|
||||||
impl<'d, PIO: PioInstance> PioCommon for PioCommonInstance<'d, PIO> {
|
|
||||||
fn write_instr<I>(&mut self, start: usize, instrs: I) -> PioInstanceMemory<'d, Self::Pio>
|
|
||||||
where
|
where
|
||||||
I: Iterator<Item = u16>,
|
I: Iterator<Item = u16>,
|
||||||
{
|
{
|
||||||
@ -833,58 +830,50 @@ impl<'d, PIO: PioInstance> PioCommon for PioCommonInstance<'d, PIO> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn free_instr(&mut self, instrs: PioInstanceMemory<Self::Pio>) {
|
// TODO make instruction memory that is currently in use unfreeable
|
||||||
|
pub fn free_instr(&mut self, instrs: PioInstanceMemory<PIO>) {
|
||||||
self.instructions_used &= !instrs.used_mask;
|
self.instructions_used &= !instrs.used_mask;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PioCommon: sealed::PioCommon + Sized {
|
pub fn is_irq_set(&self, irq_no: u8) -> bool {
|
||||||
fn write_instr<I>(&mut self, start: usize, instrs: I) -> PioInstanceMemory<Self::Pio>
|
|
||||||
where
|
|
||||||
I: Iterator<Item = u16>;
|
|
||||||
|
|
||||||
// TODO make instruction memory that is currently in use unfreeable
|
|
||||||
fn free_instr(&mut self, instrs: PioInstanceMemory<Self::Pio>);
|
|
||||||
|
|
||||||
fn is_irq_set(&self, irq_no: u8) -> bool {
|
|
||||||
assert!(irq_no < 8);
|
assert!(irq_no < 8);
|
||||||
unsafe {
|
unsafe {
|
||||||
let irq_flags = Self::Pio::PIO.irq();
|
let irq_flags = PIO::PIO.irq();
|
||||||
irq_flags.read().0 & (1 << irq_no) != 0
|
irq_flags.read().0 & (1 << irq_no) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_irq(&mut self, irq_no: usize) {
|
pub fn clear_irq(&mut self, irq_no: usize) {
|
||||||
assert!(irq_no < 8);
|
assert!(irq_no < 8);
|
||||||
unsafe { Self::Pio::PIO.irq().write(|w| w.set_irq(1 << irq_no)) }
|
unsafe { PIO::PIO.irq().write(|w| w.set_irq(1 << irq_no)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_irqs(&mut self, mask: u8) {
|
pub fn clear_irqs(&mut self, mask: u8) {
|
||||||
unsafe { Self::Pio::PIO.irq().write(|w| w.set_irq(mask)) }
|
unsafe { PIO::PIO.irq().write(|w| w.set_irq(mask)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn force_irq(&mut self, irq_no: usize) {
|
pub fn force_irq(&mut self, irq_no: usize) {
|
||||||
assert!(irq_no < 8);
|
assert!(irq_no < 8);
|
||||||
unsafe { Self::Pio::PIO.irq_force().write(|w| w.set_irq_force(1 << irq_no)) }
|
unsafe { PIO::PIO.irq_force().write(|w| w.set_irq_force(1 << irq_no)) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) {
|
pub fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
// this can interfere with per-pin bypass functions. splitting the
|
// this can interfere with per-pin bypass functions. splitting the
|
||||||
// modification is going to be fine since nothing that relies on
|
// modification is going to be fine since nothing that relies on
|
||||||
// it can reasonably run before we finish.
|
// it can reasonably run before we finish.
|
||||||
Self::Pio::PIO.input_sync_bypass().write_set(|w| *w = mask & bypass);
|
PIO::PIO.input_sync_bypass().write_set(|w| *w = mask & bypass);
|
||||||
Self::Pio::PIO.input_sync_bypass().write_clear(|w| *w = mask & !bypass);
|
PIO::PIO.input_sync_bypass().write_clear(|w| *w = mask & !bypass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_input_sync_bypass(&self) -> u32 {
|
pub fn get_input_sync_bypass(&self) -> u32 {
|
||||||
unsafe { Self::Pio::PIO.input_sync_bypass().read() }
|
unsafe { PIO::PIO.input_sync_bypass().read() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_pio_pin(&self, pin: impl Pin) -> PioPin<Self::Pio> {
|
pub fn make_pio_pin(&self, pin: impl Pin) -> PioPin<PIO> {
|
||||||
unsafe {
|
unsafe {
|
||||||
pin.io().ctrl().write(|w| w.set_funcsel(Self::Pio::FUNCSEL.0));
|
pin.io().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL.0));
|
||||||
}
|
}
|
||||||
PioPin {
|
PioPin {
|
||||||
pin_bank: pin.pin_bank(),
|
pin_bank: pin.pin_bank(),
|
||||||
@ -904,7 +893,7 @@ impl<const SM_NO: u8> sealed::SmInstance for SmInstanceBase<SM_NO> {
|
|||||||
impl<const SM_NO: u8> SmInstance for SmInstanceBase<SM_NO> {}
|
impl<const SM_NO: u8> SmInstance for SmInstanceBase<SM_NO> {}
|
||||||
|
|
||||||
pub struct Pio<'d, PIO: PioInstance> {
|
pub struct Pio<'d, PIO: PioInstance> {
|
||||||
pub common: PioCommonInstance<'d, PIO>,
|
pub common: PioCommon<'d, PIO>,
|
||||||
pub sm0: PioStateMachineInstance<'d, PIO, SmInstanceBase<0>>,
|
pub sm0: PioStateMachineInstance<'d, PIO, SmInstanceBase<0>>,
|
||||||
pub sm1: PioStateMachineInstance<'d, PIO, SmInstanceBase<1>>,
|
pub sm1: PioStateMachineInstance<'d, PIO, SmInstanceBase<1>>,
|
||||||
pub sm2: PioStateMachineInstance<'d, PIO, SmInstanceBase<2>>,
|
pub sm2: PioStateMachineInstance<'d, PIO, SmInstanceBase<2>>,
|
||||||
@ -914,7 +903,7 @@ pub struct Pio<'d, PIO: PioInstance> {
|
|||||||
impl<'d, PIO: PioInstance> Pio<'d, PIO> {
|
impl<'d, PIO: PioInstance> Pio<'d, PIO> {
|
||||||
pub fn new(_pio: impl Peripheral<P = PIO> + 'd) -> Self {
|
pub fn new(_pio: impl Peripheral<P = PIO> + 'd) -> Self {
|
||||||
Self {
|
Self {
|
||||||
common: PioCommonInstance {
|
common: PioCommon {
|
||||||
instructions_used: 0,
|
instructions_used: 0,
|
||||||
pio: PhantomData,
|
pio: PhantomData,
|
||||||
},
|
},
|
||||||
@ -945,10 +934,6 @@ pub trait PioInstance: sealed::PioInstance + Sized + Unpin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
mod sealed {
|
mod sealed {
|
||||||
pub trait PioCommon {
|
|
||||||
type Pio: super::PioInstance;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait PioStateMachine {
|
pub trait PioStateMachine {
|
||||||
type Pio: super::PioInstance;
|
type Pio: super::PioInstance;
|
||||||
type Sm: super::SmInstance;
|
type Sm: super::SmInstance;
|
||||||
|
@ -5,14 +5,12 @@ use defmt::info;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::gpio::{AnyPin, Pin};
|
use embassy_rp::gpio::{AnyPin, Pin};
|
||||||
use embassy_rp::peripherals::PIO0;
|
use embassy_rp::peripherals::PIO0;
|
||||||
use embassy_rp::pio::{
|
use embassy_rp::pio::{Pio, PioCommon, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2};
|
||||||
Pio, PioCommon, PioCommonInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, Sm0, Sm1, Sm2,
|
|
||||||
};
|
|
||||||
use embassy_rp::pio_instr_util;
|
use embassy_rp::pio_instr_util;
|
||||||
use embassy_rp::relocate::RelocatedProgram;
|
use embassy_rp::relocate::RelocatedProgram;
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
|
||||||
fn setup_pio_task_sm0(pio: &mut PioCommonInstance<PIO0>, sm: &mut PioStateMachineInstance<PIO0, Sm0>, pin: AnyPin) {
|
fn setup_pio_task_sm0(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachineInstance<PIO0, Sm0>, pin: AnyPin) {
|
||||||
// Setup sm0
|
// Setup sm0
|
||||||
|
|
||||||
// Send data serially to pin
|
// Send data serially to pin
|
||||||
@ -51,7 +49,7 @@ async fn pio_task_sm0(mut sm: PioStateMachineInstance<'static, PIO0, Sm0>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_pio_task_sm1(pio: &mut PioCommonInstance<PIO0>, sm: &mut PioStateMachineInstance<PIO0, Sm1>) {
|
fn setup_pio_task_sm1(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachineInstance<PIO0, Sm1>) {
|
||||||
// Setupm sm1
|
// Setupm sm1
|
||||||
|
|
||||||
// Read 0b10101 repeatedly until ISR is full
|
// Read 0b10101 repeatedly until ISR is full
|
||||||
@ -78,7 +76,7 @@ async fn pio_task_sm1(mut sm: PioStateMachineInstance<'static, PIO0, Sm1>) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_pio_task_sm2(pio: &mut PioCommonInstance<PIO0>, sm: &mut PioStateMachineInstance<PIO0, Sm2>) {
|
fn setup_pio_task_sm2(pio: &mut PioCommon<PIO0>, sm: &mut PioStateMachineInstance<PIO0, Sm2>) {
|
||||||
// Setup sm2
|
// Setup sm2
|
||||||
|
|
||||||
// Repeatedly trigger IRQ 3
|
// Repeatedly trigger IRQ 3
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
use defmt::info;
|
use defmt::info;
|
||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_futures::join::join;
|
use embassy_futures::join::join;
|
||||||
use embassy_rp::pio::{Pio, PioCommon, PioStateMachine, ShiftDirection};
|
use embassy_rp::pio::{Pio, PioStateMachine, ShiftDirection};
|
||||||
use embassy_rp::relocate::RelocatedProgram;
|
use embassy_rp::relocate::RelocatedProgram;
|
||||||
use embassy_rp::{pio_instr_util, Peripheral};
|
use embassy_rp::{pio_instr_util, Peripheral};
|
||||||
use {defmt_rtt as _, panic_probe as _};
|
use {defmt_rtt as _, panic_probe as _};
|
||||||
|
@ -8,9 +8,7 @@ use embassy_executor::Spawner;
|
|||||||
use embassy_rp::dma::{AnyChannel, Channel};
|
use embassy_rp::dma::{AnyChannel, Channel};
|
||||||
use embassy_rp::gpio::Pin;
|
use embassy_rp::gpio::Pin;
|
||||||
use embassy_rp::peripherals::PIO0;
|
use embassy_rp::peripherals::PIO0;
|
||||||
use embassy_rp::pio::{
|
use embassy_rp::pio::{FifoJoin, Pio, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstanceBase};
|
||||||
FifoJoin, Pio, PioCommon, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstanceBase,
|
|
||||||
};
|
|
||||||
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};
|
||||||
|
@ -6,8 +6,7 @@ use defmt::*;
|
|||||||
use embassy_executor::Spawner;
|
use embassy_executor::Spawner;
|
||||||
use embassy_rp::gpio::{self, Pin};
|
use embassy_rp::gpio::{self, Pin};
|
||||||
use embassy_rp::pio::{
|
use embassy_rp::pio::{
|
||||||
FifoJoin, Pio, PioCommon, PioCommonInstance, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection,
|
FifoJoin, Pio, PioCommon, PioInstance, PioStateMachine, PioStateMachineInstance, ShiftDirection, SmInstance,
|
||||||
SmInstance,
|
|
||||||
};
|
};
|
||||||
use embassy_rp::pio_instr_util;
|
use embassy_rp::pio_instr_util;
|
||||||
use embassy_rp::relocate::RelocatedProgram;
|
use embassy_rp::relocate::RelocatedProgram;
|
||||||
@ -19,11 +18,7 @@ pub struct Ws2812<'d, P: PioInstance, S: SmInstance> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'d, P: PioInstance, S: SmInstance> Ws2812<'d, P, S> {
|
impl<'d, P: PioInstance, S: SmInstance> Ws2812<'d, P, S> {
|
||||||
pub fn new(
|
pub fn new(mut pio: PioCommon<'d, P>, mut sm: PioStateMachineInstance<'d, P, S>, pin: gpio::AnyPin) -> Self {
|
||||||
mut pio: PioCommonInstance<'d, P>,
|
|
||||||
mut sm: PioStateMachineInstance<'d, P, S>,
|
|
||||||
pin: gpio::AnyPin,
|
|
||||||
) -> Self {
|
|
||||||
// Setup sm0
|
// Setup sm0
|
||||||
|
|
||||||
// prepare the PIO program
|
// prepare the PIO program
|
||||||
|
Loading…
Reference in New Issue
Block a user