diff options
| author | Dario Nieuwenhuis <[email protected]> | 2024-09-17 22:15:37 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-09-17 22:15:37 +0000 |
| commit | e597c6b959c8c79078d5bc7126a29cab6f3df46c (patch) | |
| tree | 9f9544fa007c5a92fdee326d55fecd88baf52526 | |
| parent | cc9e2a51da9735d438ce0512b51466d355bc6bc8 (diff) | |
| parent | d1508cc49c9ac029ececb1ae5e4c326ac678d1ec (diff) | |
Merge pull request #3332 from CBJamo/rp2350_pio_pins
rp: rp2350 pio pin fixes
| -rw-r--r-- | embassy-rp/src/gpio.rs | 4 | ||||
| -rw-r--r-- | embassy-rp/src/pio/mod.rs | 61 |
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}; | |||
| 16 | const NEW_AW: AtomicWaker = AtomicWaker::new(); | 16 | const NEW_AW: AtomicWaker = AtomicWaker::new(); |
| 17 | 17 | ||
| 18 | #[cfg(any(feature = "rp2040", feature = "rp235xa"))] | 18 | #[cfg(any(feature = "rp2040", feature = "rp235xa"))] |
| 19 | const BANK0_PIN_COUNT: usize = 30; | 19 | pub(crate) const BANK0_PIN_COUNT: usize = 30; |
| 20 | #[cfg(feature = "rp235xb")] | 20 | #[cfg(feature = "rp235xb")] |
| 21 | const BANK0_PIN_COUNT: usize = 48; | 21 | pub(crate) const BANK0_PIN_COUNT: usize = 48; |
| 22 | 22 | ||
| 23 | static BANK0_WAKERS: [AtomicWaker; BANK0_PIN_COUNT] = [NEW_AW; BANK0_PIN_COUNT]; | 23 | static 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; | |||
| 5 | use core::sync::atomic::{compiler_fence, Ordering}; | 5 | use core::sync::atomic::{compiler_fence, Ordering}; |
| 6 | use core::task::{Context, Poll}; | 6 | use core::task::{Context, Poll}; |
| 7 | 7 | ||
| 8 | use atomic_polyfill::{AtomicU32, AtomicU8}; | 8 | use atomic_polyfill::{AtomicU64, AtomicU8}; |
| 9 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; | 9 | use embassy_hal_internal::{into_ref, Peripheral, PeripheralRef}; |
| 10 | use embassy_sync::waitqueue::AtomicWaker; | 10 | use embassy_sync::waitqueue::AtomicWaker; |
| 11 | use fixed::types::extra::U8; | 11 | use 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. |
| 1188 | pub struct State { | 1240 | pub struct State { |
| 1189 | users: AtomicU8, | 1241 | users: AtomicU8, |
| 1190 | used_pins: AtomicU32, | 1242 | used_pins: AtomicU64, |
| 1191 | } | 1243 | } |
| 1192 | 1244 | ||
| 1193 | fn on_pio_drop<PIO: Instance>() { | 1245 | fn 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 |
