aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--embassy-rp/src/pio.rs128
-rw-r--r--examples/rp/src/bin/pio_async.rs25
-rw-r--r--examples/rp/src/bin/pio_dma.rs7
-rw-r--r--examples/rp/src/bin/pio_hd44780.rs16
-rw-r--r--examples/rp/src/bin/ws2812-pio.rs13
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};
9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_common::{into_ref, Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11use pac::io::vals::Gpio0ctrlFuncsel; 11use pac::io::vals::Gpio0ctrlFuncsel;
12use pio::{SideSet, Wrap};
12 13
13use crate::dma::{Channel, Transfer, Word}; 14use crate::dma::{Channel, Transfer, Word};
14use crate::gpio::sealed::Pin as SealedPin; 15use crate::gpio::sealed::Pin as SealedPin;
15use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate}; 16use crate::gpio::{self, AnyPin, Drive, Pull, SlewRate};
16use crate::pac::dma::vals::TreqSel; 17use crate::pac::dma::vals::TreqSel;
17use crate::{interrupt, pac, peripherals, RegExt}; 18use crate::relocate::RelocatedProgram;
19use crate::{interrupt, pac, peripherals, pio_instr_util, RegExt};
18 20
19struct Wakers([AtomicWaker; 12]); 21struct 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
465fn 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
463impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> { 472impl<'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
772pub struct LoadedProgram<'d, PIO: Instance> {
773 pub used_memory: InstanceMemory<'d, PIO>,
774 origin: u8,
775 wrap: Wrap,
776 side_set: SideSet,
777}
778
802impl<'d, PIO: Instance> Common<'d, PIO> { 779impl<'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;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_rp::peripherals::PIO0; 6use embassy_rp::peripherals::PIO0;
7use embassy_rp::pio::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine}; 7use embassy_rp::pio::{Common, Irq, Pio, PioPin, ShiftDirection, StateMachine};
8use embassy_rp::pio_instr_util;
9use embassy_rp::relocate::RelocatedProgram; 8use embassy_rp::relocate::RelocatedProgram;
10use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
11 10
12fn setup_pio_task_sm0(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 0>, pin: impl PioPin) { 11fn 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
51fn setup_pio_task_sm1(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 1>) { 47fn 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
78fn setup_pio_task_sm2(pio: &mut Common<PIO0>, sm: &mut StateMachine<PIO0, 2>) { 70fn 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;
6use embassy_futures::join::join; 6use embassy_futures::join::join;
7use embassy_rp::pio::{Pio, ShiftDirection}; 7use embassy_rp::pio::{Pio, ShiftDirection};
8use embassy_rp::relocate::RelocatedProgram; 8use embassy_rp::relocate::RelocatedProgram;
9use embassy_rp::{pio_instr_util, Peripheral}; 9use embassy_rp::Peripheral;
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12fn swap_nibbles(v: u32) -> u32 { 12fn 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 @@
5use defmt::*; 5use defmt::*;
6use embassy_executor::Spawner; 6use embassy_executor::Spawner;
7use embassy_rp::pio::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine}; 7use embassy_rp::pio::{Common, FifoJoin, Instance, Pio, PioPin, ShiftDirection, StateMachine};
8use embassy_rp::pio_instr_util;
9use embassy_rp::relocate::RelocatedProgram; 8use embassy_rp::relocate::RelocatedProgram;
10use embassy_time::{Duration, Timer}; 9use embassy_time::{Duration, Timer};
11use smart_leds::RGB8; 10use 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);