pamoja_radios/sx127x/
irq.rs1use core::ops::{BitAnd, BitOr, BitOrAssign};
8
9#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
22pub struct IrqFlags(u8);
23
24impl IrqFlags {
25 pub const NONE: IrqFlags = IrqFlags(0);
27 pub const CAD_DETECTED: IrqFlags = IrqFlags(1 << 0);
29 pub const FHSS_CHANGE_CHANNEL: IrqFlags = IrqFlags(1 << 1);
31 pub const CAD_DONE: IrqFlags = IrqFlags(1 << 2);
33 pub const TX_DONE: IrqFlags = IrqFlags(1 << 3);
35 pub const VALID_HEADER: IrqFlags = IrqFlags(1 << 4);
37 pub const PAYLOAD_CRC_ERROR: IrqFlags = IrqFlags(1 << 5);
39 pub const RX_DONE: IrqFlags = IrqFlags(1 << 6);
41 pub const RX_TIMEOUT: IrqFlags = IrqFlags(1 << 7);
43 pub const ALL: IrqFlags = IrqFlags(0xFF);
45
46 pub const fn from_bits(bits: u8) -> IrqFlags {
56 IrqFlags(bits)
57 }
58
59 pub const fn bits(self) -> u8 {
65 self.0
66 }
67
68 pub const fn contains(self, other: IrqFlags) -> bool {
78 self.0 & other.0 == other.0
79 }
80
81 pub const fn intersects(self, other: IrqFlags) -> bool {
91 self.0 & other.0 != 0
92 }
93
94 pub const fn is_empty(self) -> bool {
100 self.0 == 0
101 }
102}
103
104impl BitOr for IrqFlags {
105 type Output = IrqFlags;
106
107 fn bitor(self, rhs: IrqFlags) -> IrqFlags {
108 IrqFlags(self.0 | rhs.0)
109 }
110}
111
112impl BitOrAssign for IrqFlags {
113 fn bitor_assign(&mut self, rhs: IrqFlags) {
114 self.0 |= rhs.0;
115 }
116}
117
118impl BitAnd for IrqFlags {
119 type Output = IrqFlags;
120
121 fn bitand(self, rhs: IrqFlags) -> IrqFlags {
122 IrqFlags(self.0 & rhs.0)
123 }
124}
125
126#[cfg(test)]
127mod tests {
128 use super::*;
129
130 #[test]
131 fn each_flag_sits_on_the_bit_the_register_description_gives() {
132 assert_eq!(IrqFlags::RX_TIMEOUT.bits(), 0x80);
133 assert_eq!(IrqFlags::RX_DONE.bits(), 0x40);
134 assert_eq!(IrqFlags::PAYLOAD_CRC_ERROR.bits(), 0x20);
135 assert_eq!(IrqFlags::VALID_HEADER.bits(), 0x10);
136 assert_eq!(IrqFlags::TX_DONE.bits(), 0x08);
137 assert_eq!(IrqFlags::CAD_DONE.bits(), 0x04);
138 assert_eq!(IrqFlags::FHSS_CHANGE_CHANNEL.bits(), 0x02);
139 assert_eq!(IrqFlags::CAD_DETECTED.bits(), 0x01);
140 }
141
142 #[test]
143 fn the_flags_together_are_the_whole_register() {
144 let every = IrqFlags::RX_TIMEOUT
145 | IrqFlags::RX_DONE
146 | IrqFlags::PAYLOAD_CRC_ERROR
147 | IrqFlags::VALID_HEADER
148 | IrqFlags::TX_DONE
149 | IrqFlags::CAD_DONE
150 | IrqFlags::FHSS_CHANGE_CHANNEL
151 | IrqFlags::CAD_DETECTED;
152 assert_eq!(every, IrqFlags::ALL);
153 }
154
155 #[test]
156 fn intersects_finds_any_and_contains_needs_all() {
157 let raised = IrqFlags::RX_DONE | IrqFlags::VALID_HEADER;
158 assert!(raised.intersects(IrqFlags::RX_DONE | IrqFlags::RX_TIMEOUT));
159 assert!(!raised.contains(IrqFlags::RX_DONE | IrqFlags::RX_TIMEOUT));
160 assert!(IrqFlags::NONE.is_empty());
161 assert_eq!(raised & IrqFlags::RX_DONE, IrqFlags::RX_DONE);
162 }
163}