nrf52840_dk_bsp/
lib.rs

1//! Board support crate for the Nordic nRF52840-DK
2//!
3//! UARTE, SPIM and TWI should be functional,
4//! but might miss some features.
5#![no_std]
6
7pub use cortex_m;
8pub use embedded_hal;
9pub use nrf52840_hal as hal;
10
11/// Exports traits that are usually needed when using this crate
12pub mod prelude {
13    pub use nrf52840_hal::prelude::*;
14}
15
16// TODO: Maybe we want a debug module like in the DWM1001-Dev implementation.
17// pub mod debug;
18
19use nrf52840_hal::{
20    gpio::{p0, p1, Disconnected, Input, Level, Output, Pin, PullUp, PushPull},
21    pac::{self as nrf52, CorePeripherals, Peripherals},
22    spim::{self, Frequency, Spim, MODE_0},
23    uarte::{self, Baudrate as UartBaudrate, Parity as UartParity, Uarte},
24};
25
26use embedded_hal::digital::v2::{InputPin, OutputPin};
27
28/// Provides access to all features of the nRF52840-DK board
29#[allow(non_snake_case)]
30pub struct Board {
31    /// The nRF52's pins which are not otherwise occupied on the nRF52840-DK
32    pub pins: Pins,
33
34    /// The nRF52840-DK UART which is wired to the virtual USB CDC port
35    pub cdc: Uarte<nrf52::UARTE0>,
36
37    /// The nRF52840-DK SPI which is wired to the SPI flash
38    pub flash: Spim<nrf52::SPIM2>,
39    pub flash_cs: Pin<Output<PushPull>>,
40
41    /// The LEDs on the nRF52840-DK board
42    pub leds: Leds,
43
44    /// The buttons on the nRF52840-DK board
45    pub buttons: Buttons,
46
47    pub nfc: NFC,
48
49    /// Core peripheral: Cache and branch predictor maintenance operations
50    pub CBP: nrf52::CBP,
51
52    /// Core peripheral: CPUID
53    pub CPUID: nrf52::CPUID,
54
55    /// Core peripheral: Debug Control Block
56    pub DCB: nrf52::DCB,
57
58    /// Core peripheral: Data Watchpoint and Trace unit
59    pub DWT: nrf52::DWT,
60
61    /// Core peripheral: Flash Patch and Breakpoint unit
62    pub FPB: nrf52::FPB,
63
64    /// Core peripheral: Floating Point Unit
65    pub FPU: nrf52::FPU,
66
67    /// Core peripheral: Instrumentation Trace Macrocell
68    pub ITM: nrf52::ITM,
69
70    /// Core peripheral: Memory Protection Unit
71    pub MPU: nrf52::MPU,
72
73    /// Core peripheral: Nested Vector Interrupt Controller
74    pub NVIC: nrf52::NVIC,
75
76    /// Core peripheral: System Control Block
77    pub SCB: nrf52::SCB,
78
79    /// Core peripheral: SysTick Timer
80    pub SYST: nrf52::SYST,
81
82    /// Core peripheral: Trace Port Interface Unit
83    pub TPIU: nrf52::TPIU,
84
85    /// nRF52 peripheral: FICR
86    pub FICR: nrf52::FICR,
87
88    /// nRF52 peripheral: UICR
89    pub UICR: nrf52::UICR,
90
91    /// nRF52 peripheral: ACL
92    pub ACL: nrf52::ACL,
93
94    /// nRF52 peripheral: POWER
95    pub POWER: nrf52::POWER,
96
97    /// nRF52 peripheral: CLOCK
98    pub CLOCK: nrf52::CLOCK,
99
100    /// nRF52 peripheral: RADIO
101    pub RADIO: nrf52::RADIO,
102
103    /// nRF52 peripheral: UART0
104    pub UART0: nrf52::UART0,
105
106    /// nRF52 peripheral: SPIM0
107    pub SPIM0: nrf52::SPIM0,
108
109    /// nRF52 peripheral: SPIS0
110    pub SPIS0: nrf52::SPIS0,
111
112    /// nRF52 peripheral: TWIM0
113    pub TWIM0: nrf52::TWIM0,
114
115    /// nRF52 peripheral: TWIS0
116    pub TWIS0: nrf52::TWIS0,
117
118    /// nRF52 peripheral: SPI0
119    pub SPI0: nrf52::SPI0,
120
121    /// nRF52 peripheral: TWI0
122    pub TWI0: nrf52::TWI0,
123
124    /// nRF52 peripheral: SPIM1
125    pub SPIM1: nrf52::SPIM1,
126
127    /// nRF52 peripheral: SPIS1
128    pub SPIS1: nrf52::SPIS1,
129
130    /// nRF52 peripheral: TWIM1
131    pub TWIM1: nrf52::TWIM1,
132
133    /// nRF52 peripheral: TWIS1
134    pub TWIS1: nrf52::TWIS1,
135
136    /// nRF52 peripheral: SPI1
137    pub SPI1: nrf52::SPI1,
138
139    /// nRF52 peripheral: TWI1
140    pub TWI1: nrf52::TWI1,
141
142    /// nRF52 peripheral: NFCT
143    pub NFCT: nrf52::NFCT,
144
145    /// nRF52 peripheral: GPIOTE
146    pub GPIOTE: nrf52::GPIOTE,
147
148    /// nRF52 peripheral: SAADC
149    pub SAADC: nrf52::SAADC,
150
151    /// nRF52 peripheral: TIMER0
152    pub TIMER0: nrf52::TIMER0,
153
154    /// nRF52 peripheral: TIMER1
155    pub TIMER1: nrf52::TIMER1,
156
157    /// nRF52 peripheral: TIMER2
158    pub TIMER2: nrf52::TIMER2,
159
160    /// nRF52 peripheral: RTC0
161    pub RTC0: nrf52::RTC0,
162
163    /// nRF52 peripheral: TEMP
164    pub TEMP: nrf52::TEMP,
165
166    /// nRF52 peripheral: RNG
167    pub RNG: nrf52::RNG,
168
169    /// nRF52 peripheral: ECB
170    pub ECB: nrf52::ECB,
171
172    /// nRF52 peripheral: CCM
173    pub CCM: nrf52::CCM,
174
175    /// nRF52 peripheral: AAR
176    pub AAR: nrf52::AAR,
177
178    /// nRF52 peripheral: WDT
179    pub WDT: nrf52::WDT,
180
181    /// nRF52 peripheral: RTC1
182    pub RTC1: nrf52::RTC1,
183
184    /// nRF52 peripheral: QDEC
185    pub QDEC: nrf52::QDEC,
186
187    /// nRF52 peripheral: COMP
188    pub COMP: nrf52::COMP,
189
190    /// nRF52 peripheral: LPCOMP
191    pub LPCOMP: nrf52::LPCOMP,
192
193    /// nRF52 peripheral: SWI0
194    pub SWI0: nrf52::SWI0,
195
196    /// nRF52 peripheral: EGU0
197    pub EGU0: nrf52::EGU0,
198
199    /// nRF52 peripheral: SWI1
200    pub SWI1: nrf52::SWI1,
201
202    /// nRF52 peripheral: EGU1
203    pub EGU1: nrf52::EGU1,
204
205    /// nRF52 peripheral: SWI2
206    pub SWI2: nrf52::SWI2,
207
208    /// nRF52 peripheral: EGU2
209    pub EGU2: nrf52::EGU2,
210
211    /// nRF52 peripheral: SWI3
212    pub SWI3: nrf52::SWI3,
213
214    /// nRF52 peripheral: EGU3
215    pub EGU3: nrf52::EGU3,
216
217    /// nRF52 peripheral: SWI4
218    pub SWI4: nrf52::SWI4,
219
220    /// nRF52 peripheral: EGU4
221    pub EGU4: nrf52::EGU4,
222
223    /// nRF52 peripheral: SWI5
224    pub SWI5: nrf52::SWI5,
225
226    /// nRF52 peripheral: EGU5
227    pub EGU5: nrf52::EGU5,
228
229    /// nRF52 peripheral: TIMER3
230    pub TIMER3: nrf52::TIMER3,
231
232    /// nRF52 peripheral: TIMER4
233    pub TIMER4: nrf52::TIMER4,
234
235    /// nRF52 peripheral: PWM0
236    pub PWM0: nrf52::PWM0,
237
238    /// nRF52 peripheral: PDM
239    pub PDM: nrf52::PDM,
240
241    /// nRF52 peripheral: NVMC
242    pub NVMC: nrf52::NVMC,
243
244    /// nRF52 peripheral: PPI
245    pub PPI: nrf52::PPI,
246
247    /// nRF52 peripheral: MWU
248    pub MWU: nrf52::MWU,
249
250    /// nRF52 peripheral: PWM1
251    pub PWM1: nrf52::PWM1,
252
253    /// nRF52 peripheral: PWM2
254    pub PWM2: nrf52::PWM2,
255
256    /// nRF52 peripheral: RTC2
257    pub RTC2: nrf52::RTC2,
258
259    /// nRF52 peripheral: I2S
260    pub I2S: nrf52::I2S,
261}
262
263impl Board {
264    /// Take the peripherals safely
265    ///
266    /// This method will return an instance of `nRF52840DK` the first time it is
267    /// called. It will return only `None` on subsequent calls.
268    pub fn take() -> Option<Self> {
269        Some(Self::new(CorePeripherals::take()?, Peripherals::take()?))
270    }
271
272    /// Steal the peripherals
273    ///
274    /// This method produces an instance of `nRF52840DK`, regardless of whether
275    /// another instance was create previously.
276    ///
277    /// # Safety
278    ///
279    /// This method can be used to create multiple instances of `nRF52840DK`. Those
280    /// instances can interfere with each other, causing all kinds of unexpected
281    /// behavior and circumventing safety guarantees in many ways.
282    ///
283    /// Always use `nRF52840DK::take`, unless you really know what you're doing.
284    pub unsafe fn steal() -> Self {
285        Self::new(CorePeripherals::steal(), Peripherals::steal())
286    }
287
288    fn new(cp: CorePeripherals, p: Peripherals) -> Self {
289        let pins0 = p0::Parts::new(p.P0);
290        let pins1 = p1::Parts::new(p.P1);
291
292        // The nRF52840-DK has an 64MB SPI flash on board which can be interfaced through SPI or Quad SPI.
293        // As for now, only the normal SPI mode is available, so we are using this for the interface.
294        let flash_spim = Spim::new(
295            p.SPIM2,
296            spim::Pins {
297                sck: pins0.p0_19.into_push_pull_output(Level::Low).degrade(),
298                mosi: Some(pins0.p0_20.into_push_pull_output(Level::Low).degrade()),
299                miso: Some(pins0.p0_21.into_floating_input().degrade()),
300            },
301            Frequency::K500,
302            MODE_0,
303            0,
304        );
305
306        let flash_cs = pins0.p0_17.into_push_pull_output(Level::High).degrade();
307
308        // The nRF52840-DK features an USB CDC port.
309        // It features HWFC but does not have to use it.
310        // It can transmit a flexible baudrate of up to 1Mbps.
311        let cdc_uart = Uarte::new(
312            p.UARTE0,
313            uarte::Pins {
314                txd: pins0.p0_06.into_push_pull_output(Level::High).degrade(),
315                rxd: pins0.p0_08.into_floating_input().degrade(),
316                cts: Some(pins0.p0_07.into_floating_input().degrade()),
317                rts: Some(pins0.p0_05.into_push_pull_output(Level::High).degrade()),
318            },
319            UartParity::EXCLUDED,
320            UartBaudrate::BAUD115200,
321        );
322
323        Board {
324            cdc: cdc_uart,
325            flash: flash_spim,
326            flash_cs,
327
328            pins: Pins {
329                P0_03: pins0.p0_03,
330                P0_04: pins0.p0_04,
331                _RESET: pins0.p0_18,
332                P0_22: pins0.p0_22,
333                P0_23: pins0.p0_23,
334                P0_26: pins0.p0_26,
335                P0_27: pins0.p0_27,
336                P0_28: pins0.p0_28,
337                P0_29: pins0.p0_29,
338                P0_30: pins0.p0_30,
339                P0_31: pins0.p0_31,
340                P1_00: pins1.p1_00,
341                P1_01: pins1.p1_01,
342                P1_02: pins1.p1_02,
343                P1_03: pins1.p1_03,
344                P1_04: pins1.p1_04,
345                P1_05: pins1.p1_05,
346                P1_06: pins1.p1_06,
347                P1_07: pins1.p1_07,
348                P1_08: pins1.p1_08,
349                P1_09: pins1.p1_09,
350                P1_10: pins1.p1_10,
351                P1_11: pins1.p1_11,
352                P1_12: pins1.p1_12,
353                P1_13: pins1.p1_13,
354                P1_14: pins1.p1_14,
355                P1_15: pins1.p1_15,
356            },
357
358            leds: Leds {
359                led_1: Led::new(pins0.p0_13.degrade()),
360                led_2: Led::new(pins0.p0_14.degrade()),
361                led_3: Led::new(pins0.p0_15.degrade()),
362                led_4: Led::new(pins0.p0_16.degrade()),
363            },
364
365            buttons: Buttons {
366                button_1: Button::new(pins0.p0_11.degrade()),
367                button_2: Button::new(pins0.p0_12.degrade()),
368                button_3: Button::new(pins0.p0_24.degrade()),
369                button_4: Button::new(pins0.p0_25.degrade()),
370            },
371
372            nfc: NFC {
373                nfc_1: pins0.p0_09,
374                nfc_2: pins0.p0_10,
375            },
376
377            // Core peripherals
378            CBP: cp.CBP,
379            CPUID: cp.CPUID,
380            DCB: cp.DCB,
381            DWT: cp.DWT,
382            FPB: cp.FPB,
383            FPU: cp.FPU,
384            ITM: cp.ITM,
385            MPU: cp.MPU,
386            NVIC: cp.NVIC,
387            SCB: cp.SCB,
388            SYST: cp.SYST,
389            TPIU: cp.TPIU,
390
391            // nRF52 peripherals
392            FICR: p.FICR,
393            UICR: p.UICR,
394            ACL: p.ACL,
395            POWER: p.POWER,
396            CLOCK: p.CLOCK,
397            RADIO: p.RADIO,
398
399            UART0: p.UART0,
400            SPIM0: p.SPIM0,
401            SPIS0: p.SPIS0,
402            TWIM0: p.TWIM0,
403            TWIS0: p.TWIS0,
404            SPI0: p.SPI0,
405            TWI0: p.TWI0,
406            SPIM1: p.SPIM1,
407            SPIS1: p.SPIS1,
408            TWIM1: p.TWIM1,
409            TWIS1: p.TWIS1,
410            SPI1: p.SPI1,
411            TWI1: p.TWI1,
412            NFCT: p.NFCT,
413            GPIOTE: p.GPIOTE,
414            SAADC: p.SAADC,
415            TIMER0: p.TIMER0,
416            TIMER1: p.TIMER1,
417            TIMER2: p.TIMER2,
418            RTC0: p.RTC0,
419            TEMP: p.TEMP,
420            RNG: p.RNG,
421            ECB: p.ECB,
422            CCM: p.CCM,
423            AAR: p.AAR,
424            WDT: p.WDT,
425            RTC1: p.RTC1,
426            QDEC: p.QDEC,
427            COMP: p.COMP,
428            LPCOMP: p.LPCOMP,
429            SWI0: p.SWI0,
430            EGU0: p.EGU0,
431            SWI1: p.SWI1,
432            EGU1: p.EGU1,
433            SWI2: p.SWI2,
434            EGU2: p.EGU2,
435            SWI3: p.SWI3,
436            EGU3: p.EGU3,
437            SWI4: p.SWI4,
438            EGU4: p.EGU4,
439            SWI5: p.SWI5,
440            EGU5: p.EGU5,
441            TIMER3: p.TIMER3,
442            TIMER4: p.TIMER4,
443            PWM0: p.PWM0,
444            PDM: p.PDM,
445            NVMC: p.NVMC,
446            PPI: p.PPI,
447            MWU: p.MWU,
448            PWM1: p.PWM1,
449            PWM2: p.PWM2,
450            RTC2: p.RTC2,
451            I2S: p.I2S,
452        }
453    }
454}
455
456/// The nRF52 pins that are available on the nRF52840DK
457#[allow(non_snake_case)]
458pub struct Pins {
459    pub P0_03: p0::P0_03<Disconnected>,
460    pub P0_04: p0::P0_04<Disconnected>,
461    _RESET: p0::P0_18<Disconnected>,
462    pub P0_22: p0::P0_22<Disconnected>,
463    pub P0_23: p0::P0_23<Disconnected>,
464    pub P0_26: p0::P0_26<Disconnected>,
465    pub P0_27: p0::P0_27<Disconnected>,
466    pub P0_28: p0::P0_28<Disconnected>,
467    pub P0_29: p0::P0_29<Disconnected>,
468    pub P0_30: p0::P0_30<Disconnected>,
469    pub P0_31: p0::P0_31<Disconnected>,
470    pub P1_00: p1::P1_00<Disconnected>,
471    pub P1_01: p1::P1_01<Disconnected>,
472    pub P1_02: p1::P1_02<Disconnected>,
473    pub P1_03: p1::P1_03<Disconnected>,
474    pub P1_04: p1::P1_04<Disconnected>,
475    pub P1_05: p1::P1_05<Disconnected>,
476    pub P1_06: p1::P1_06<Disconnected>,
477    pub P1_07: p1::P1_07<Disconnected>,
478    pub P1_08: p1::P1_08<Disconnected>,
479    pub P1_09: p1::P1_09<Disconnected>,
480    pub P1_10: p1::P1_10<Disconnected>,
481    pub P1_11: p1::P1_11<Disconnected>,
482    pub P1_12: p1::P1_12<Disconnected>,
483    pub P1_13: p1::P1_13<Disconnected>,
484    pub P1_14: p1::P1_14<Disconnected>,
485    pub P1_15: p1::P1_15<Disconnected>,
486}
487
488/// The LEDs on the nRF52840-DK board
489pub struct Leds {
490    /// nRF52840-DK: LED1, nRF52: P0.30
491    pub led_1: Led,
492
493    /// nRF52840-DK: LED2, nRF52: P0.31
494    pub led_2: Led,
495
496    /// nRF52840-DK: LED3, nRF52: P0.22
497    pub led_3: Led,
498
499    /// nRF52840-DK: LED4, nRF52: P0.14
500    pub led_4: Led,
501}
502
503/// An LED on the nRF52840-DK board
504pub struct Led(Pin<Output<PushPull>>);
505
506impl Led {
507    fn new<Mode>(pin: Pin<Mode>) -> Self {
508        Led(pin.into_push_pull_output(Level::High))
509    }
510
511    /// Release the inner Pin to be used directly
512    pub fn release(self) -> Pin<Output<PushPull>> {
513        self.0
514    }
515
516    /// Enable the LED
517    pub fn enable(&mut self) {
518        self.0.set_low().unwrap()
519    }
520
521    /// Disable the LED
522    pub fn disable(&mut self) {
523        self.0.set_high().unwrap()
524    }
525}
526
527/// The Buttons on the nRF52840-DK board
528pub struct Buttons {
529    /// nRF52840-DK: Button 1, nRF52: P0.30
530    pub button_1: Button,
531
532    /// nRF52840-DK: Button 2, nRF52: P0.31
533    pub button_2: Button,
534
535    /// nRF52840-DK: Button 3, nRF52: P0.22
536    pub button_3: Button,
537
538    /// nRF52840-DK: Button 4, nRF52: P0.14
539    pub button_4: Button,
540}
541
542/// A Button on the nRF52840-DK board
543pub struct Button(Pin<Input<PullUp>>);
544
545impl Button {
546    fn new<Mode>(pin: Pin<Mode>) -> Self {
547        Button(pin.into_pullup_input())
548    }
549
550    /// Release the inner Pin to be used directly
551    pub fn release(self) -> Pin<Input<PullUp>> {
552        self.0
553    }
554
555    /// Button is pressed
556    pub fn is_pressed(&self) -> bool {
557        self.0.is_low().unwrap()
558    }
559
560    /// Button is released
561    pub fn is_released(&self) -> bool {
562        self.0.is_high().unwrap()
563    }
564}
565
566/// The NFC pins on the nRF52840-DK board
567pub struct NFC {
568    /// nRF52840-DK: NFC1, nRF52: P0.09
569    pub nfc_1: p0::P0_09<Disconnected>,
570
571    /// nRF52840-DK: NFC2, nRF52: P0.10
572    pub nfc_2: p0::P0_10<Disconnected>,
573}