Skip to main content

rmicrobit/
gpio.rs

1//! Support for the GPIO peripheral.
2//!
3//! The types in this module provide structured access to the micro:bit's GPIO
4//! pins, organised in functional groups.
5//!
6//! This system supports working with different devices without having to
7//! manage a shared reference to the single GPIO peripheral.
8//!
9//! The structs don't hold any data at runtime; they exist to manage ownership
10//! of the pins.
11//!
12//! Use `GPIO.split_by_kind()` to retrieve one instance of each Xxx`Pins` type.
13//!
14//! # Example
15//!
16//! ```
17//! use rmicrobit::prelude::*;
18//! use rmicrobit::gpio::PinsByKind;
19//! let p: nrf51::Peripherals = _;
20//! let PinsByKind {display_pins, button_pins, ..} = p.GPIO.split_by_kind();
21//! ```
22
23use crate::nrf51::GPIO;
24use nrf51_hal::gpio::{Input, Floating, GpioExt};
25
26
27/// The GPIO pins connected to the micro:bit's LED display.
28///
29/// See also [`pin_constants`] for dealing with these pin numbers.
30///
31/// [`pin_constants`]: crate::display::display_port::pin_constants
32///
33/// The pins for columns 1,2,3,7,8,9 are also presented on the edge connector.
34pub struct DisplayPins {
35    /// The GPIO pin connected to LED matrix column 1
36    ///
37    /// Also connected to edge connector strip 3
38    pub pin4: nrf51_hal::gpio::gpio::PIN4<Input<Floating>>,
39    /// The GPIO pin connected to LED matrix column 2
40    ///
41    /// Also connected to edge connector strip 4
42    pub pin5: nrf51_hal::gpio::gpio::PIN5<Input<Floating>>,
43    /// The GPIO pin connected to LED matrix column 3
44    ///
45    /// Also connected to edge connector strip 10
46    pub pin6: nrf51_hal::gpio::gpio::PIN6<Input<Floating>>,
47    /// The GPIO pin connected to LED matrix column 4
48    pub pin7: nrf51_hal::gpio::gpio::PIN7<Input<Floating>>,
49    /// The GPIO pin connected to LED matrix column 5
50    pub pin8: nrf51_hal::gpio::gpio::PIN8<Input<Floating>>,
51    /// The GPIO pin connected to LED matrix column 6
52    pub pin9: nrf51_hal::gpio::gpio::PIN9<Input<Floating>>,
53    /// The GPIO pin connected to LED matrix column 7
54    ///
55    /// Also connected to edge connector strip 9
56    pub pin10: nrf51_hal::gpio::gpio::PIN10<Input<Floating>>,
57    /// The GPIO pin connected to LED matrix column 8
58    ///
59    /// Also connected to edge connector strip 7
60    pub pin11: nrf51_hal::gpio::gpio::PIN11<Input<Floating>>,
61    /// The GPIO pin connected to LED matrix column 9
62    ///
63    /// Also connected to edge connector strip 6
64    pub pin12: nrf51_hal::gpio::gpio::PIN12<Input<Floating>>,
65    /// The GPIO pin connected to LED matrix row 1
66    pub pin13: nrf51_hal::gpio::gpio::PIN13<Input<Floating>>,
67    /// The GPIO pin connected to LED matrix row 2
68    pub pin14: nrf51_hal::gpio::gpio::PIN14<Input<Floating>>,
69    /// The GPIO pin connected to LED matrix row 3
70    pub pin15: nrf51_hal::gpio::gpio::PIN15<Input<Floating>>,
71}
72
73/// The GPIO pins connected to the micro:bit's user buttons.
74pub struct ButtonPins {
75    /// The GPIO pin connected to Button A.
76    pub pin17: nrf51_hal::gpio::gpio::PIN17<Input<Floating>>,
77    /// The GPIO pin connected to Button B.
78    pub pin26: nrf51_hal::gpio::gpio::PIN26<Input<Floating>>,
79}
80
81/// The GPIO pins connected to the micro:bit's USB serial port.
82///
83/// These pins are directly connected to the on-board Kinetis interface MCU,
84/// which then makes the serial connection available over USB.
85pub struct SerialPins {
86    /// The 'tx' GPIO pin (micro:bit to USB)
87    pub pin24: nrf51_hal::gpio::gpio::PIN24<Input<Floating>>,
88    /// The 'rx' GPIO pin (USB to micro:bit)
89    pub pin25: nrf51_hal::gpio::gpio::PIN25<Input<Floating>>,
90}
91
92/// The GPIO pins used for the micro:bit's I2C interface.
93///
94/// These pins are connected to the internal I2C devices (the accelerometer
95/// and magnetometer), and are also presented on the edge connector.
96pub struct I2cPins {
97    /// The I2C SCL (clock) GPIO pin.
98    ///
99    /// Also connected to edge connector strip 19.
100    pub pin0: nrf51_hal::gpio::gpio::PIN0<Input<Floating>>,
101    /// The I2C SDA (data) GPIO pin.
102    ///
103    /// Also connected to edge connector strip 20.
104    pub pin30: nrf51_hal::gpio::gpio::PIN30<Input<Floating>>,
105}
106
107/// The GPIO pins available on the edge connector and not otherwise connected.
108///
109/// The edge-connector pins included in [`DisplayPins`] and [`I2cPins`] are
110/// excluded from this struct.
111pub struct EdgeConnectorPins {
112    /// The GPIO pin connected to edge connector ring 2
113    pub pin1: nrf51_hal::gpio::gpio::PIN1<Input<Floating>>,
114    /// The GPIO pin connected to edge connector ring 1
115    pub pin2: nrf51_hal::gpio::gpio::PIN2<Input<Floating>>,
116    /// The GPIO pin connected to edge connector ring 0
117    pub pin3: nrf51_hal::gpio::gpio::PIN3<Input<Floating>>,
118    /// The GPIO pin connected to edge connector strip 16
119    pub pin16: nrf51_hal::gpio::gpio::PIN16<Input<Floating>>,
120    /// The GPIO pin connected to edge connector strip 8
121    pub pin18: nrf51_hal::gpio::gpio::PIN18<Input<Floating>>,
122    /// The GPIO pin connected to edge connector strip 12
123    pub pin20: nrf51_hal::gpio::gpio::PIN20<Input<Floating>>,
124    /// The GPIO pin connected to edge connector strip 15
125    ///
126    /// Conventionally used for SPI MOSI.
127    pub pin21: nrf51_hal::gpio::gpio::PIN21<Input<Floating>>,
128    /// The GPIO pin connected to edge connector strip 14
129    ///
130    /// Conventionally used for SPI MISO.
131    pub pin22: nrf51_hal::gpio::gpio::PIN22<Input<Floating>>,
132    /// The GPIO pin connected to edge connector strip 13
133    ///
134    /// Conventionally used for SPI SCK.
135    pub pin23: nrf51_hal::gpio::gpio::PIN23<Input<Floating>>,
136}
137
138/// The remaining GPIO pins.
139///
140/// As far as I know none of these pins have any use.
141pub struct OtherPins {
142    pub pin19: nrf51_hal::gpio::gpio::PIN19<Input<Floating>>,
143    pub pin27: nrf51_hal::gpio::gpio::PIN27<Input<Floating>>,
144    pub pin28: nrf51_hal::gpio::gpio::PIN28<Input<Floating>>,
145    pub pin29: nrf51_hal::gpio::gpio::PIN29<Input<Floating>>,
146    pub pin31: nrf51_hal::gpio::gpio::PIN31<Input<Floating>>,
147}
148
149/// The micro:bit's GPIO pins, organised in functional groups.
150pub struct PinsByKind {
151    pub display_pins: DisplayPins,
152    pub button_pins: ButtonPins,
153    pub serial_pins: SerialPins,
154    pub i2c_pins: I2cPins,
155    pub edge_connector_pins: EdgeConnectorPins,
156    pub other_pins: OtherPins,
157    _reserved: (),
158}
159
160/// Extension trait to split the GPIO peripheral into functional groups.
161pub trait MicrobitGpioExt {
162    /// Splits the GPIO peripheral into groups of pins.
163    fn split_by_kind(self) -> PinsByKind;
164}
165
166impl MicrobitGpioExt for GPIO {
167
168    fn split_by_kind(self) -> PinsByKind {
169        let parts = self.split();
170        let display_pins = DisplayPins {
171            pin4: parts.pin4,
172            pin5: parts.pin5,
173            pin6: parts.pin6,
174            pin7: parts.pin7,
175            pin8: parts.pin8,
176            pin9: parts.pin9,
177            pin10: parts.pin10,
178            pin11: parts.pin11,
179            pin12: parts.pin12,
180            pin13: parts.pin13,
181            pin14: parts.pin14,
182            pin15: parts.pin15,
183        };
184        let button_pins = ButtonPins {
185            pin17: parts.pin17,
186            pin26: parts.pin26,
187        };
188        let serial_pins = SerialPins {
189            pin24: parts.pin24,
190            pin25: parts.pin25,
191        };
192        let i2c_pins = I2cPins {
193            pin0: parts.pin0,
194            pin30: parts.pin30,
195        };
196        let edge_connector_pins = EdgeConnectorPins {
197            pin1: parts.pin1,
198            pin2: parts.pin2,
199            pin3: parts.pin3,
200            pin16: parts.pin16,
201            pin18: parts.pin18,
202            pin20: parts.pin20,
203            pin21: parts.pin21,
204            pin22: parts.pin22,
205            pin23: parts.pin23,
206        };
207        let other_pins = OtherPins {
208            pin19: parts.pin19,
209            pin27: parts.pin27,
210            pin28: parts.pin28,
211            pin29: parts.pin29,
212            pin31: parts.pin31,
213        };
214        PinsByKind{
215            display_pins,
216            button_pins,
217            serial_pins,
218            i2c_pins,
219            edge_connector_pins,
220            other_pins,
221            _reserved: (),
222        }
223    }
224
225}
226