1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153
//! Support for hardware buttons. //! //! # Scope //! //! This module provides: //! - a lower-level interface for reading a button or switch's state //! - optional 'debouncing' //! - a higher-level interface for retrieving button events, including: //! - simple 'click' events //! - support for treating two buttons as a single device, with a 'clicked //! both' event //! - support for detecting 'hold' (long press) events //! - convenience APIs for using these features with the built-in buttons //! //! # Polling model //! //! This module's client is responsible for calling polling functions at //! regular intervals (nothing in this module itself uses interrupts or //! timers). //! //! The intended polling interval is 6ms. //! //! In practice it appears no debouncing is needed for the micro:bit's //! built-in buttons given this polling interval, so by default no debouncing //! is applied. //! //! With a 6ms polling interval, the 'with hold' drivers report a hold event //! after a press 1.5s long. //! //! # Usage //! //! The simplest way to access the higher-level features is via one of the //! high-level driver modules: //! - [`single_eager`] //! - [`single_lazy`] //! - [`single_with_hold`] //! - [`dual`] //! - [`dual_with_hold`] //! //! Each of these modules defines a similar interface, including a //! `ButtonEvent` enum and either a `Monitor` type for each button or a //! `Monitor` type for both buttons treated as a single device. //! //! Each `Monitor` type defines a `new()` method which expects a [`ButtonA`], //! a [`ButtonB`], or one of each. //! //! Use the [`from_pins()`] function to retrieve [`ButtonA`] and [`ButtonB`]. //! //! Each `Monitor` type defines a `poll()` method which returns an //! `Option(ButtonEvent)`; this method should be called at regular intervals //! (in practice every 6ms). //! //! ## Lower-level access //! //! See the [`core`] module if none of the event types above are suitable for //! your purposes, or to use an external button. //! //! See the [`debouncing`] module if you need to control debouncing behaviour. //! //! # Examples //! //! ```ignore //! use rmicrobit::prelude::*; //! use rmicrobit::gpio::PinsByKind; //! use rmicrobit::buttons; //! use rmicrobit::buttons::dual::{ABMonitor, ButtonEvent}; //! let p: nrf51::Peripherals = _; //! let PinsByKind {button_pins, ..} = p.GPIO.split_by_kind(); //! let (button_a, button_b) = buttons::from_pins(button_pins); //! let monitor = ABMonitor::new(button_a, button_b); //! loop { //! // every 6ms //! match monitor.poll() { //! Some(ButtonEvent::ClickA) => { ... } //! Some(ButtonEvent::ClickB) => { ... } //! Some(ButtonEvent::ClickAB) => { ... } //! None => {} //! } //! } //! ``` //! //! See `examples/use_single_button_monitor.rs` and //! `examples/use_dual_button_monitor.rs` for complete examples. //! //! [`single_eager`]: crate::buttons::single_eager //! [`single_lazy`]: crate::buttons::single_lazy //! [`single_with_hold`]: crate::buttons::single_with_hold //! [`dual`]: crate::buttons::dual //! [`dual_with_hold`]: crate::buttons::dual_with_hold //! [`from_pins()`]: crate::buttons::from_pins //! [`ButtonA`]: crate::buttons::builtin::ButtonA //! [`ButtonB`]: crate::buttons::builtin::ButtonB pub use crate::buttons::builtin::from_pins; pub mod builtin; pub mod core; pub mod debouncing; /// Implementations of the high-level button drivers. pub mod monitors { pub mod holding; pub mod single; pub mod dual; pub mod single_with_hold; pub mod dual_with_hold; } /// High-level driver for a single button, with events on press. pub mod single_eager { pub use crate::buttons::monitors::single::Event as ButtonEvent; pub use crate::buttons::builtin::{ EagerButtonAMonitor as ButtonAMonitor, EagerButtonBMonitor as ButtonBMonitor, }; } /// High-level driver for a single button, with events on release. pub mod single_lazy { pub use crate::buttons::monitors::single::Event as ButtonEvent; pub use crate::buttons::builtin::{ LazyButtonAMonitor as ButtonAMonitor, LazyButtonBMonitor as ButtonBMonitor, }; } /// High-level driver for two buttons together. pub mod dual { pub use crate::buttons::monitors::dual::Event as ButtonEvent; pub use crate::buttons::builtin::{ ABMonitor, }; } /// High-level driver for a single button, with 'hold' support. pub mod single_with_hold { pub use crate::buttons::monitors::single_with_hold::Event as ButtonEvent; pub use crate::buttons::builtin::{ ButtonAMonitorWithHold as ButtonAMonitor, ButtonBMonitorWithHold as ButtonBMonitor, }; } /// High-level driver for two buttons together, with 'hold' support. pub mod dual_with_hold { pub use crate::buttons::monitors::dual_with_hold::Event as ButtonEvent; pub use crate::buttons::builtin::{ ABMonitorWithHold as ABMonitor, }; }