use pio instruction encoding apis

This commit is contained in:
Gus Caplan 2021-09-15 11:34:07 -05:00 committed by 9names
parent b399c96cf5
commit 833b69819e

View file

@ -140,21 +140,35 @@ impl<P: Instance> PIO<P> {
} }
} }
fn add_program(&self, instructions: &[u16], origin: Option<u8>) -> Option<usize> { fn add_program(
&self,
instructions: &[u16],
origin: Option<u8>,
side_set: pio::SideSet,
) -> Option<usize> {
if let Some(offset) = self.find_offset_for_instructions(instructions, origin) { if let Some(offset) = self.find_offset_for_instructions(instructions, origin) {
for (i, instr) in instructions.iter().enumerate() { for (i, instr) in instructions
let instr = if instr & 0xe000 != 0 { .iter()
*instr .map(|instr| {
} else { let mut instr = pio::Instruction::decode(*instr, side_set).unwrap();
instr.operands = match instr.operands {
pio::InstructionOperands::JMP { condition, address } => {
// JMP instruction. We need to apply offset here // JMP instruction. We need to apply offset here
let address = instr & 0x001f; let address = address + offset as u8;
assert!( assert!(
address + (offset as u16) <= 0x001f, address < pio::RP2040_MAX_PROGRAM_SIZE as u8,
"Invalid JMP out of the program after offset addition" "Invalid JMP out of the program after offset addition"
); );
instr + offset as u16 pio::InstructionOperands::JMP { condition, address }
}
_ => instr.operands,
}; };
instr.encode(side_set)
})
.enumerate()
{
self.pio.instr_mem[i + offset].write(|w| unsafe { w.bits(instr as u32) }) self.pio.instr_mem[i + offset].write(|w| unsafe { w.bits(instr as u32) })
} }
self.used_instruction_space self.used_instruction_space
@ -800,7 +814,8 @@ impl<'a> PIOBuilder<'a> {
/// Build the config and deploy it to a StateMachine. /// Build the config and deploy it to a StateMachine.
pub fn build<P: Instance>(self, pio: &PIO<P>, sm: &StateMachine<P>) -> Result<(), BuildError> { pub fn build<P: Instance>(self, pio: &PIO<P>, sm: &StateMachine<P>) -> Result<(), BuildError> {
let offset = match pio.add_program(self.instructions, self.instruction_origin) { let offset =
match pio.add_program(self.instructions, self.instruction_origin, self.side_set) {
Some(o) => o, Some(o) => o,
None => return Err(BuildError::NoSpace), None => return Err(BuildError::NoSpace),
}; };
@ -898,10 +913,13 @@ impl<'a> PIOBuilder<'a> {
// Set starting location by setting the state machine to execute a jmp // Set starting location by setting the state machine to execute a jmp
// to the beginning of the program we loaded in. // to the beginning of the program we loaded in.
#[allow(clippy::unusual_byte_groupings)] sm.set_instruction(
let mut instr = 0b000_00000_000_00000; // JMP 0 pio::InstructionOperands::JMP {
instr |= offset as u16; condition: pio::JmpCondition::Always,
sm.set_instruction(instr); address: offset as u8,
}
.encode(),
);
// Enable SM // Enable SM
sm.set_enabled(true); sm.set_enabled(true);