diff options
| -rw-r--r-- | embassy-rp/src/pio.rs | 128 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_async.rs | 25 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_dma.rs | 7 | ||||
| -rw-r--r-- | examples/rp/src/bin/pio_hd44780.rs | 16 | ||||
| -rw-r--r-- | examples/rp/src/bin/ws2812-pio.rs | 13 |
5 files changed, 74 insertions, 115 deletions
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs index ea6814fb8..f835fc8d9 100644 --- a/embassy-rp/src/pio.rs +++ b/embassy-rp/src/pio.rs | |||
| @@ -9,12 +9,14 @@ use embassy_cortex_m::interrupt::{Interrupt, InterruptExt}; | |||
| 9 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; | 9 | use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; |
| 10 | use embassy_sync::waitqueue::AtomicWaker; | 10 | use embassy_sync::waitqueue::AtomicWaker; |
| 11 | use pac::io::vals::Gpio0ctrlFuncsel; | 11 | use pac::io::vals::Gpio0ctrlFuncsel; |
| 12 | use pio::{SideSet, Wrap}; | ||
| 12 | 13 | ||
| 13 | use crate::dma::{Channel, Transfer, Word}; | 14 | use crate::dma::{Channel, Transfer, Word}; |
| 14 | use crate::gpio::sealed::Pin as SealedPin; | 15 | use crate::gpio::sealed::Pin as SealedPin; |
| 15 | use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate}; | 16 | use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate}; |
| 16 | use crate::pac::dma::vals::TreqSel; | 17 | use crate::pac::dma::vals::TreqSel; |
| 17 | use crate::{interrupt, pac, peripherals, RegExt}; | 18 | use crate::relocate::RelocatedProgram; |
| 19 | use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt}; | ||
| 18 | 20 | ||
| 19 | struct Wakers([AtomicWaker; 12]); | 21 | struct Wakers([AtomicWaker; 12]); |
| 20 | 22 | ||
| @@ -460,6 +462,13 @@ impl<'d, PIO: Instance, const SM: usize> Drop for StateMachine<'d, PIO, SM> { | |||
| 460 | } | 462 | } |
| 461 | } | 463 | } |
| 462 | 464 | ||
| 465 | fn assert_consecutive<'d, PIO: Instance>(pins: &[&Pin<'d, PIO>]) { | ||
| 466 | for (p1, p2) in pins.iter().zip(pins.iter().skip(1)) { | ||
| 467 | // purposely does not allow wrap-around because we can't claim pins 30 and 31. | ||
| 468 | assert!(p1.pin() + 1 == p2.pin(), "pins must be consecutive"); | ||
| 469 | } | ||
| 470 | } | ||
| 471 | |||
| 463 | impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { | 472 | impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { |
| 464 | #[inline(always)] | 473 | #[inline(always)] |
| 465 | fn this_sm() -> crate::pac::pio::StateMachine { | 474 | fn this_sm() -> crate::pac::pio::StateMachine { |
| @@ -504,26 +513,26 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { | |||
| 504 | } | 513 | } |
| 505 | } | 514 | } |
| 506 | 515 | ||
| 507 | pub fn set_side_enable(&self, enable: bool) { | 516 | /// Configures this state machine to use the given program, including jumping to the origin |
| 508 | unsafe { | 517 | /// of the program. The state machine is not started. |
| 509 | Self::this_sm().execctrl().modify(|w| w.set_side_en(enable)); | 518 | pub fn use_program(&mut self, prog: &LoadedProgram<'d, PIO>, side_set: &[&Pin<'d, PIO>]) { |
| 510 | } | 519 | assert!((prog.side_set.bits() - prog.side_set.optional() as u8) as usize == side_set.len()); |
| 511 | } | 520 | assert_consecutive(side_set); |
| 512 | |||
| 513 | pub fn is_side_enabled(&self) -> bool { | ||
| 514 | unsafe { Self::this_sm().execctrl().read().side_en() } | ||
| 515 | } | ||
| 516 | |||
| 517 | pub fn set_side_pindir(&mut self, pindir: bool) { | ||
| 518 | unsafe { | 521 | unsafe { |
| 519 | Self::this_sm().execctrl().modify(|w| w.set_side_pindir(pindir)); | 522 | Self::this_sm().execctrl().modify(|w| { |
| 523 | w.set_side_en(prog.side_set.optional()); | ||
| 524 | w.set_side_pindir(prog.side_set.pindirs()); | ||
| 525 | w.set_wrap_bottom(prog.wrap.target); | ||
| 526 | w.set_wrap_top(prog.wrap.source); | ||
| 527 | }); | ||
| 528 | Self::this_sm().pinctrl().modify(|w| { | ||
| 529 | w.set_sideset_count(prog.side_set.bits()); | ||
| 530 | w.set_sideset_base(side_set.first().map_or(0, |p| p.pin())); | ||
| 531 | }); | ||
| 532 | pio_instr_util::exec_jmp(self, prog.origin); | ||
| 520 | } | 533 | } |
| 521 | } | 534 | } |
| 522 | 535 | ||
| 523 | pub fn is_side_pindir(&self) -> bool { | ||
| 524 | unsafe { Self::this_sm().execctrl().read().side_pindir() } | ||
| 525 | } | ||
| 526 | |||
| 527 | pub fn set_jmp_pin(&mut self, pin: u8) { | 536 | pub fn set_jmp_pin(&mut self, pin: u8) { |
| 528 | unsafe { | 537 | unsafe { |
| 529 | Self::this_sm().execctrl().modify(|w| w.set_jmp_pin(pin)); | 538 | Self::this_sm().execctrl().modify(|w| w.set_jmp_pin(pin)); |
| @@ -534,23 +543,6 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { | |||
| 534 | unsafe { Self::this_sm().execctrl().read().jmp_pin() } | 543 | unsafe { Self::this_sm().execctrl().read().jmp_pin() } |
| 535 | } | 544 | } |
| 536 | 545 | ||
| 537 | pub fn set_wrap(&self, source: u8, target: u8) { | ||
| 538 | unsafe { | ||
| 539 | Self::this_sm().execctrl().modify(|w| { | ||
| 540 | w.set_wrap_top(source); | ||
| 541 | w.set_wrap_bottom(target) | ||
| 542 | }); | ||
| 543 | } | ||
| 544 | } | ||
| 545 | |||
| 546 | /// Get wrapping addresses. Returns (source, target). | ||
| 547 | pub fn get_wrap(&self) -> (u8, u8) { | ||
| 548 | unsafe { | ||
| 549 | let r = Self::this_sm().execctrl().read(); | ||
| 550 | (r.wrap_top(), r.wrap_bottom()) | ||
| 551 | } | ||
| 552 | } | ||
| 553 | |||
| 554 | pub fn set_fifo_join(&mut self, join: FifoJoin) { | 546 | pub fn set_fifo_join(&mut self, join: FifoJoin) { |
| 555 | let (rx, tx) = match join { | 547 | let (rx, tx) = match join { |
| 556 | FifoJoin::Duplex => (false, false), | 548 | FifoJoin::Duplex => (false, false), |
| @@ -667,28 +659,6 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { | |||
| 667 | pub fn get_addr(&self) -> u8 { | 659 | pub fn get_addr(&self) -> u8 { |
| 668 | unsafe { Self::this_sm().addr().read().addr() } | 660 | unsafe { Self::this_sm().addr().read().addr() } |
| 669 | } | 661 | } |
| 670 | pub fn set_sideset_count(&mut self, count: u8) { | ||
| 671 | unsafe { | ||
| 672 | Self::this_sm().pinctrl().modify(|w| w.set_sideset_count(count)); | ||
| 673 | } | ||
| 674 | } | ||
| 675 | |||
| 676 | pub fn get_sideset_count(&self) -> u8 { | ||
| 677 | unsafe { Self::this_sm().pinctrl().read().sideset_count() } | ||
| 678 | } | ||
| 679 | |||
| 680 | pub fn set_sideset_base_pin(&mut self, base_pin: &Pin<PIO>) { | ||
| 681 | unsafe { | ||
| 682 | Self::this_sm().pinctrl().modify(|w| w.set_sideset_base(base_pin.pin())); | ||
| 683 | } | ||
| 684 | } | ||
| 685 | |||
| 686 | pub fn get_sideset_base(&self) -> u8 { | ||
| 687 | unsafe { | ||
| 688 | let r = Self::this_sm().pinctrl().read(); | ||
| 689 | r.sideset_base() | ||
| 690 | } | ||
| 691 | } | ||
| 692 | 662 | ||
| 693 | /// Set the range of out pins affected by a set instruction. | 663 | /// Set the range of out pins affected by a set instruction. |
| 694 | pub fn set_set_range(&mut self, base: u8, count: u8) { | 664 | pub fn set_set_range(&mut self, base: u8, count: u8) { |
| @@ -799,8 +769,35 @@ pub struct InstanceMemory<'d, PIO: Instance> { | |||
| 799 | pio: PhantomData<&'d mut PIO>, | 769 | pio: PhantomData<&'d mut PIO>, |
| 800 | } | 770 | } |
| 801 | 771 | ||
| 772 | pub struct LoadedProgram<'d, PIO: Instance> { | ||
| 773 | pub used_memory: InstanceMemory<'d, PIO>, | ||
| 774 | origin: u8, | ||
| 775 | wrap: Wrap, | ||
| 776 | side_set: SideSet, | ||
| 777 | } | ||
| 778 | |||
| 802 | impl<'d, PIO: Instance> Common<'d, PIO> { | 779 | impl<'d, PIO: Instance> Common<'d, PIO> { |
| 803 | pub fn write_instr<I>(&mut self, start: usize, instrs: I) -> InstanceMemory<'d, PIO> | 780 | pub fn load_program<const SIZE: usize>(&mut self, prog: &RelocatedProgram<SIZE>) -> LoadedProgram<'d, PIO> { |
| 781 | match self.try_load_program(prog) { | ||
| 782 | Ok(r) => r, | ||
| 783 | Err(at) => panic!("Trying to write already used PIO instruction memory at {}", at), | ||
| 784 | } | ||
| 785 | } | ||
| 786 | |||
| 787 | pub fn try_load_program<const SIZE: usize>( | ||
| 788 | &mut self, | ||
| 789 | prog: &RelocatedProgram<SIZE>, | ||
| 790 | ) -> Result<LoadedProgram<'d, PIO>, usize> { | ||
| 791 | let used_memory = self.try_write_instr(prog.origin() as _, prog.code())?; | ||
| 792 | Ok(LoadedProgram { | ||
| 793 | used_memory, | ||
| 794 | origin: prog.origin(), | ||
| 795 | wrap: prog.wrap(), | ||
| 796 | side_set: prog.side_set(), | ||
| 797 | }) | ||
| 798 | } | ||
| 799 | |||
| 800 | pub fn try_write_instr<I>(&mut self, start: usize, instrs: I) -> Result<InstanceMemory<'d, PIO>, usize> | ||
| 804 | where | 801 | where |
| 805 | I: Iterator<Item = u16>, | 802 | I: Iterator<Item = u16>, |
| 806 | { | 803 | { |
| @@ -808,11 +805,9 @@ impl<'d, PIO: Instance> Common<'d, PIO> { | |||
| 808 | for (i, instr) in instrs.enumerate() { | 805 | for (i, instr) in instrs.enumerate() { |
| 809 | let addr = (i + start) as u8; | 806 | let addr = (i + start) as u8; |
| 810 | let mask = 1 << (addr as usize); | 807 | let mask = 1 << (addr as usize); |
| 811 | assert!( | 808 | if self.instructions_used & mask != 0 { |
| 812 | self.instructions_used & mask == 0, | 809 | return Err(addr as usize); |
| 813 | "Trying to write already used PIO instruction memory at {}", | 810 | } |
| 814 | addr | ||
| 815 | ); | ||
| 816 | unsafe { | 811 | unsafe { |
| 817 | PIO::PIO.instr_mem(addr as usize).write(|w| { | 812 | PIO::PIO.instr_mem(addr as usize).write(|w| { |
| 818 | w.set_instr_mem(instr); | 813 | w.set_instr_mem(instr); |
| @@ -821,15 +816,14 @@ impl<'d, PIO: Instance> Common<'d, PIO> { | |||
| 821 | used_mask |= mask; | 816 | used_mask |= mask; |
| 822 | } | 817 | } |
| 823 | self.instructions_used |= used_mask; | 818 | self.instructions_used |= used_mask; |
| 824 | InstanceMemory { | 819 | Ok(InstanceMemory { |
| 825 | used_mask, | 820 | used_mask, |
| 826 | pio: PhantomData, | 821 | pio: PhantomData, |
| 827 | } | 822 | }) |
| 828 | } | 823 | } |
| 829 | 824 | ||
| 830 | /// Free instruction memory previously allocated with [`Common::write_instr`]. | 825 | /// Free instruction memory. This is always possible but unsafe if any |
| 831 | /// This is always possible but unsafe if any state machine is still using this | 826 | /// state machine is still using this bit of memory. |
| 832 | /// bit of memory. | ||
| 833 | pub unsafe fn free_instr(&mut self, instrs: InstanceMemory<PIO>) { | 827 | pub unsafe fn free_instr(&mut self, instrs: InstanceMemory<PIO>) { |
| 834 | self.instructions_used &= !instrs.used_mask; | 828 | self.instructions_used &= !instrs.used_mask; |
| 835 | } | 829 | } |
diff --git a/examples/rp/src/bin/pio_async.rs b/examples/rp/src/bin/pio_async.rs index 461ea3ff9..9f47c2316 100644 --- a/examples/rp/src/bin/pio_async.rs +++ b/examples/rp/src/bin/pio_async.rs | |||
| @@ -5,11 +5,10 @@ use defmt::info; | |||
| 5 | use embassy_executor::Spawner; | 5 | use embassy_executor::Spawner; |
| 6 | use embassy_rp::peripherals::PIO0; | 6 | use embassy_rp::peripherals::PIO0; |
| 7 | use embassy_rp::pio::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine}; | 7 | use embassy_rp::pio::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine}; |
| 8 | use embassy_rp::pio_instr_util; | ||
| 9 | use embassy_rp::relocate::RelocatedProgram; | 8 | use embassy_rp::relocate::RelocatedProgram; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 9 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 10 | ||
| 12 | fn setup_pio_task_sm0(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 0>, pin: impl PioPin) { | 11 | fn setup_pio_task_sm0<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 0>, pin: impl PioPin) { |
| 13 | // Setup sm0 | 12 | // Setup sm0 |
| 14 | 13 | ||
| 15 | // Send data serially to pin | 14 | // Send data serially to pin |
| @@ -22,15 +21,12 @@ fn setup_pio_task_sm0(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 0>, pi | |||
| 22 | ); | 21 | ); |
| 23 | 22 | ||
| 24 | let relocated = RelocatedProgram::new(&prg.program); | 23 | let relocated = RelocatedProgram::new(&prg.program); |
| 24 | sm.use_program(&pio.load_program(&relocated), &[]); | ||
| 25 | let out_pin = pio.make_pio_pin(pin); | 25 | let out_pin = pio.make_pio_pin(pin); |
| 26 | let pio_pins = [&out_pin]; | 26 | let pio_pins = [&out_pin]; |
| 27 | sm.set_out_pins(&pio_pins); | 27 | sm.set_out_pins(&pio_pins); |
| 28 | pio.write_instr(relocated.origin() as usize, relocated.code()); | ||
| 29 | pio_instr_util::exec_jmp(sm, relocated.origin()); | ||
| 30 | sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); | 28 | sm.set_clkdiv((125e6 / 20.0 / 2e2 * 256.0) as u32); |
| 31 | sm.set_set_range(0, 1); | 29 | sm.set_set_range(0, 1); |
| 32 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 33 | sm.set_wrap(source, target); | ||
| 34 | 30 | ||
| 35 | sm.set_autopull(true); | 31 | sm.set_autopull(true); |
| 36 | sm.set_out_shift_dir(ShiftDirection::Left); | 32 | sm.set_out_shift_dir(ShiftDirection::Left); |
| @@ -48,20 +44,16 @@ async fn pio_task_sm0(mut sm: StateMachine<'static, PIO0, 0>) { | |||
| 48 | } | 44 | } |
| 49 | } | 45 | } |
| 50 | 46 | ||
| 51 | fn setup_pio_task_sm1(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 1>) { | 47 | fn setup_pio_task_sm1<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 1>) { |
| 52 | // Setupm sm1 | 48 | // Setupm sm1 |
| 53 | 49 | ||
| 54 | // Read 0b10101 repeatedly until ISR is full | 50 | // Read 0b10101 repeatedly until ISR is full |
| 55 | let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); | 51 | let prg = pio_proc::pio_asm!(".origin 8", "set x, 0x15", ".wrap_target", "in x, 5 [31]", ".wrap",); |
| 56 | 52 | ||
| 57 | let relocated = RelocatedProgram::new(&prg.program); | 53 | let relocated = RelocatedProgram::new(&prg.program); |
| 58 | pio.write_instr(relocated.origin() as usize, relocated.code()); | 54 | sm.use_program(&pio.load_program(&relocated), &[]); |
| 59 | pio_instr_util::exec_jmp(sm, relocated.origin()); | ||
| 60 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | 55 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); |
| 61 | sm.set_set_range(0, 0); | 56 | sm.set_set_range(0, 0); |
| 62 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 63 | sm.set_wrap(source, target); | ||
| 64 | |||
| 65 | sm.set_autopush(true); | 57 | sm.set_autopush(true); |
| 66 | sm.set_in_shift_dir(ShiftDirection::Right); | 58 | sm.set_in_shift_dir(ShiftDirection::Right); |
| 67 | } | 59 | } |
| @@ -75,7 +67,7 @@ async fn pio_task_sm1(mut sm: StateMachine<'static, PIO0, 1>) { | |||
| 75 | } | 67 | } |
| 76 | } | 68 | } |
| 77 | 69 | ||
| 78 | fn setup_pio_task_sm2(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 2>) { | 70 | fn setup_pio_task_sm2<'a>(pio: &mut Common<'a, PIO0>, sm: &mut StateMachine<'a, PIO0, 2>) { |
| 79 | // Setup sm2 | 71 | // Setup sm2 |
| 80 | 72 | ||
| 81 | // Repeatedly trigger IRQ 3 | 73 | // Repeatedly trigger IRQ 3 |
| @@ -89,12 +81,7 @@ fn setup_pio_task_sm2(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 2>) { | |||
| 89 | ".wrap", | 81 | ".wrap", |
| 90 | ); | 82 | ); |
| 91 | let relocated = RelocatedProgram::new(&prg.program); | 83 | let relocated = RelocatedProgram::new(&prg.program); |
| 92 | pio.write_instr(relocated.origin() as usize, relocated.code()); | 84 | sm.use_program(&pio.load_program(&relocated), &[]); |
| 93 | |||
| 94 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 95 | sm.set_wrap(source, target); | ||
| 96 | |||
| 97 | pio_instr_util::exec_jmp(sm, relocated.origin()); | ||
| 98 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); | 85 | sm.set_clkdiv((125e6 / 2e3 * 256.0) as u32); |
| 99 | } | 86 | } |
| 100 | 87 | ||
diff --git a/examples/rp/src/bin/pio_dma.rs b/examples/rp/src/bin/pio_dma.rs index c664482e5..1c4e127c7 100644 --- a/examples/rp/src/bin/pio_dma.rs +++ b/examples/rp/src/bin/pio_dma.rs | |||
| @@ -6,7 +6,7 @@ use embassy_executor::Spawner; | |||
| 6 | use embassy_futures::join::join; | 6 | use embassy_futures::join::join; |
| 7 | use embassy_rp::pio::{Pio, ShiftDirection}; | 7 | use embassy_rp::pio::{Pio, ShiftDirection}; |
| 8 | use embassy_rp::relocate::RelocatedProgram; | 8 | use embassy_rp::relocate::RelocatedProgram; |
| 9 | use embassy_rp::{pio_instr_util, Peripheral}; | 9 | use embassy_rp::Peripheral; |
| 10 | use {defmt_rtt as _, panic_probe as _}; | 10 | use {defmt_rtt as _, panic_probe as _}; |
| 11 | 11 | ||
| 12 | fn swap_nibbles(v: u32) -> u32 { | 12 | fn swap_nibbles(v: u32) -> u32 { |
| @@ -38,11 +38,8 @@ async fn main(_spawner: Spawner) { | |||
| 38 | ); | 38 | ); |
| 39 | 39 | ||
| 40 | let relocated = RelocatedProgram::new(&prg.program); | 40 | let relocated = RelocatedProgram::new(&prg.program); |
| 41 | common.write_instr(relocated.origin() as usize, relocated.code()); | 41 | sm.use_program(&common.load_program(&relocated), &[]); |
| 42 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | ||
| 43 | sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); | 42 | sm.set_clkdiv((125e6 / 10e3 * 256.0) as u32); |
| 44 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 45 | sm.set_wrap(source, target); | ||
| 46 | sm.set_autopull(true); | 43 | sm.set_autopull(true); |
| 47 | sm.set_autopush(true); | 44 | sm.set_autopush(true); |
| 48 | sm.set_pull_threshold(32); | 45 | sm.set_pull_threshold(32); |
diff --git a/examples/rp/src/bin/pio_hd44780.rs b/examples/rp/src/bin/pio_hd44780.rs index 17b2440cf..c3466b554 100644 --- a/examples/rp/src/bin/pio_hd44780.rs +++ b/examples/rp/src/bin/pio_hd44780.rs | |||
| @@ -123,15 +123,9 @@ impl<'l> HD44780<'l> { | |||
| 123 | embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11111); | 123 | embassy_rp::pio_instr_util::set_pindir(&mut sm0, 0b11111); |
| 124 | 124 | ||
| 125 | let relocated = RelocatedProgram::new(&prg.program); | 125 | let relocated = RelocatedProgram::new(&prg.program); |
| 126 | common.write_instr(relocated.origin() as usize, relocated.code()); | 126 | sm0.use_program(&common.load_program(&relocated), &[&e]); |
| 127 | embassy_rp::pio_instr_util::exec_jmp(&mut sm0, relocated.origin()); | ||
| 128 | sm0.set_clkdiv(125 * 256); | 127 | sm0.set_clkdiv(125 * 256); |
| 129 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 130 | sm0.set_wrap(source, target); | ||
| 131 | sm0.set_side_enable(true); | ||
| 132 | sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); | 128 | sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); |
| 133 | sm0.set_sideset_base_pin(&e); | ||
| 134 | sm0.set_sideset_count(2); | ||
| 135 | sm0.set_out_shift_dir(ShiftDirection::Left); | 129 | sm0.set_out_shift_dir(ShiftDirection::Left); |
| 136 | sm0.set_fifo_join(FifoJoin::TxOnly); | 130 | sm0.set_fifo_join(FifoJoin::TxOnly); |
| 137 | sm0.set_autopull(true); | 131 | sm0.set_autopull(true); |
| @@ -199,17 +193,11 @@ impl<'l> HD44780<'l> { | |||
| 199 | ); | 193 | ); |
| 200 | 194 | ||
| 201 | let relocated = RelocatedProgram::new(&prg.program); | 195 | let relocated = RelocatedProgram::new(&prg.program); |
| 202 | common.write_instr(relocated.origin() as usize, relocated.code()); | 196 | sm0.use_program(&common.load_program(&relocated), &[&e]); |
| 203 | embassy_rp::pio_instr_util::exec_jmp(&mut sm0, relocated.origin()); | ||
| 204 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 205 | sm0.set_clkdiv(8 * 256); // ~64ns/insn | 197 | sm0.set_clkdiv(8 * 256); // ~64ns/insn |
| 206 | sm0.set_side_enable(false); | ||
| 207 | sm0.set_jmp_pin(db7pin); | 198 | sm0.set_jmp_pin(db7pin); |
| 208 | sm0.set_wrap(source, target); | ||
| 209 | sm0.set_set_pins(&[&rs, &rw]); | 199 | sm0.set_set_pins(&[&rs, &rw]); |
| 210 | sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); | 200 | sm0.set_out_pins(&[&db4, &db5, &db6, &db7]); |
| 211 | sm0.set_sideset_base_pin(&e); | ||
| 212 | sm0.set_sideset_count(1); | ||
| 213 | sm0.set_out_shift_dir(ShiftDirection::Left); | 201 | sm0.set_out_shift_dir(ShiftDirection::Left); |
| 214 | sm0.set_fifo_join(FifoJoin::TxOnly); | 202 | sm0.set_fifo_join(FifoJoin::TxOnly); |
| 215 | 203 | ||
diff --git a/examples/rp/src/bin/ws2812-pio.rs b/examples/rp/src/bin/ws2812-pio.rs index 2e6860d8b..889970541 100644 --- a/examples/rp/src/bin/ws2812-pio.rs +++ b/examples/rp/src/bin/ws2812-pio.rs | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy_executor::Spawner; | 6 | use embassy_executor::Spawner; |
| 7 | use embassy_rp::pio::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine}; | 7 | use embassy_rp::pio::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine}; |
| 8 | use embassy_rp::pio_instr_util; | ||
| 9 | use embassy_rp::relocate::RelocatedProgram; | 8 | use embassy_rp::relocate::RelocatedProgram; |
| 10 | use embassy_time::{Duration, Timer}; | 9 | use embassy_time::{Duration, Timer}; |
| 11 | use smart_leds::RGB8; | 10 | use smart_leds::RGB8; |
| @@ -45,15 +44,11 @@ impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> { | |||
| 45 | 44 | ||
| 46 | let prg = a.assemble_with_wrap(wrap_source, wrap_target); | 45 | let prg = a.assemble_with_wrap(wrap_source, wrap_target); |
| 47 | 46 | ||
| 48 | let relocated = RelocatedProgram::new(&prg); | ||
| 49 | pio.write_instr(relocated.origin() as usize, relocated.code()); | ||
| 50 | pio_instr_util::exec_jmp(&mut sm, relocated.origin()); | ||
| 51 | |||
| 52 | // Pin config | 47 | // Pin config |
| 53 | let out_pin = pio.make_pio_pin(pin); | 48 | let out_pin = pio.make_pio_pin(pin); |
| 54 | sm.set_set_pins(&[&out_pin]); | 49 | |
| 55 | sm.set_sideset_base_pin(&out_pin); | 50 | let relocated = RelocatedProgram::new(&prg); |
| 56 | sm.set_sideset_count(1); | 51 | sm.use_program(&pio.load_program(&relocated), &[&out_pin]); |
| 57 | 52 | ||
| 58 | // Clock config | 53 | // Clock config |
| 59 | // TODO CLOCK_FREQ should come from embassy_rp | 54 | // TODO CLOCK_FREQ should come from embassy_rp |
| @@ -70,8 +65,6 @@ impl<'d, P: Instance, const S: usize> Ws2812<'d, P, S> { | |||
| 70 | } | 65 | } |
| 71 | 66 | ||
| 72 | sm.set_clkdiv((int << 8) | frac); | 67 | sm.set_clkdiv((int << 8) | frac); |
| 73 | let pio::Wrap { source, target } = relocated.wrap(); | ||
| 74 | sm.set_wrap(source, target); | ||
| 75 | 68 | ||
| 76 | // FIFO config | 69 | // FIFO config |
| 77 | sm.set_autopull(true); | 70 | sm.set_autopull(true); |
