microbit_common/v2/
board.rs

1use super::gpio::{
2    DisplayPins, MicrophonePins, BTN_A, BTN_B, EDGE00, EDGE01, EDGE02, EDGE08, EDGE09, EDGE12,
3    EDGE16, INT_SCL, INT_SDA, SCL, SDA, UART_RX, UART_TX,
4};
5use crate::{
6    hal::{
7        gpio::{p0, p1, Disconnected, Level, OpenDrainConfig::Disconnect0HighDrive1},
8        twim, twis, uarte,
9    },
10    pac,
11};
12
13/// Provides access to the microbit
14#[allow(non_snake_case)]
15pub struct Board {
16    /// GPIO pins that are not otherwise used
17    pub pins: Pins,
18
19    /// Unused GPIO pins on edge connector
20    pub edge: Edge,
21
22    /// display pins
23    pub display_pins: DisplayPins,
24
25    /// buttons
26    pub buttons: Buttons,
27
28    /// speaker
29    pub speaker_pin: p0::P0_00<Disconnected>,
30
31    /// microphone pins
32    pub microphone_pins: MicrophonePins,
33
34    /// I2C internal bus pins
35    pub i2c_internal: I2CInternalPins,
36
37    /// I2C external bus pins
38    pub i2c_external: I2CExternalPins,
39
40    /// UART to debugger pins
41    pub uart: UartPins,
42
43    /// Core peripheral: Cache and branch predictor maintenance operations
44    pub CBP: pac::CBP,
45
46    /// Core peripheral: CPUID
47    pub CPUID: pac::CPUID,
48
49    /// Core peripheral: Debug Control Block
50    pub DCB: pac::DCB,
51
52    /// Core peripheral: Data Watchpoint and Trace unit
53    pub DWT: pac::DWT,
54
55    /// Core peripheral: Flash Patch and Breakpoint unit
56    pub FPB: pac::FPB,
57
58    /// Core peripheral: Floating Point Unit
59    pub FPU: pac::FPU,
60
61    /// Core peripheral: Instrumentation Trace Macrocell
62    pub ITM: pac::ITM,
63
64    /// Core peripheral: Memory Protection Unit
65    pub MPU: pac::MPU,
66
67    /// Core peripheral: Nested Vector Interrupt Controller
68    pub NVIC: pac::NVIC,
69
70    /// Core peripheral: System Control Block
71    pub SCB: pac::SCB,
72
73    /// Core peripheral: SysTick Timer
74    pub SYST: pac::SYST,
75
76    /// Core peripheral: Trace Port Interface Unit
77    pub TPIU: pac::TPIU,
78
79    /// nRF52 peripheral: CLOCK
80    pub CLOCK: pac::CLOCK,
81
82    /// nRF52 peripheral: FICR
83    pub FICR: pac::FICR,
84
85    /// nRF52 peripheral: GPIOTE
86    pub GPIOTE: pac::GPIOTE,
87
88    /// nRF52 preipheral: PPI
89    pub PPI: pac::PPI,
90
91    /// nRF52 peripheral: PWM0
92    pub PWM0: pac::PWM0,
93
94    /// nRF52 peripheral: PWM1
95    pub PWM1: pac::PWM1,
96
97    /// nRF52 peripheral: PWM2
98    pub PWM2: pac::PWM2,
99
100    /// nRF52 peripheral: PWM3
101    pub PWM3: pac::PWM3,
102
103    /// nRF52 peripheral: RADIO
104    pub RADIO: pac::RADIO,
105
106    /// nRF52 peripheral: RNG
107    pub RNG: pac::RNG,
108
109    /// nRF52 peripheral: RTC0
110    pub RTC0: pac::RTC0,
111
112    /// nRF52 peripheral: RTC1
113    pub RTC1: pac::RTC1,
114
115    /// nRF52 peripheral: RTC2
116    pub RTC2: pac::RTC2,
117
118    /// nRF52 peripheral: TEMP <br>
119    /// Can be used with [`Temp::new()`](`crate::hal::temp::Temp::new()`)
120    pub TEMP: pac::TEMP,
121
122    /// nRF52 peripheral: TIMER0
123    pub TIMER0: pac::TIMER0,
124
125    /// nRF52 peripheral: TIMER1
126    pub TIMER1: pac::TIMER1,
127
128    /// nRF52 peripheral: TIMER2
129    pub TIMER2: pac::TIMER2,
130
131    /// nRF52 peripheral: TIMER3
132    pub TIMER3: pac::TIMER3,
133
134    /// nRF52 peripheral: TIMER4
135    pub TIMER4: pac::TIMER4,
136
137    /// nRF52 peripheral: TWIM0
138    pub TWIM0: pac::TWIM0,
139
140    /// nRF52 peripheral: TWIS0
141    pub TWIS0: pac::TWIS0,
142
143    /// nRF52 peripheral: UARTE0
144    pub UARTE0: pac::UARTE0,
145
146    /// nRF52 peripheral: UARTE1
147    pub UARTE1: pac::UARTE1,
148
149    /// nRF52 peripheral: SAADC
150    pub ADC: pac::SAADC,
151
152    /// nRF52 peripheral: POWER
153    pub POWER: pac::POWER,
154
155    /// nRF52 peripheral: SPI0
156    pub SPI0: pac::SPI0,
157
158    /// nRF52 peripheral: SPI1
159    pub SPI1: pac::SPI1,
160
161    /// nRF52 peripheral: SPI2
162    pub SPI2: pac::SPI2,
163
164    /// nRF52 peripheral: UART0
165    pub UART0: pac::UART0,
166
167    /// nRF52 peripheral: TWI0
168    pub TWI0: pac::TWI0,
169
170    /// nRF52 peripheral: TWI1
171    pub TWI1: pac::TWI1,
172
173    /// nRF52 peripheral: SPIS1
174    pub SPIS1: pac::SPIS1,
175
176    /// nRF52 peripheral: ECB
177    pub ECB: pac::ECB,
178
179    /// nRF52 peripheral: AAR
180    pub AAR: pac::AAR,
181
182    /// nRF52 peripheral: CCM
183    pub CCM: pac::CCM,
184
185    /// nRF52 peripheral: WDT
186    pub WDT: pac::WDT,
187
188    /// nRF52 peripheral: QDEC
189    pub QDEC: pac::QDEC,
190
191    /// nRF52 peripheral: LPCOMP
192    pub LPCOMP: pac::LPCOMP,
193
194    /// nRF52 peripheral: NVMC
195    pub NVMC: pac::NVMC,
196
197    /// nRF52 peripheral: UICR
198    pub UICR: pac::UICR,
199}
200
201impl Board {
202    /// Take the peripherals safely
203    ///
204    /// This method will return an instance of the board the first time it is
205    /// called. It will return only `None` on subsequent calls.
206    /// This function can also return `None` if one of the the peripherals was
207    /// already taken.
208    pub fn take() -> Option<Self> {
209        Some(Self::new(
210            pac::Peripherals::take()?,
211            pac::CorePeripherals::take()?,
212        ))
213    }
214
215    /// Fallback method in the case peripherals and core peripherals were taken
216    /// elsewhere already.
217    ///
218    /// This method will take the peripherals and core peripherals and
219    /// return an instance of the board.
220    ///
221    /// An exemplary usecase is shown in the rtic display example.
222    pub fn new(p: pac::Peripherals, cp: pac::CorePeripherals) -> Self {
223        let p0parts = p0::Parts::new(p.P0);
224        let p1parts = p1::Parts::new(p.P1);
225        Self {
226            pins: Pins {
227                p0_01: p0parts.p0_01,
228                //p0_02: p0parts.p0_02,
229                //p0_03: p0parts.p0_03,
230                //p0_04: p0parts.p0_04,
231                p0_07: p0parts.p0_07,
232                //p0_09: p0parts.p0_09,
233                //p0_10: p0parts.p0_10,
234                //p0_12: p0parts.p0_12,
235                p0_13: p0parts.p0_13,
236                p0_17: p0parts.p0_17,
237                p0_18: p0parts.p0_18,
238                p0_25: p0parts.p0_25,
239                p0_27: p0parts.p0_27,
240                p0_29: p0parts.p0_29,
241                p1_01: p1parts.p1_01,
242                //p1_02: p1parts.p1_02,
243                p1_03: p1parts.p1_03,
244                p1_04: p1parts.p1_04,
245                p1_06: p1parts.p1_06,
246                p1_07: p1parts.p1_07,
247                p1_09: p1parts.p1_09,
248            },
249            edge: Edge {
250                e00: p0parts.p0_02,
251                e01: p0parts.p0_03,
252                e02: p0parts.p0_04,
253                e08: p0parts.p0_10,
254                e09: p0parts.p0_09,
255                e12: p0parts.p0_12,
256                e16: p1parts.p1_02,
257            },
258            display_pins: DisplayPins {
259                col1: p0parts.p0_28.into_push_pull_output(Level::High),
260                col2: p0parts.p0_11.into_push_pull_output(Level::High),
261                col3: p0parts.p0_31.into_push_pull_output(Level::High),
262                col4: p1parts.p1_05.into_push_pull_output(Level::High),
263                col5: p0parts.p0_30.into_push_pull_output(Level::High),
264                row1: p0parts.p0_21.into_push_pull_output(Level::Low),
265                row2: p0parts.p0_22.into_push_pull_output(Level::Low),
266                row3: p0parts.p0_15.into_push_pull_output(Level::Low),
267                row4: p0parts.p0_24.into_push_pull_output(Level::Low),
268                row5: p0parts.p0_19.into_push_pull_output(Level::Low),
269            },
270            buttons: Buttons {
271                button_a: p0parts.p0_14.into_floating_input(),
272                button_b: p0parts.p0_23.into_floating_input(),
273            },
274            speaker_pin: p0parts.p0_00,
275            microphone_pins: MicrophonePins {
276                mic_in: p0parts.p0_05.into_floating_input(),
277                mic_run: p0parts
278                    .p0_20
279                    .into_open_drain_output(Disconnect0HighDrive1, Level::Low),
280            },
281            i2c_internal: I2CInternalPins {
282                scl: p0parts.p0_08.into_floating_input(),
283                sda: p0parts.p0_16.into_floating_input(),
284            },
285            i2c_external: I2CExternalPins {
286                scl: p0parts.p0_26.into_floating_input(),
287                sda: p1parts.p1_00.into_floating_input(),
288            },
289            uart: UartPins {
290                tx: p0parts.p0_06.into_push_pull_output(Level::High),
291                rx: p1parts.p1_08.into_floating_input(),
292            },
293
294            // Core peripherals
295            CBP: cp.CBP,
296            CPUID: cp.CPUID,
297            DCB: cp.DCB,
298            DWT: cp.DWT,
299            FPB: cp.FPB,
300            FPU: cp.FPU,
301            ITM: cp.ITM,
302            MPU: cp.MPU,
303            NVIC: cp.NVIC,
304            SCB: cp.SCB,
305            SYST: cp.SYST,
306            TPIU: cp.TPIU,
307
308            // nRF52 peripherals
309            CLOCK: p.CLOCK,
310            FICR: p.FICR,
311            GPIOTE: p.GPIOTE,
312            PPI: p.PPI,
313            PWM0: p.PWM0,
314            PWM1: p.PWM1,
315            PWM2: p.PWM2,
316            PWM3: p.PWM3,
317            RADIO: p.RADIO,
318            RNG: p.RNG,
319            RTC0: p.RTC0,
320            RTC1: p.RTC1,
321            RTC2: p.RTC2,
322            TEMP: p.TEMP,
323            TIMER0: p.TIMER0,
324            TIMER1: p.TIMER1,
325            TIMER2: p.TIMER2,
326            TIMER3: p.TIMER3,
327            TIMER4: p.TIMER4,
328            TWIM0: p.TWIM0,
329            TWIS0: p.TWIS0,
330            UARTE0: p.UARTE0,
331            UARTE1: p.UARTE1,
332            ADC: p.SAADC,
333            SPI0: p.SPI0,
334            SPI1: p.SPI1,
335            SPI2: p.SPI2,
336            POWER: p.POWER,
337            UART0: p.UART0,
338            TWI0: p.TWI0,
339            TWI1: p.TWI1,
340            SPIS1: p.SPIS1,
341            ECB: p.ECB,
342            AAR: p.AAR,
343            CCM: p.CCM,
344            WDT: p.WDT,
345            QDEC: p.QDEC,
346            LPCOMP: p.LPCOMP,
347            NVMC: p.NVMC,
348            UICR: p.UICR,
349        }
350    }
351}
352
353/// Unused GPIO pins
354#[allow(missing_docs)]
355pub struct Pins {
356    // pub p0_00: p0::P0_00<Disconnected>, // Speaker
357    pub p0_01: p0::P0_01<Disconnected>,
358    // pub p0_02: p0::P0_02<Disconnected>, // PAD0, EDGE00
359    // pub p0_03: p0::P0_03<Disconnected>, // PAD1, EDGE01
360    // pub p0_04: p0::P0_04<Disconnected>, // PAD2, EDGE02
361    // pub p0_05: p0::P0_05<Disconnected>, // Microphone IN
362    // pub p0_06: p0::P0_06<Disconnected>, // UART RX
363    pub p0_07: p0::P0_07<Disconnected>,
364    // pub p0_08: p0::P0_08<Disconnected>, // INT_SCL
365    // pub p0_09: p0::P0_09<Disconnected>, // EDGE09
366    // pub p0_10: p0::P0_10<Disconnected>, // EDGE08
367    // pub p0_11: p0::P0_11<Disconnected>, // LEDs
368    // pub p0_12: p0::P0_12<Disconnected>, // EDGE12
369    pub p0_13: p0::P0_13<Disconnected>,
370    // pub p0_14: p0::P0_14<Disconnected>, // BTN_A
371    // pub p0_15: p0::P0_15<Disconnected>, // LEDs
372    // pub p0_16: p0::P0_16<Disconnected>, // INT_SDA
373    pub p0_17: p0::P0_17<Disconnected>,
374    pub p0_18: p0::P0_18<Disconnected>,
375    // pub p0_19: p0::P0_19<Disconnected>, // LEDs
376    // pub p0_20: p0::P0_20<Disconnected>, // Microphone RUN
377    // pub p0_21: p0::P0_21<Disconnected>, // LEDs
378    // pub p0_22: p0::P0_22<Disconnected>, // LEDs
379    // pub p0_23: p0::P0_23<Disconnected>, // BTN_B
380    // pub p0_24: p0::P0_24<Disconnected>, // LEDs
381    pub p0_25: p0::P0_25<Disconnected>,
382    // pub p0_26: p0::P0_26<Disconnected>, // SCL
383    pub p0_27: p0::P0_27<Disconnected>,
384    // pub p0_28: p0::P0_28<Disconnected>, // LEDs
385    pub p0_29: p0::P0_29<Disconnected>,
386    // pub p0_30: p0::P0_30<Disconnected>, // LEDs
387    // pub p0_31: p0::P0_31<Disconnected>, // LEDs
388    // pub p1_00: p1::P1_00<Disconnected>, // SDA
389    pub p1_01: p1::P1_01<Disconnected>,
390    // pub p1_02: p1::P1_02<Disconnected>, // EDGE16
391    pub p1_03: p1::P1_03<Disconnected>,
392    pub p1_04: p1::P1_04<Disconnected>,
393    // pub p1_05: p1::P1_05<Disconnected>, // LEDs
394    pub p1_06: p1::P1_06<Disconnected>,
395    pub p1_07: p1::P1_07<Disconnected>,
396    // pub p1_08: p1::P1_08<Disconnected>, // UART TX
397    pub p1_09: p1::P1_09<Disconnected>,
398}
399
400/// Unused edge connector pins
401#[allow(missing_docs)]
402pub struct Edge {
403    /* edge connector */
404    // pub e03: COL3,
405    pub e00: EDGE00<Disconnected>, // <- big pad 1
406    // pub e04: COL1,
407    // pub e05: BTN_A,
408    // pub e06: COL4,
409    // pub e07: COL2,
410    pub e01: EDGE01<Disconnected>, // <- big pad 2
411    pub e08: EDGE08<Disconnected>,
412    pub e09: EDGE09<Disconnected>,
413    // pub e10: COL5,
414    // pub e11: BTN_B,
415    pub e12: EDGE12<Disconnected>,
416    pub e02: EDGE02<Disconnected>, // <- big pad 3
417    //pub e13<MODE>: SCK<MODE>,
418    //pub e14<MODE>: MISO<MODE>,
419    //pub e15<MODE>: MOSI<MODE>,
420    pub e16: EDGE16<Disconnected>,
421    // +V
422    // +V
423    // +V
424    // pub e19: SCL,
425    // pub e20: SDA,
426    // GND
427    // GND
428    // GND
429}
430
431/// Buttons
432pub struct Buttons {
433    /// Left hand button
434    pub button_a: BTN_A,
435    /// Right hand button
436    pub button_b: BTN_B,
437}
438
439/// I2C internal bus pins
440pub struct I2CInternalPins {
441    /// Internal I2C clock pin
442    pub scl: INT_SCL,
443    /// Internal I2C data pin
444    pub sda: INT_SDA,
445}
446
447impl From<I2CInternalPins> for twim::Pins {
448    fn from(pins: I2CInternalPins) -> Self {
449        Self {
450            scl: pins.scl.degrade(),
451            sda: pins.sda.degrade(),
452        }
453    }
454}
455
456impl From<I2CInternalPins> for twis::Pins {
457    fn from(pins: I2CInternalPins) -> Self {
458        Self {
459            scl: pins.scl.degrade(),
460            sda: pins.sda.degrade(),
461        }
462    }
463}
464
465/// I2C external bus pins
466pub struct I2CExternalPins {
467    /// External I2C clock pin
468    pub scl: SCL,
469    /// External I2C data pin
470    pub sda: SDA,
471}
472
473impl From<I2CExternalPins> for twim::Pins {
474    fn from(pins: I2CExternalPins) -> Self {
475        Self {
476            scl: pins.scl.degrade(),
477            sda: pins.sda.degrade(),
478        }
479    }
480}
481
482impl From<I2CExternalPins> for twis::Pins {
483    fn from(pins: I2CExternalPins) -> Self {
484        Self {
485            scl: pins.scl.degrade(),
486            sda: pins.sda.degrade(),
487        }
488    }
489}
490
491/// UART to debugger pins
492pub struct UartPins {
493    tx: UART_TX,
494    rx: UART_RX,
495}
496
497impl From<UartPins> for uarte::Pins {
498    fn from(pins: UartPins) -> Self {
499        Self {
500            txd: pins.tx.degrade(),
501            rxd: pins.rx.degrade(),
502            cts: None,
503            rts: None,
504        }
505    }
506}