diff options
| author | Nicolas Viennot <[email protected]> | 2022-03-19 14:06:11 -0400 |
|---|---|---|
| committer | Nicolas Viennot <[email protected]> | 2022-03-19 14:06:11 -0400 |
| commit | 4aba87f983be3d4366f644335ab9228bd2609a3d (patch) | |
| tree | 7aa50b006bab392afff94e71e825d228ef9a689c | |
| parent | cb1be3983a47029e0e6a1c07082dd6ed18eda2a7 (diff) | |
Inline GPIO functions
All GPIO functions are monomorphized (per pin). Inlining these make the
ROM smaller when using opt-level="z"
| -rw-r--r-- | embassy-stm32/src/gpio.rs | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 3e108736b..1ac6f3952 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -77,6 +77,7 @@ pub struct Input<'d, T: Pin> { | |||
| 77 | } | 77 | } |
| 78 | 78 | ||
| 79 | impl<'d, T: Pin> Input<'d, T> { | 79 | impl<'d, T: Pin> Input<'d, T> { |
| 80 | #[inline] | ||
| 80 | pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { | 81 | pub fn new(pin: impl Unborrow<Target = T> + 'd, pull: Pull) -> Self { |
| 81 | unborrow!(pin); | 82 | unborrow!(pin); |
| 82 | 83 | ||
| @@ -117,10 +118,12 @@ impl<'d, T: Pin> Input<'d, T> { | |||
| 117 | } | 118 | } |
| 118 | } | 119 | } |
| 119 | 120 | ||
| 121 | #[inline] | ||
| 120 | pub fn is_high(&self) -> bool { | 122 | pub fn is_high(&self) -> bool { |
| 121 | !self.is_low() | 123 | !self.is_low() |
| 122 | } | 124 | } |
| 123 | 125 | ||
| 126 | #[inline] | ||
| 124 | pub fn is_low(&self) -> bool { | 127 | pub fn is_low(&self) -> bool { |
| 125 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; | 128 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; |
| 126 | state == vals::Idr::LOW | 129 | state == vals::Idr::LOW |
| @@ -128,6 +131,7 @@ impl<'d, T: Pin> Input<'d, T> { | |||
| 128 | } | 131 | } |
| 129 | 132 | ||
| 130 | impl<'d, T: Pin> Drop for Input<'d, T> { | 133 | impl<'d, T: Pin> Drop for Input<'d, T> { |
| 134 | #[inline] | ||
| 131 | fn drop(&mut self) { | 135 | fn drop(&mut self) { |
| 132 | critical_section::with(|_| unsafe { | 136 | critical_section::with(|_| unsafe { |
| 133 | let r = self.pin.block(); | 137 | let r = self.pin.block(); |
| @@ -159,6 +163,7 @@ pub struct Output<'d, T: Pin> { | |||
| 159 | } | 163 | } |
| 160 | 164 | ||
| 161 | impl<'d, T: Pin> Output<'d, T> { | 165 | impl<'d, T: Pin> Output<'d, T> { |
| 166 | #[inline] | ||
| 162 | pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, speed: Speed) -> Self { | 167 | pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level, speed: Speed) -> Self { |
| 163 | unborrow!(pin); | 168 | unborrow!(pin); |
| 164 | 169 | ||
| @@ -194,27 +199,32 @@ impl<'d, T: Pin> Output<'d, T> { | |||
| 194 | } | 199 | } |
| 195 | 200 | ||
| 196 | /// Set the output as high. | 201 | /// Set the output as high. |
| 202 | #[inline] | ||
| 197 | pub fn set_high(&mut self) { | 203 | pub fn set_high(&mut self) { |
| 198 | self.pin.set_high(); | 204 | self.pin.set_high(); |
| 199 | } | 205 | } |
| 200 | 206 | ||
| 201 | /// Set the output as low. | 207 | /// Set the output as low. |
| 208 | #[inline] | ||
| 202 | pub fn set_low(&mut self) { | 209 | pub fn set_low(&mut self) { |
| 203 | self.pin.set_low(); | 210 | self.pin.set_low(); |
| 204 | } | 211 | } |
| 205 | 212 | ||
| 206 | /// Is the output pin set as high? | 213 | /// Is the output pin set as high? |
| 214 | #[inline] | ||
| 207 | pub fn is_set_high(&self) -> bool { | 215 | pub fn is_set_high(&self) -> bool { |
| 208 | !self.is_set_low() | 216 | !self.is_set_low() |
| 209 | } | 217 | } |
| 210 | 218 | ||
| 211 | /// Is the output pin set as low? | 219 | /// Is the output pin set as low? |
| 220 | #[inline] | ||
| 212 | pub fn is_set_low(&self) -> bool { | 221 | pub fn is_set_low(&self) -> bool { |
| 213 | let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) }; | 222 | let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) }; |
| 214 | state == vals::Odr::LOW | 223 | state == vals::Odr::LOW |
| 215 | } | 224 | } |
| 216 | 225 | ||
| 217 | /// Toggle pin output | 226 | /// Toggle pin output |
| 227 | #[inline] | ||
| 218 | pub fn toggle(&mut self) { | 228 | pub fn toggle(&mut self) { |
| 219 | if self.is_set_low() { | 229 | if self.is_set_low() { |
| 220 | self.set_high() | 230 | self.set_high() |
| @@ -225,6 +235,7 @@ impl<'d, T: Pin> Output<'d, T> { | |||
| 225 | } | 235 | } |
| 226 | 236 | ||
| 227 | impl<'d, T: Pin> Drop for Output<'d, T> { | 237 | impl<'d, T: Pin> Drop for Output<'d, T> { |
| 238 | #[inline] | ||
| 228 | fn drop(&mut self) { | 239 | fn drop(&mut self) { |
| 229 | critical_section::with(|_| unsafe { | 240 | critical_section::with(|_| unsafe { |
| 230 | let r = self.pin.block(); | 241 | let r = self.pin.block(); |
| @@ -253,6 +264,7 @@ pub struct OutputOpenDrain<'d, T: Pin> { | |||
| 253 | } | 264 | } |
| 254 | 265 | ||
| 255 | impl<'d, T: Pin> OutputOpenDrain<'d, T> { | 266 | impl<'d, T: Pin> OutputOpenDrain<'d, T> { |
| 267 | #[inline] | ||
| 256 | pub fn new( | 268 | pub fn new( |
| 257 | pin: impl Unborrow<Target = T> + 'd, | 269 | pin: impl Unborrow<Target = T> + 'd, |
| 258 | initial_output: Level, | 270 | initial_output: Level, |
| @@ -296,37 +308,44 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> { | |||
| 296 | } | 308 | } |
| 297 | } | 309 | } |
| 298 | 310 | ||
| 311 | #[inline] | ||
| 299 | pub fn is_high(&self) -> bool { | 312 | pub fn is_high(&self) -> bool { |
| 300 | !self.is_low() | 313 | !self.is_low() |
| 301 | } | 314 | } |
| 302 | 315 | ||
| 316 | #[inline] | ||
| 303 | pub fn is_low(&self) -> bool { | 317 | pub fn is_low(&self) -> bool { |
| 304 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; | 318 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; |
| 305 | state == vals::Idr::LOW | 319 | state == vals::Idr::LOW |
| 306 | } | 320 | } |
| 307 | 321 | ||
| 308 | /// Set the output as high. | 322 | /// Set the output as high. |
| 323 | #[inline] | ||
| 309 | pub fn set_high(&mut self) { | 324 | pub fn set_high(&mut self) { |
| 310 | self.pin.set_high(); | 325 | self.pin.set_high(); |
| 311 | } | 326 | } |
| 312 | 327 | ||
| 313 | /// Set the output as low. | 328 | /// Set the output as low. |
| 329 | #[inline] | ||
| 314 | pub fn set_low(&mut self) { | 330 | pub fn set_low(&mut self) { |
| 315 | self.pin.set_low(); | 331 | self.pin.set_low(); |
| 316 | } | 332 | } |
| 317 | 333 | ||
| 318 | /// Is the output pin set as high? | 334 | /// Is the output pin set as high? |
| 335 | #[inline] | ||
| 319 | pub fn is_set_high(&self) -> bool { | 336 | pub fn is_set_high(&self) -> bool { |
| 320 | !self.is_set_low() | 337 | !self.is_set_low() |
| 321 | } | 338 | } |
| 322 | 339 | ||
| 323 | /// Is the output pin set as low? | 340 | /// Is the output pin set as low? |
| 341 | #[inline] | ||
| 324 | pub fn is_set_low(&self) -> bool { | 342 | pub fn is_set_low(&self) -> bool { |
| 325 | let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) }; | 343 | let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) }; |
| 326 | state == vals::Odr::LOW | 344 | state == vals::Odr::LOW |
| 327 | } | 345 | } |
| 328 | 346 | ||
| 329 | /// Toggle pin output | 347 | /// Toggle pin output |
| 348 | #[inline] | ||
| 330 | pub fn toggle(&mut self) { | 349 | pub fn toggle(&mut self) { |
| 331 | if self.is_set_low() { | 350 | if self.is_set_low() { |
| 332 | self.set_high() | 351 | self.set_high() |
| @@ -337,6 +356,7 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> { | |||
| 337 | } | 356 | } |
| 338 | 357 | ||
| 339 | impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> { | 358 | impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> { |
| 359 | #[inline] | ||
| 340 | fn drop(&mut self) { | 360 | fn drop(&mut self) { |
| 341 | critical_section::with(|_| unsafe { | 361 | critical_section::with(|_| unsafe { |
| 342 | let r = self.pin.block(); | 362 | let r = self.pin.block(); |
| @@ -406,6 +426,7 @@ pub(crate) mod sealed { | |||
| 406 | } | 426 | } |
| 407 | 427 | ||
| 408 | #[cfg(gpio_v1)] | 428 | #[cfg(gpio_v1)] |
| 429 | #[inline] | ||
| 409 | unsafe fn set_as_af(&self, _af_num: u8, af_type: AFType) { | 430 | unsafe fn set_as_af(&self, _af_num: u8, af_type: AFType) { |
| 410 | // F1 uses the AFIO register for remapping. | 431 | // F1 uses the AFIO register for remapping. |
| 411 | // For now, this is not implemented, so af_num is ignored | 432 | // For now, this is not implemented, so af_num is ignored |
| @@ -436,11 +457,13 @@ pub(crate) mod sealed { | |||
| 436 | } | 457 | } |
| 437 | 458 | ||
| 438 | #[cfg(gpio_v2)] | 459 | #[cfg(gpio_v2)] |
| 460 | #[inline] | ||
| 439 | unsafe fn set_as_af(&self, af_num: u8, af_type: AFType) { | 461 | unsafe fn set_as_af(&self, af_num: u8, af_type: AFType) { |
| 440 | self.set_as_af_pull(af_num, af_type, Pull::None); | 462 | self.set_as_af_pull(af_num, af_type, Pull::None); |
| 441 | } | 463 | } |
| 442 | 464 | ||
| 443 | #[cfg(gpio_v2)] | 465 | #[cfg(gpio_v2)] |
| 466 | #[inline] | ||
| 444 | unsafe fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) { | 467 | unsafe fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) { |
| 445 | let pin = self._pin() as usize; | 468 | let pin = self._pin() as usize; |
| 446 | let block = self.block(); | 469 | let block = self.block(); |
| @@ -461,6 +484,7 @@ pub(crate) mod sealed { | |||
| 461 | .modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE)); | 484 | .modify(|w| w.set_moder(pin, vals::Moder::ALTERNATE)); |
| 462 | } | 485 | } |
| 463 | 486 | ||
| 487 | #[inline] | ||
| 464 | unsafe fn set_as_analog(&self) { | 488 | unsafe fn set_as_analog(&self) { |
| 465 | let pin = self._pin() as usize; | 489 | let pin = self._pin() as usize; |
| 466 | let block = self.block(); | 490 | let block = self.block(); |
| @@ -483,11 +507,13 @@ pub(crate) mod sealed { | |||
| 483 | /// | 507 | /// |
| 484 | /// This is currently the same as set_as_analog but is semantically different really. | 508 | /// This is currently the same as set_as_analog but is semantically different really. |
| 485 | /// Drivers should set_as_disconnected pins when dropped. | 509 | /// Drivers should set_as_disconnected pins when dropped. |
| 510 | #[inline] | ||
| 486 | unsafe fn set_as_disconnected(&self) { | 511 | unsafe fn set_as_disconnected(&self) { |
| 487 | self.set_as_analog(); | 512 | self.set_as_analog(); |
| 488 | } | 513 | } |
| 489 | 514 | ||
| 490 | #[cfg(gpio_v2)] | 515 | #[cfg(gpio_v2)] |
| 516 | #[inline] | ||
| 491 | unsafe fn set_speed(&self, speed: Speed) { | 517 | unsafe fn set_speed(&self, speed: Speed) { |
| 492 | let pin = self._pin() as usize; | 518 | let pin = self._pin() as usize; |
| 493 | self.block() | 519 | self.block() |
| @@ -583,10 +609,12 @@ mod eh02 { | |||
| 583 | impl<'d, T: Pin> InputPin for Input<'d, T> { | 609 | impl<'d, T: Pin> InputPin for Input<'d, T> { |
| 584 | type Error = Infallible; | 610 | type Error = Infallible; |
| 585 | 611 | ||
| 612 | #[inline] | ||
| 586 | fn is_high(&self) -> Result<bool, Self::Error> { | 613 | fn is_high(&self) -> Result<bool, Self::Error> { |
| 587 | Ok(self.is_high()) | 614 | Ok(self.is_high()) |
| 588 | } | 615 | } |
| 589 | 616 | ||
| 617 | #[inline] | ||
| 590 | fn is_low(&self) -> Result<bool, Self::Error> { | 618 | fn is_low(&self) -> Result<bool, Self::Error> { |
| 591 | Ok(self.is_low()) | 619 | Ok(self.is_low()) |
| 592 | } | 620 | } |
| @@ -595,21 +623,25 @@ mod eh02 { | |||
| 595 | impl<'d, T: Pin> OutputPin for Output<'d, T> { | 623 | impl<'d, T: Pin> OutputPin for Output<'d, T> { |
| 596 | type Error = Infallible; | 624 | type Error = Infallible; |
| 597 | 625 | ||
| 626 | #[inline] | ||
| 598 | fn set_high(&mut self) -> Result<(), Self::Error> { | 627 | fn set_high(&mut self) -> Result<(), Self::Error> { |
| 599 | Ok(self.set_high()) | 628 | Ok(self.set_high()) |
| 600 | } | 629 | } |
| 601 | 630 | ||
| 631 | #[inline] | ||
| 602 | fn set_low(&mut self) -> Result<(), Self::Error> { | 632 | fn set_low(&mut self) -> Result<(), Self::Error> { |
| 603 | Ok(self.set_low()) | 633 | Ok(self.set_low()) |
| 604 | } | 634 | } |
| 605 | } | 635 | } |
| 606 | 636 | ||
| 607 | impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> { | 637 | impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> { |
| 638 | #[inline] | ||
| 608 | fn is_set_high(&self) -> Result<bool, Self::Error> { | 639 | fn is_set_high(&self) -> Result<bool, Self::Error> { |
| 609 | Ok(self.is_set_high()) | 640 | Ok(self.is_set_high()) |
| 610 | } | 641 | } |
| 611 | 642 | ||
| 612 | /// Is the output pin set as low? | 643 | /// Is the output pin set as low? |
| 644 | #[inline] | ||
| 613 | fn is_set_low(&self) -> Result<bool, Self::Error> { | 645 | fn is_set_low(&self) -> Result<bool, Self::Error> { |
| 614 | Ok(self.is_set_low()) | 646 | Ok(self.is_set_low()) |
| 615 | } | 647 | } |
| @@ -617,6 +649,7 @@ mod eh02 { | |||
| 617 | 649 | ||
| 618 | impl<'d, T: Pin> ToggleableOutputPin for Output<'d, T> { | 650 | impl<'d, T: Pin> ToggleableOutputPin for Output<'d, T> { |
| 619 | type Error = Infallible; | 651 | type Error = Infallible; |
| 652 | #[inline] | ||
| 620 | fn toggle(&mut self) -> Result<(), Self::Error> { | 653 | fn toggle(&mut self) -> Result<(), Self::Error> { |
| 621 | Ok(self.toggle()) | 654 | Ok(self.toggle()) |
| 622 | } | 655 | } |
| @@ -625,21 +658,25 @@ mod eh02 { | |||
| 625 | impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> { | 658 | impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> { |
| 626 | type Error = Infallible; | 659 | type Error = Infallible; |
| 627 | 660 | ||
| 661 | #[inline] | ||
| 628 | fn set_high(&mut self) -> Result<(), Self::Error> { | 662 | fn set_high(&mut self) -> Result<(), Self::Error> { |
| 629 | Ok(self.set_high()) | 663 | Ok(self.set_high()) |
| 630 | } | 664 | } |
| 631 | 665 | ||
| 666 | #[inline] | ||
| 632 | fn set_low(&mut self) -> Result<(), Self::Error> { | 667 | fn set_low(&mut self) -> Result<(), Self::Error> { |
| 633 | Ok(self.set_low()) | 668 | Ok(self.set_low()) |
| 634 | } | 669 | } |
| 635 | } | 670 | } |
| 636 | 671 | ||
| 637 | impl<'d, T: Pin> StatefulOutputPin for OutputOpenDrain<'d, T> { | 672 | impl<'d, T: Pin> StatefulOutputPin for OutputOpenDrain<'d, T> { |
| 673 | #[inline] | ||
| 638 | fn is_set_high(&self) -> Result<bool, Self::Error> { | 674 | fn is_set_high(&self) -> Result<bool, Self::Error> { |
| 639 | Ok(self.is_set_high()) | 675 | Ok(self.is_set_high()) |
| 640 | } | 676 | } |
| 641 | 677 | ||
| 642 | /// Is the output pin set as low? | 678 | /// Is the output pin set as low? |
| 679 | #[inline] | ||
| 643 | fn is_set_low(&self) -> Result<bool, Self::Error> { | 680 | fn is_set_low(&self) -> Result<bool, Self::Error> { |
| 644 | Ok(self.is_set_low()) | 681 | Ok(self.is_set_low()) |
| 645 | } | 682 | } |
| @@ -647,6 +684,7 @@ mod eh02 { | |||
| 647 | 684 | ||
| 648 | impl<'d, T: Pin> ToggleableOutputPin for OutputOpenDrain<'d, T> { | 685 | impl<'d, T: Pin> ToggleableOutputPin for OutputOpenDrain<'d, T> { |
| 649 | type Error = Infallible; | 686 | type Error = Infallible; |
| 687 | #[inline] | ||
| 650 | fn toggle(&mut self) -> Result<(), Self::Error> { | 688 | fn toggle(&mut self) -> Result<(), Self::Error> { |
| 651 | Ok(self.toggle()) | 689 | Ok(self.toggle()) |
| 652 | } | 690 | } |
