aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpennae <[email protected]>2023-05-03 10:51:50 +0200
committerpennae <[email protected]>2023-05-03 13:00:08 +0200
commit77f7830da396b8666600a39e860c46ddde395f04 (patch)
tree94aeea5d814afb64c470a97dd6c9fe0778018aae
parent909a5fe2e513ef91129a29ccdd8772824879383c (diff)
rp/pio: move irq flag handling to own struct
this way we can share irq handling between state machines and common without having to duplicate the methods. it also lets us give irq flag access to places without having to dedicate a state machine or the common instance to those places, which can be very useful to eg trigger an event and wait for a confirmation using an irq wait object.
-rw-r--r--embassy-rp/src/pio.rs62
1 files changed, 40 insertions, 22 deletions
diff --git a/embassy-rp/src/pio.rs b/embassy-rp/src/pio.rs
index 769641ac9..3c5969dbd 100644
--- a/embassy-rp/src/pio.rs
+++ b/embassy-rp/src/pio.rs
@@ -811,28 +811,6 @@ impl<'d, PIO: PioInstance> PioCommon<'d, PIO> {
811 self.instructions_used &= !instrs.used_mask; 811 self.instructions_used &= !instrs.used_mask;
812 } 812 }
813 813
814 pub fn is_irq_set(&self, irq_no: u8) -> bool {
815 assert!(irq_no < 8);
816 unsafe {
817 let irq_flags = PIO::PIO.irq();
818 irq_flags.read().0 & (1 << irq_no) != 0
819 }
820 }
821
822 pub fn clear_irq(&mut self, irq_no: usize) {
823 assert!(irq_no < 8);
824 unsafe { PIO::PIO.irq().write(|w| w.set_irq(1 << irq_no)) }
825 }
826
827 pub fn clear_irqs(&mut self, mask: u8) {
828 unsafe { PIO::PIO.irq().write(|w| w.set_irq(mask)) }
829 }
830
831 pub fn force_irq(&mut self, irq_no: usize) {
832 assert!(irq_no < 8);
833 unsafe { PIO::PIO.irq_force().write(|w| w.set_irq_force(1 << irq_no)) }
834 }
835
836 pub fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) { 814 pub fn set_input_sync_bypass<'a>(&'a mut self, bypass: u32, mask: u32) {
837 unsafe { 815 unsafe {
838 // this can interfere with per-pin bypass functions. splitting the 816 // this can interfere with per-pin bypass functions. splitting the
@@ -878,8 +856,47 @@ impl<'d, PIO: PioInstance, const N: usize> PioIrq<'d, PIO, N> {
878 } 856 }
879} 857}
880 858
859#[derive(Clone)]
860pub struct PioIrqFlags<'d, PIO: PioInstance> {
861 pio: PhantomData<&'d PIO>,
862}
863
864impl<'d, PIO: PioInstance> PioIrqFlags<'d, PIO> {
865 pub fn check(&self, irq_no: u8) -> bool {
866 assert!(irq_no < 8);
867 self.check_any(1 << irq_no)
868 }
869
870 pub fn check_any(&self, irqs: u8) -> bool {
871 unsafe { PIO::PIO.irq().read().irq() & irqs != 0 }
872 }
873
874 pub fn check_all(&self, irqs: u8) -> bool {
875 unsafe { PIO::PIO.irq().read().irq() & irqs == irqs }
876 }
877
878 pub fn clear(&self, irq_no: usize) {
879 assert!(irq_no < 8);
880 self.clear_all(1 << irq_no);
881 }
882
883 pub fn clear_all(&self, irqs: u8) {
884 unsafe { PIO::PIO.irq().write(|w| w.set_irq(irqs)) }
885 }
886
887 pub fn set(&self, irq_no: usize) {
888 assert!(irq_no < 8);
889 self.set_all(1 << irq_no);
890 }
891
892 pub fn set_all(&self, irqs: u8) {
893 unsafe { PIO::PIO.irq_force().write(|w| w.set_irq_force(irqs)) }
894 }
895}
896
881pub struct Pio<'d, PIO: PioInstance> { 897pub struct Pio<'d, PIO: PioInstance> {
882 pub common: PioCommon<'d, PIO>, 898 pub common: PioCommon<'d, PIO>,
899 pub irq_flags: PioIrqFlags<'d, PIO>,
883 pub irq0: PioIrq<'d, PIO, 0>, 900 pub irq0: PioIrq<'d, PIO, 0>,
884 pub irq1: PioIrq<'d, PIO, 1>, 901 pub irq1: PioIrq<'d, PIO, 1>,
885 pub irq2: PioIrq<'d, PIO, 2>, 902 pub irq2: PioIrq<'d, PIO, 2>,
@@ -899,6 +916,7 @@ impl<'d, PIO: PioInstance> Pio<'d, PIO> {
899 instructions_used: 0, 916 instructions_used: 0,
900 pio: PhantomData, 917 pio: PhantomData,
901 }, 918 },
919 irq_flags: PioIrqFlags { pio: PhantomData },
902 irq0: PioIrq { pio: PhantomData }, 920 irq0: PioIrq { pio: PhantomData },
903 irq1: PioIrq { pio: PhantomData }, 921 irq1: PioIrq { pio: PhantomData },
904 irq2: PioIrq { pio: PhantomData }, 922 irq2: PioIrq { pio: PhantomData },