diff options
| author | chemicstry <[email protected]> | 2022-07-13 02:21:42 +0300 |
|---|---|---|
| committer | chemicstry <[email protected]> | 2022-07-13 02:21:42 +0300 |
| commit | 8cebbde1013bb98901e6fb18a4a0b095bf28f58f (patch) | |
| tree | 71da0dff9615a656dc3798e286aee7499774c854 /embassy-nrf/src | |
| parent | 329955f718ac6a99f98856386e8a3708f285de43 (diff) | |
Add convenience GPIO functions to NRF
Diffstat (limited to 'embassy-nrf/src')
| -rw-r--r-- | embassy-nrf/src/gpio.rs | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/embassy-nrf/src/gpio.rs b/embassy-nrf/src/gpio.rs index 0ba20b0b1..d8295fc06 100644 --- a/embassy-nrf/src/gpio.rs +++ b/embassy-nrf/src/gpio.rs | |||
| @@ -38,6 +38,7 @@ pub struct Input<'d, T: Pin> { | |||
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | impl<'d, T: Pin> Input<'d, T> { | 40 | impl<'d, T: Pin> Input<'d, T> { |
| 41 | #[inline] | ||
| 41 | pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { | 42 | pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { |
| 42 | let mut pin = Flex::new(pin); | 43 | let mut pin = Flex::new(pin); |
| 43 | pin.set_as_input(pull); | 44 | pin.set_as_input(pull); |
| @@ -45,13 +46,21 @@ impl<'d, T: Pin> Input<'d, T> { | |||
| 45 | Self { pin } | 46 | Self { pin } |
| 46 | } | 47 | } |
| 47 | 48 | ||
| 49 | #[inline] | ||
| 48 | pub fn is_high(&self) -> bool { | 50 | pub fn is_high(&self) -> bool { |
| 49 | self.pin.is_high() | 51 | self.pin.is_high() |
| 50 | } | 52 | } |
| 51 | 53 | ||
| 54 | #[inline] | ||
| 52 | pub fn is_low(&self) -> bool { | 55 | pub fn is_low(&self) -> bool { |
| 53 | self.pin.is_low() | 56 | self.pin.is_low() |
| 54 | } | 57 | } |
| 58 | |||
| 59 | /// Returns current pin level | ||
| 60 | #[inline] | ||
| 61 | pub fn get_level(&self) -> Level { | ||
| 62 | self.pin.is_high().into() | ||
| 63 | } | ||
| 55 | } | 64 | } |
| 56 | 65 | ||
| 57 | /// Digital input or output level. | 66 | /// Digital input or output level. |
| @@ -62,6 +71,24 @@ pub enum Level { | |||
| 62 | High, | 71 | High, |
| 63 | } | 72 | } |
| 64 | 73 | ||
| 74 | impl From<bool> for Level { | ||
| 75 | fn from(val: bool) -> Self { | ||
| 76 | match val { | ||
| 77 | true => Self::High, | ||
| 78 | false => Self::Low, | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | impl Into<bool> for Level { | ||
| 84 | fn into(self) -> bool { | ||
| 85 | match self { | ||
| 86 | Level::Low => false, | ||
| 87 | Level::High => true, | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 65 | // These numbers match DRIVE_A exactly so hopefully the compiler will unify them. | 92 | // These numbers match DRIVE_A exactly so hopefully the compiler will unify them. |
| 66 | #[derive(Clone, Copy, Debug, PartialEq)] | 93 | #[derive(Clone, Copy, Debug, PartialEq)] |
| 67 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 94 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -91,6 +118,7 @@ pub struct Output<'d, T: Pin> { | |||
| 91 | } | 118 | } |
| 92 | 119 | ||
| 93 | impl<'d, T: Pin> Output<'d, T> { | 120 | impl<'d, T: Pin> Output<'d, T> { |
| 121 | #[inline] | ||
| 94 | pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self { | 122 | pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, drive: OutputDrive) -> Self { |
| 95 | let mut pin = Flex::new(pin); | 123 | let mut pin = Flex::new(pin); |
| 96 | match initial_output { | 124 | match initial_output { |
| @@ -103,24 +131,43 @@ impl<'d, T: Pin> Output<'d, T> { | |||
| 103 | } | 131 | } |
| 104 | 132 | ||
| 105 | /// Set the output as high. | 133 | /// Set the output as high. |
| 134 | #[inline] | ||
| 106 | pub fn set_high(&mut self) { | 135 | pub fn set_high(&mut self) { |
| 107 | self.pin.set_high() | 136 | self.pin.set_high() |
| 108 | } | 137 | } |
| 109 | 138 | ||
| 110 | /// Set the output as low. | 139 | /// Set the output as low. |
| 140 | #[inline] | ||
| 111 | pub fn set_low(&mut self) { | 141 | pub fn set_low(&mut self) { |
| 112 | self.pin.set_low() | 142 | self.pin.set_low() |
| 113 | } | 143 | } |
| 114 | 144 | ||
| 145 | /// Set the output level. | ||
| 146 | #[inline] | ||
| 147 | pub fn set_level(&mut self, level: Level) { | ||
| 148 | match level { | ||
| 149 | Level::Low => self.pin.set_low(), | ||
| 150 | Level::High => self.pin.set_high(), | ||
| 151 | } | ||
| 152 | } | ||
| 153 | |||
| 115 | /// Is the output pin set as high? | 154 | /// Is the output pin set as high? |
| 155 | #[inline] | ||
| 116 | pub fn is_set_high(&self) -> bool { | 156 | pub fn is_set_high(&self) -> bool { |
| 117 | self.pin.is_set_high() | 157 | self.pin.is_set_high() |
| 118 | } | 158 | } |
| 119 | 159 | ||
| 120 | /// Is the output pin set as low? | 160 | /// Is the output pin set as low? |
| 161 | #[inline] | ||
| 121 | pub fn is_set_low(&self) -> bool { | 162 | pub fn is_set_low(&self) -> bool { |
| 122 | self.pin.is_set_low() | 163 | self.pin.is_set_low() |
| 123 | } | 164 | } |
| 165 | |||
| 166 | /// What level output is set to | ||
| 167 | #[inline] | ||
| 168 | pub fn get_set_level(&self) -> Level { | ||
| 169 | self.pin.is_set_high().into() | ||
| 170 | } | ||
| 124 | } | 171 | } |
| 125 | 172 | ||
| 126 | fn convert_drive(drive: OutputDrive) -> DRIVE_A { | 173 | fn convert_drive(drive: OutputDrive) -> DRIVE_A { |
| @@ -159,6 +206,7 @@ impl<'d, T: Pin> Flex<'d, T> { | |||
| 159 | /// | 206 | /// |
| 160 | /// The pin remains disconnected. The initial output level is unspecified, but can be changed | 207 | /// The pin remains disconnected. The initial output level is unspecified, but can be changed |
| 161 | /// before the pin is put into output mode. | 208 | /// before the pin is put into output mode. |
| 209 | #[inline] | ||
| 162 | pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self { | 210 | pub fn new(pin: impl Unborrow<Target = T> + 'd) -> Self { |
| 163 | unborrow!(pin); | 211 | unborrow!(pin); |
| 164 | // Pin will be in disconnected state. | 212 | // Pin will be in disconnected state. |
| @@ -169,6 +217,7 @@ impl<'d, T: Pin> Flex<'d, T> { | |||
| 169 | } | 217 | } |
| 170 | 218 | ||
| 171 | /// Put the pin into input mode. | 219 | /// Put the pin into input mode. |
| 220 | #[inline] | ||
| 172 | pub fn set_as_input(&mut self, pull: Pull) { | 221 | pub fn set_as_input(&mut self, pull: Pull) { |
| 173 | self.pin.conf().write(|w| { | 222 | self.pin.conf().write(|w| { |
| 174 | w.dir().input(); | 223 | w.dir().input(); |
| @@ -184,6 +233,7 @@ impl<'d, T: Pin> Flex<'d, T> { | |||
| 184 | /// | 233 | /// |
| 185 | /// The pin level will be whatever was set before (or low by default). If you want it to begin | 234 | /// The pin level will be whatever was set before (or low by default). If you want it to begin |
| 186 | /// at a specific level, call `set_high`/`set_low` on the pin first. | 235 | /// at a specific level, call `set_high`/`set_low` on the pin first. |
| 236 | #[inline] | ||
| 187 | pub fn set_as_output(&mut self, drive: OutputDrive) { | 237 | pub fn set_as_output(&mut self, drive: OutputDrive) { |
| 188 | self.pin.conf().write(|w| { | 238 | self.pin.conf().write(|w| { |
| 189 | w.dir().output(); | 239 | w.dir().output(); |
| @@ -204,6 +254,7 @@ impl<'d, T: Pin> Flex<'d, T> { | |||
| 204 | /// | 254 | /// |
| 205 | /// The pin level will be whatever was set before (or low by default). If you want it to begin | 255 | /// The pin level will be whatever was set before (or low by default). If you want it to begin |
| 206 | /// at a specific level, call `set_high`/`set_low` on the pin first. | 256 | /// at a specific level, call `set_high`/`set_low` on the pin first. |
| 257 | #[inline] | ||
| 207 | pub fn set_as_input_output(&mut self, pull: Pull, drive: OutputDrive) { | 258 | pub fn set_as_input_output(&mut self, pull: Pull, drive: OutputDrive) { |
| 208 | self.pin.conf().write(|w| { | 259 | self.pin.conf().write(|w| { |
| 209 | w.dir().output(); | 260 | w.dir().output(); |
| @@ -216,37 +267,65 @@ impl<'d, T: Pin> Flex<'d, T> { | |||
| 216 | } | 267 | } |
| 217 | 268 | ||
| 218 | /// Put the pin into disconnected mode. | 269 | /// Put the pin into disconnected mode. |
| 270 | #[inline] | ||
| 219 | pub fn set_as_disconnected(&mut self) { | 271 | pub fn set_as_disconnected(&mut self) { |
| 220 | self.pin.conf().reset(); | 272 | self.pin.conf().reset(); |
| 221 | } | 273 | } |
| 222 | 274 | ||
| 275 | #[inline] | ||
| 223 | pub fn is_high(&self) -> bool { | 276 | pub fn is_high(&self) -> bool { |
| 224 | !self.is_low() | 277 | !self.is_low() |
| 225 | } | 278 | } |
| 226 | 279 | ||
| 280 | #[inline] | ||
| 227 | pub fn is_low(&self) -> bool { | 281 | pub fn is_low(&self) -> bool { |
| 228 | self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0 | 282 | self.pin.block().in_.read().bits() & (1 << self.pin.pin()) == 0 |
| 229 | } | 283 | } |
| 230 | 284 | ||
| 285 | /// Returns current pin level | ||
| 286 | #[inline] | ||
| 287 | pub fn get_level(&self) -> Level { | ||
| 288 | self.is_high().into() | ||
| 289 | } | ||
| 290 | |||
| 231 | /// Set the output as high. | 291 | /// Set the output as high. |
| 292 | #[inline] | ||
| 232 | pub fn set_high(&mut self) { | 293 | pub fn set_high(&mut self) { |
| 233 | self.pin.set_high() | 294 | self.pin.set_high() |
| 234 | } | 295 | } |
| 235 | 296 | ||
| 236 | /// Set the output as low. | 297 | /// Set the output as low. |
| 298 | #[inline] | ||
| 237 | pub fn set_low(&mut self) { | 299 | pub fn set_low(&mut self) { |
| 238 | self.pin.set_low() | 300 | self.pin.set_low() |
| 239 | } | 301 | } |
| 240 | 302 | ||
| 303 | /// Set the output level. | ||
| 304 | #[inline] | ||
| 305 | pub fn set_level(&mut self, level: Level) { | ||
| 306 | match level { | ||
| 307 | Level::Low => self.pin.set_low(), | ||
| 308 | Level::High => self.pin.set_high(), | ||
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 241 | /// Is the output pin set as high? | 312 | /// Is the output pin set as high? |
| 313 | #[inline] | ||
| 242 | pub fn is_set_high(&self) -> bool { | 314 | pub fn is_set_high(&self) -> bool { |
| 243 | !self.is_set_low() | 315 | !self.is_set_low() |
| 244 | } | 316 | } |
| 245 | 317 | ||
| 246 | /// Is the output pin set as low? | 318 | /// Is the output pin set as low? |
| 319 | #[inline] | ||
| 247 | pub fn is_set_low(&self) -> bool { | 320 | pub fn is_set_low(&self) -> bool { |
| 248 | self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0 | 321 | self.pin.block().out.read().bits() & (1 << self.pin.pin()) == 0 |
| 249 | } | 322 | } |
| 323 | |||
| 324 | /// What level output is set to | ||
| 325 | #[inline] | ||
| 326 | pub fn get_set_level(&self) -> Level { | ||
| 327 | self.is_set_high().into() | ||
| 328 | } | ||
| 250 | } | 329 | } |
| 251 | 330 | ||
| 252 | impl<'d, T: Pin> Drop for Flex<'d, T> { | 331 | impl<'d, T: Pin> Drop for Flex<'d, T> { |
