diff options
| author | pennae <[email protected]> | 2023-05-06 20:53:06 +0200 |
|---|---|---|
| committer | pennae <[email protected]> | 2023-05-06 21:08:20 +0200 |
| commit | b38d496d519f87d7f455e6c6b32f5d6379af44a5 (patch) | |
| tree | 68d682e82887b33e910dda7b37cf7f8e4957a257 | |
| parent | 374c7513f905fcbf353bee2987e78d68fe8ea303 (diff) | |
rp/pio: allow wrap-around program loading
execution wraps around after the end of instruction memory and wrapping
works with this, so we may as well allow program loading across this
boundary. could be useful for reusing chunks of instruction memory.
| -rw-r--r-- | embassy-rp/src/pio.rs | 11 | ||||
| -rw-r--r-- | embassy-rp/src/relocate.rs | 10 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_hd44780.rs | 3 |
3 files changed, 11 insertions, 13 deletions
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index 5fed4f1fa..fe66d9aef 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs | |||
| @@ -855,13 +855,14 @@ impl<'d, PIO: Instance> Common<'d, PIO> { | |||
| 855 | { | 855 | { |
| 856 | let mut used_mask = 0; | 856 | let mut used_mask = 0; |
| 857 | for (i, instr) in instrs.enumerate() { | 857 | for (i, instr) in instrs.enumerate() { |
| 858 | let addr = (i + start) as u8; | 858 | // wrapping around the end of program memory is valid, let's make use of that. |
| 859 | let mask = 1 << (addr as usize); | 859 | let addr = (i + start) % 32; |
| 860 | if self.instructions_used & mask != 0 { | 860 | let mask = 1 << addr; |
| 861 | return Err(addr as usize); | 861 | if (self.instructions_used | used_mask) & mask != 0 { |
| 862 | return Err(addr); | ||
| 862 | } | 863 | } |
| 863 | unsafe { | 864 | unsafe { |
| 864 | PIO::PIO.instr_mem(addr as usize).write(|w| { | 865 | PIO::PIO.instr_mem(addr).write(|w| { |
| 865 | w.set_instr_mem(instr); | 866 | w.set_instr_mem(instr); |
| 866 | }); | 867 | }); |
| 867 | } | 868 | } |
diff --git a/embassy-rp/src/relocate.rs b/embassy-rp/src/relocate.rs index f36170e03..9cb279ccd 100644 --- a/embassy-rp/src/relocate.rs +++ b/embassy-rp/src/relocate.rs | |||
| @@ -26,11 +26,7 @@ where | |||
| 26 | Some(if instr & 0b1110_0000_0000_0000 == 0 { | 26 | Some(if instr & 0b1110_0000_0000_0000 == 0 { |
| 27 | // this is a JMP instruction -> add offset to address | 27 | // this is a JMP instruction -> add offset to address |
| 28 | let address = (instr & 0b1_1111) as u8; | 28 | let address = (instr & 0b1_1111) as u8; |
| 29 | let address = address + self.offset; | 29 | let address = address.wrapping_add(self.offset) % 32; |
| 30 | assert!( | ||
| 31 | address < pio::RP2040_MAX_PROGRAM_SIZE as u8, | ||
| 32 | "Invalid JMP out of the program after offset addition" | ||
| 33 | ); | ||
| 34 | instr & (!0b11111) | address as u16 | 30 | instr & (!0b11111) | address as u16 |
| 35 | } else { | 31 | } else { |
| 36 | instr | 32 | instr |
| @@ -62,8 +58,8 @@ impl<'a, const PROGRAM_SIZE: usize> RelocatedProgram<'a, PROGRAM_SIZE> { | |||
| 62 | let wrap = self.program.wrap; | 58 | let wrap = self.program.wrap; |
| 63 | let origin = self.origin; | 59 | let origin = self.origin; |
| 64 | Wrap { | 60 | Wrap { |
| 65 | source: wrap.source + origin, | 61 | source: wrap.source.wrapping_add(origin) % 32, |
| 66 | target: wrap.target + origin, | 62 | target: wrap.target.wrapping_add(origin) % 32, |
| 67 | } | 63 | } |
| 68 | } | 64 | } |
| 69 | 65 | ||
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 61c5565d3..088fd5649 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs | |||
| @@ -95,6 +95,7 @@ impl<'l> HD44780<'l> { | |||
| 95 | let prg = pio_proc::pio_asm!( | 95 | let prg = pio_proc::pio_asm!( |
| 96 | r#" | 96 | r#" |
| 97 | .side_set 1 opt | 97 | .side_set 1 opt |
| 98 | .origin 20 | ||
| 98 | 99 | ||
| 99 | loop: | 100 | loop: |
| 100 | out x, 24 | 101 | out x, 24 |
| @@ -148,7 +149,7 @@ impl<'l> HD44780<'l> { | |||
| 148 | // many side sets are only there to free up a delay bit! | 149 | // many side sets are only there to free up a delay bit! |
| 149 | let prg = pio_proc::pio_asm!( | 150 | let prg = pio_proc::pio_asm!( |
| 150 | r#" | 151 | r#" |
| 151 | .origin 7 | 152 | .origin 27 |
| 152 | .side_set 1 | 153 | .side_set 1 |
| 153 | 154 | ||
| 154 | .wrap_target | 155 | .wrap_target |
