From a12a5086149c5830c76d57a7c3a73eb27d86a72d Mon Sep 17 00:00:00 2001 From: Wilfried Chauveau Date: Sat, 29 Jun 2024 22:42:59 +0100 Subject: [PATCH] gpio: add `PinGroup::set_u32` to allow setting each pin to a different state --- rp2040-hal/src/gpio/pin_group.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/rp2040-hal/src/gpio/pin_group.rs b/rp2040-hal/src/gpio/pin_group.rs index ab2fbda0c..88ff8817a 100644 --- a/rp2040-hal/src/gpio/pin_group.rs +++ b/rp2040-hal/src/gpio/pin_group.rs @@ -159,6 +159,34 @@ where } } + /// Set this set of pins to the state given in a single operation. + /// + /// The state passed in must be a mask where each bit corresponds to a gpio. + /// + /// For example, if the group contains Gpio1 and Gpio3, a read may yield: + /// ```text + /// 0b0000_0000__0000_0000__0000_0000__0000_1010 + /// This is Gpio3 ↑↑↑ + /// Gpio2 is not used || + /// This is Gpio1 | + /// ``` + /// + /// State corresponding to bins not in this group are ignored. + pub fn set_u32(&mut self, state: u32) { + use super::pin::pin_sealed::PinIdOps; + let mask = self.0.write_mask(); + let state_masked = mask & state; + let head_id = self.0.head.borrow().id(); + // UNSAFE: this register is 32bit wide and all bits are valid. + // The value set is masked + head_id.sio_out().modify(|r, w| unsafe { + // clear all bit part of this group + let cleared = r.bits() & !mask; + // set bits according to state + w.bits(cleared | state_masked) + }); + } + /// Toggles this set of pins all at the same time. /// /// This only affects output pins. Input pins in the