Skip to content

Commit

Permalink
Merge pull request #66 from CBJamo/main
Browse files Browse the repository at this point in the history
RP235x support
  • Loading branch information
jannic authored Jan 11, 2025
2 parents c92f324 + 3bae675 commit fa58644
Show file tree
Hide file tree
Showing 4 changed files with 434 additions and 83 deletions.
164 changes: 149 additions & 15 deletions pio-parser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
#![allow(clippy::upper_case_acronyms)]

use pio::{
InSource, Instruction, InstructionOperands, JmpCondition, MovDestination, MovOperation,
MovSource, OutDestination, ProgramWithDefines, SetDestination, WaitSource,
InSource, Instruction, InstructionOperands, IrqIndexMode, JmpCondition, MovDestination,
MovOperation, MovRxIndex, MovSource, OutDestination, ProgramWithDefines, SetDestination,
WaitSource,
};

use std::collections::HashMap;
Expand All @@ -28,7 +29,7 @@ pub(crate) enum Value<'input> {
Rev(Box<Value<'input>>),
}

impl<'i> Value<'i> {
impl Value<'_> {
fn reify(&self, state: &ProgramState) -> i32 {
match self {
Value::I32(v) => *v,
Expand Down Expand Up @@ -76,7 +77,7 @@ pub(crate) struct ParsedInstruction<'input> {
delay: Value<'input>,
}

impl<'i> ParsedInstruction<'i> {
impl ParsedInstruction<'_> {
fn reify(&self, state: &ProgramState) -> Instruction {
Instruction {
operands: self.operands.reify(state),
Expand All @@ -86,6 +87,90 @@ impl<'i> ParsedInstruction<'i> {
}
}

#[derive(Clone, Copy, Debug)]
pub(crate) enum ParsedMovDestination {
PINS,
X,
Y,
PINDIRS,
EXEC,
PC,
ISR,
OSR,
RXFIFOY,
RXFIFO0,
RXFIFO1,
RXFIFO2,
RXFIFO3,
}

#[derive(Debug)]
enum MovDestInternal {
Mov(MovDestination),
Fifo(MovRxIndex),
}

impl From<ParsedMovDestination> for MovDestInternal {
fn from(value: ParsedMovDestination) -> Self {
match value {
ParsedMovDestination::PINS => MovDestInternal::Mov(MovDestination::PINS),
ParsedMovDestination::X => MovDestInternal::Mov(MovDestination::X),
ParsedMovDestination::Y => MovDestInternal::Mov(MovDestination::Y),
ParsedMovDestination::PINDIRS => MovDestInternal::Mov(MovDestination::PINDIRS),
ParsedMovDestination::EXEC => MovDestInternal::Mov(MovDestination::EXEC),
ParsedMovDestination::PC => MovDestInternal::Mov(MovDestination::PC),
ParsedMovDestination::ISR => MovDestInternal::Mov(MovDestination::ISR),
ParsedMovDestination::OSR => MovDestInternal::Mov(MovDestination::OSR),
ParsedMovDestination::RXFIFOY => MovDestInternal::Fifo(MovRxIndex::RXFIFOY),
ParsedMovDestination::RXFIFO0 => MovDestInternal::Fifo(MovRxIndex::RXFIFO0),
ParsedMovDestination::RXFIFO1 => MovDestInternal::Fifo(MovRxIndex::RXFIFO1),
ParsedMovDestination::RXFIFO2 => MovDestInternal::Fifo(MovRxIndex::RXFIFO2),
ParsedMovDestination::RXFIFO3 => MovDestInternal::Fifo(MovRxIndex::RXFIFO3),
}
}
}

#[derive(Clone, Copy, Debug)]
pub(crate) enum ParsedMovSource {
PINS,
X,
Y,
NULL,
STATUS,
ISR,
OSR,
RXFIFOY,
RXFIFO0,
RXFIFO1,
RXFIFO2,
RXFIFO3,
}

#[derive(Debug)]
enum MovSrcInternal {
Mov(MovSource),
Fifo(MovRxIndex),
}

impl From<ParsedMovSource> for MovSrcInternal {
fn from(value: ParsedMovSource) -> Self {
match value {
ParsedMovSource::PINS => MovSrcInternal::Mov(MovSource::PINS),
ParsedMovSource::X => MovSrcInternal::Mov(MovSource::X),
ParsedMovSource::Y => MovSrcInternal::Mov(MovSource::Y),
ParsedMovSource::NULL => MovSrcInternal::Mov(MovSource::NULL),
ParsedMovSource::STATUS => MovSrcInternal::Mov(MovSource::STATUS),
ParsedMovSource::ISR => MovSrcInternal::Mov(MovSource::ISR),
ParsedMovSource::OSR => MovSrcInternal::Mov(MovSource::OSR),
ParsedMovSource::RXFIFOY => MovSrcInternal::Fifo(MovRxIndex::RXFIFOY),
ParsedMovSource::RXFIFO0 => MovSrcInternal::Fifo(MovRxIndex::RXFIFO0),
ParsedMovSource::RXFIFO1 => MovSrcInternal::Fifo(MovRxIndex::RXFIFO1),
ParsedMovSource::RXFIFO2 => MovSrcInternal::Fifo(MovRxIndex::RXFIFO2),
ParsedMovSource::RXFIFO3 => MovSrcInternal::Fifo(MovRxIndex::RXFIFO3),
}
}
}

#[derive(Debug)]
pub(crate) enum ParsedOperands<'input> {
JMP {
Expand Down Expand Up @@ -115,23 +200,23 @@ pub(crate) enum ParsedOperands<'input> {
block: bool,
},
MOV {
destination: MovDestination,
destination: ParsedMovDestination,
op: MovOperation,
source: MovSource,
source: ParsedMovSource,
},
IRQ {
clear: bool,
wait: bool,
index: Value<'input>,
relative: bool,
index_mode: IrqIndexMode,
},
SET {
destination: SetDestination,
data: Value<'input>,
},
}

impl<'i> ParsedOperands<'i> {
impl ParsedOperands<'_> {
fn reify(&self, state: &ProgramState) -> InstructionOperands {
match self {
ParsedOperands::JMP { condition, address } => InstructionOperands::JMP {
Expand Down Expand Up @@ -172,21 +257,35 @@ impl<'i> ParsedOperands<'i> {
destination,
op,
source,
} => InstructionOperands::MOV {
destination: *destination,
op: *op,
source: *source,
},
} => {
let source_internal = (*source).into();
let dest_internal = (*destination).into();
match (source_internal, dest_internal) {
(MovSrcInternal::Mov(MovSource::ISR), MovDestInternal::Fifo(fifo_index)) => {
InstructionOperands::MOVTORX { fifo_index }
}
(
MovSrcInternal::Fifo(fifo_index),
MovDestInternal::Mov(MovDestination::OSR),
) => InstructionOperands::MOVFROMRX { fifo_index },
(MovSrcInternal::Mov(s), MovDestInternal::Mov(d)) => InstructionOperands::MOV {
destination: d,
op: *op,
source: s,
},
(d, s) => panic!("Illegal Mov src/dest combination: {:?} {:?}", d, s),
}
}
ParsedOperands::IRQ {
clear,
wait,
index,
relative,
index_mode,
} => InstructionOperands::IRQ {
clear: *clear,
wait: *wait,
index: index.reify(state) as u8,
relative: *relative,
index_mode: *index_mode,
},
ParsedOperands::SET { destination, data } => InstructionOperands::SET {
destination: *destination,
Expand Down Expand Up @@ -426,6 +525,41 @@ fn test() {
);
}

#[test]
fn test_rp2350() {
let p = Parser::<32>::parse_program(
"
label:
mov osr, rxfifo[0]
mov rxfifo[1], isr
mov pins, isr
mov osr, x
jmp label
",
)
.unwrap();

assert_eq!(
&p.program.code[..],
&[
// LABEL:
0b100_00000_1001_1_000, // MOV OSR, RXFIFO0
0b100_00000_0001_1_001, // MOV RXFIFO1, ISR
0b101_00000_000_00_110, // MOV PINS, ISR
0b101_00000_111_00_001, // MOV OSR, X
0b000_00000_000_00000, // JMP LABEL
]
);
assert_eq!(p.program.origin, None);
assert_eq!(
p.program.wrap,
pio::Wrap {
source: 4,
target: 0,
}
);
}

#[test]
fn test_side_set() {
let p = Parser::<32>::parse_program(
Expand Down
65 changes: 44 additions & 21 deletions pio-parser/src/pio.lalrpop
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,16 @@ use ::pio::{
MovOperation,
MovSource,
SetDestination,
IrqIndexMode,
};
use crate::{
Line,
Value,
ParsedDirective,
ParsedInstruction,
ParsedOperands,
ParsedMovSource,
ParsedMovDestination,
};

grammar();
Expand Down Expand Up @@ -139,9 +142,9 @@ Instruction: ParsedInstruction<'input> = {

BaseInstruction: ParsedOperands<'input> = {
"nop" => ParsedOperands::MOV {
destination: MovDestination::Y,
destination: ParsedMovDestination::Y,
op: MovOperation::None,
source: MovSource::Y,
source: ParsedMovSource::Y,
},
"jmp" <c:JmpCondition?> ","? <e:Expression> => ParsedOperands::JMP {
condition: match c {
Expand Down Expand Up @@ -178,15 +181,15 @@ BaseInstruction: ParsedOperands<'input> = {
None => true,
},
},
"mov" <d:MovDestination> ","? <o:MovOperation?> <s:MovSource> => ParsedOperands::MOV {
"mov" <d:ParsedMovDestination> ","? <o:MovOperation?> <s:ParsedMovSource> => ParsedOperands::MOV {
destination: d,
op: match o {
Some(o) => o,
None => MovOperation::None,
},
source: s,
},
"irq" <m:IrqModifier?> <v:Value> <r:"rel"?> => ParsedOperands::IRQ {
"irq" <m:IrqModifier?> <v:Value> <r:IrqIndexMode?> => ParsedOperands::IRQ {
clear: match m {
Some(m) => m.0,
None => false,
Expand All @@ -196,7 +199,10 @@ BaseInstruction: ParsedOperands<'input> = {
None => false,
},
index: v,
relative: r.is_some(),
index_mode: match r {
Some(m) => m,
None => IrqIndexMode::DIRECT
}
},
"set" <d:SetDestination> ","? <v:Value> => ParsedOperands::SET {
destination: d,
Expand Down Expand Up @@ -245,14 +251,20 @@ ShouldBlock: bool = {
"noblock" => false,
};

MovDestination: MovDestination = {
"pins" => MovDestination::PINS,
"x" => MovDestination::X,
"y" => MovDestination::Y,
"exec" => MovDestination::EXEC,
"pc" => MovDestination::PC,
"isr" => MovDestination::ISR,
"osr" => MovDestination::OSR,
ParsedMovDestination: ParsedMovDestination = {
"pins" => ParsedMovDestination::PINS,
"x" => ParsedMovDestination::X,
"y" => ParsedMovDestination::Y,
"pindirs" => ParsedMovDestination::PINDIRS,
"exec" => ParsedMovDestination::EXEC,
"pc" => ParsedMovDestination::PC,
"isr" => ParsedMovDestination::ISR,
"osr" => ParsedMovDestination::OSR,
"rxfifo[y]" => ParsedMovDestination::RXFIFOY,
"rxfifo[0]" => ParsedMovDestination::RXFIFO0,
"rxfifo[1]" => ParsedMovDestination::RXFIFO1,
"rxfifo[2]" => ParsedMovDestination::RXFIFO2,
"rxfifo[3]" => ParsedMovDestination::RXFIFO3,
};

MovOperation: MovOperation = {
Expand All @@ -261,14 +273,19 @@ MovOperation: MovOperation = {
"::" => MovOperation::BitReverse,
};

MovSource: MovSource = {
"pins" => MovSource::PINS,
"x" => MovSource::X,
"y" => MovSource::Y,
"null" => MovSource::NULL,
"status" => MovSource::STATUS,
"isr" => MovSource::ISR,
"osr" => MovSource::OSR,
ParsedMovSource: ParsedMovSource = {
"pins" => ParsedMovSource::PINS,
"x" => ParsedMovSource::X,
"y" => ParsedMovSource::Y,
"null" => ParsedMovSource::NULL,
"status" => ParsedMovSource::STATUS,
"isr" => ParsedMovSource::ISR,
"osr" => ParsedMovSource::OSR,
"rxfifo[y]" => ParsedMovSource::RXFIFOY,
"rxfifo[0]" => ParsedMovSource::RXFIFO0,
"rxfifo[1]" => ParsedMovSource::RXFIFO1,
"rxfifo[2]" => ParsedMovSource::RXFIFO2,
"rxfifo[3]" => ParsedMovSource::RXFIFO3,
};

IrqModifier: (bool, bool) = {
Expand All @@ -278,6 +295,12 @@ IrqModifier: (bool, bool) = {
"clear" => (true, false),
};

IrqIndexMode: IrqIndexMode = {
"prev" => IrqIndexMode::PREV,
"rel" => IrqIndexMode::REL,
"next" => IrqIndexMode::NEXT,
}

SetDestination: SetDestination = {
"pins" => SetDestination::PINS,
"x" => SetDestination::X,
Expand Down
4 changes: 4 additions & 0 deletions pio-proc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ fn to_codegen(
)
.parse()
.unwrap();
let version: proc_macro2::TokenStream = format!("::pio::PioVersion::{:?}", program.version)
.parse()
.unwrap();
let defines_struct: proc_macro2::TokenStream = format!(
"
struct ExpandedDefines {{
Expand Down Expand Up @@ -387,6 +390,7 @@ fn to_codegen(
origin: #origin,
wrap: #wrap,
side_set: #side_set,
version: #version,
},
public_defines: #defines_init,
}
Expand Down
Loading

0 comments on commit fa58644

Please sign in to comment.