aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2024-09-17 22:15:37 +0000
committerGitHub <[email protected]>2024-09-17 22:15:37 +0000
commite597c6b959c8c79078d5bc7126a29cab6f3df46c (patch)
tree9f9544fa007c5a92fdee326d55fecd88baf52526
parentcc9e2a51da9735d438ce0512b51466d355bc6bc8 (diff)
parentd1508cc49c9ac029ececb1ae5e4c326ac678d1ec (diff)
Merge pull request #3332 from CBJamo/rp2350_pio_pins
rp: rp2350 pio pin fixes
-rw-r--r--embassy-rp/src/gpio.rs4
-rw-r--r--embassy-rp/src/pio/mod.rs61
2 files changed, 58 insertions, 7 deletions
diff --git a/embassy-rp/src/gpio.rs b/embassy-rp/src/gpio.rs
index 31397172c..520043b07 100644
--- a/embassy-rp/src/gpio.rs
+++ b/embassy-rp/src/gpio.rs
@@ -16,9 +16,9 @@ use crate::{interrupt, pac, peripherals, Peripheral, RegExt};
16const NEW_AW: AtomicWaker = AtomicWaker::new(); 16const NEW_AW: AtomicWaker = AtomicWaker::new();
17 17
18#[cfg(any(feature = "rp2040", feature = "rp235xa"))] 18#[cfg(any(feature = "rp2040", feature = "rp235xa"))]
19const BANK0_PIN_COUNT: usize = 30; 19pub(crate) const BANK0_PIN_COUNT: usize = 30;
20#[cfg(feature = "rp235xb")] 20#[cfg(feature = "rp235xb")]
21const BANK0_PIN_COUNT: usize = 48; 21pub(crate) const BANK0_PIN_COUNT: usize = 48;
22 22
23static BANK0_WAKERS: [AtomicWaker; BANK0_PIN_COUNT] = [NEW_AW; BANK0_PIN_COUNT]; 23static BANK0_WAKERS: [AtomicWaker; BANK0_PIN_COUNT] = [NEW_AW; BANK0_PIN_COUNT];
24#[cfg(feature = "qspi-as-gpio")] 24#[cfg(feature = "qspi-as-gpio")]
diff --git a/embassy-rp/src/pio/mod.rs b/embassy-rp/src/pio/mod.rs
index 68b1d6849..72aa8f104 100644
--- a/embassy-rp/src/pio/mod.rs
+++ b/embassy-rp/src/pio/mod.rs
@@ -5,7 +5,7 @@ use core::pin::Pin as FuturePin;
5use core::sync::atomic::{compiler_fence, Ordering}; 5use core::sync::atomic::{compiler_fence, Ordering};
6use core::task::{Context, Poll}; 6use core::task::{Context, Poll};
7 7
8use atomic_polyfill::{AtomicU32, AtomicU8}; 8use atomic_polyfill::{AtomicU64, AtomicU8};
9use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; 9use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef};
10use embassy_sync::waitqueue::AtomicWaker; 10use embassy_sync::waitqueue::AtomicWaker;
11use fixed::types::extra::U8; 11use fixed::types::extra::U8;
@@ -731,6 +731,8 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
731 w.set_autopull(config.shift_out.auto_fill); 731 w.set_autopull(config.shift_out.auto_fill);
732 w.set_autopush(config.shift_in.auto_fill); 732 w.set_autopush(config.shift_in.auto_fill);
733 }); 733 });
734
735 #[cfg(feature = "rp2040")]
734 sm.pinctrl().write(|w| { 736 sm.pinctrl().write(|w| {
735 w.set_sideset_count(config.pins.sideset_count); 737 w.set_sideset_count(config.pins.sideset_count);
736 w.set_set_count(config.pins.set_count); 738 w.set_set_count(config.pins.set_count);
@@ -740,6 +742,52 @@ impl<'d, PIO: Instance + 'd, const SM: usize> StateMachine<'d, PIO, SM> {
740 w.set_set_base(config.pins.set_base); 742 w.set_set_base(config.pins.set_base);
741 w.set_out_base(config.pins.out_base); 743 w.set_out_base(config.pins.out_base);
742 }); 744 });
745
746 #[cfg(feature = "_rp235x")]
747 {
748 let mut low_ok = true;
749 let mut high_ok = true;
750
751 let in_pins = config.pins.in_base..config.pins.in_base + config.in_count;
752 let side_pins = config.pins.sideset_base..config.pins.sideset_base + config.pins.sideset_count;
753 let set_pins = config.pins.set_base..config.pins.set_base + config.pins.set_count;
754 let out_pins = config.pins.out_base..config.pins.out_base + config.pins.out_count;
755
756 for pin_range in [in_pins, side_pins, set_pins, out_pins] {
757 for pin in pin_range {
758 low_ok &= pin < 32;
759 high_ok &= pin >= 16;
760 }
761 }
762
763 if !low_ok && !high_ok {
764 panic!(
765 "All pins must either be <32 or >=16, in:{:?}-{:?}, side:{:?}-{:?}, set:{:?}-{:?}, out:{:?}-{:?}",
766 config.pins.in_base,
767 config.pins.in_base + config.in_count - 1,
768 config.pins.sideset_base,
769 config.pins.sideset_base + config.pins.sideset_count - 1,
770 config.pins.set_base,
771 config.pins.set_base + config.pins.set_count - 1,
772 config.pins.out_base,
773 config.pins.out_base + config.pins.out_count - 1,
774 )
775 }
776 let shift = if low_ok { 0 } else { 16 };
777
778 sm.pinctrl().write(|w| {
779 w.set_sideset_count(config.pins.sideset_count);
780 w.set_set_count(config.pins.set_count);
781 w.set_out_count(config.pins.out_count);
782 w.set_in_base(config.pins.in_base.checked_sub(shift).unwrap_or_default());
783 w.set_sideset_base(config.pins.sideset_base.checked_sub(shift).unwrap_or_default());
784 w.set_set_base(config.pins.set_base.checked_sub(shift).unwrap_or_default());
785 w.set_out_base(config.pins.out_base.checked_sub(shift).unwrap_or_default());
786 });
787
788 PIO::PIO.gpiobase().write(|w| w.set_gpiobase(shift == 16));
789 }
790
743 if let Some(origin) = config.origin { 791 if let Some(origin) = config.origin {
744 unsafe { instr::exec_jmp(self, origin) } 792 unsafe { instr::exec_jmp(self, origin) }
745 } 793 }
@@ -1006,6 +1054,10 @@ impl<'d, PIO: Instance> Common<'d, PIO> {
1006 pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> { 1054 pub fn make_pio_pin(&mut self, pin: impl Peripheral<P = impl PioPin + 'd> + 'd) -> Pin<'d, PIO> {
1007 into_ref!(pin); 1055 into_ref!(pin);
1008 pin.gpio().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL as _)); 1056 pin.gpio().ctrl().write(|w| w.set_funcsel(PIO::FUNCSEL as _));
1057 #[cfg(feature = "_rp235x")]
1058 pin.pad_ctrl().modify(|w| {
1059 w.set_iso(false);
1060 });
1009 // we can be relaxed about this because we're &mut here and nothing is cached 1061 // we can be relaxed about this because we're &mut here and nothing is cached
1010 PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed); 1062 PIO::state().used_pins.fetch_or(1 << pin.pin_bank(), Ordering::Relaxed);
1011 Pin { 1063 Pin {
@@ -1187,7 +1239,7 @@ impl<'d, PIO: Instance> Pio<'d, PIO> {
1187// other way. 1239// other way.
1188pub struct State { 1240pub struct State {
1189 users: AtomicU8, 1241 users: AtomicU8,
1190 used_pins: AtomicU32, 1242 used_pins: AtomicU64,
1191} 1243}
1192 1244
1193fn on_pio_drop<PIO: Instance>() { 1245fn on_pio_drop<PIO: Instance>() {
@@ -1195,8 +1247,7 @@ fn on_pio_drop<PIO: Instance>() {
1195 if state.users.fetch_sub(1, Ordering::AcqRel) == 1 { 1247 if state.users.fetch_sub(1, Ordering::AcqRel) == 1 {
1196 let used_pins = state.used_pins.load(Ordering::Relaxed); 1248 let used_pins = state.used_pins.load(Ordering::Relaxed);
1197 let null = pac::io::vals::Gpio0ctrlFuncsel::NULL as _; 1249 let null = pac::io::vals::Gpio0ctrlFuncsel::NULL as _;
1198 // we only have 30 pins. don't test the other two since gpio() asserts. 1250 for i in 0..crate::gpio::BANK0_PIN_COUNT {
1199 for i in 0..30 {
1200 if used_pins & (1 << i) != 0 { 1251 if used_pins & (1 << i) != 0 {
1201 pac::IO_BANK0.gpio(i).ctrl().write(|w| w.set_funcsel(null)); 1252 pac::IO_BANK0.gpio(i).ctrl().write(|w| w.set_funcsel(null));
1202 } 1253 }
@@ -1221,7 +1272,7 @@ trait SealedInstance {
1221 fn state() -> &'static State { 1272 fn state() -> &'static State {
1222 static STATE: State = State { 1273 static STATE: State = State {
1223 users: AtomicU8::new(0), 1274 users: AtomicU8::new(0),
1224 used_pins: AtomicU32::new(0), 1275 used_pins: AtomicU64::new(0),
1225 }; 1276 };
1226 1277
1227 &STATE 1278 &STATE