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