Hello World
This is a step by step guide expand the hello.rs
example in the knurling app template
from just logging hello world
to blinking an onboard LED on the nrf52840-DK.
An example of this implementation can be found here: 1_hello_extended.rs.
Project Setup
Come up with a name for the Project and generate the app template according to our guide. Don't forget to enter the appropriate Information in the TODOs.
Getting Access to Resources
- In your generated app-template folder, go to
src/bin/hello.rs
. - Bring the following modules into scope:
#![allow(unused)] fn main() { use nrf52840_hal::{ self as hal, gpio::{p0::Parts as P0Parts, Level}, Timer, }; }
The nrf52840_hal
crate is a Hardware Abstraction Layer (HAL), which helps us access the board's resources, e.g. GPIO pins or timers.
If you use a different microcontroller, you need to be able to gain access to a TIMER peripheral, pins for the onboard LEDs and Level of the pins.
- Gain access to all the peripherals of the board by adding the following line in
fn main()
:
#![allow(unused)] fn main() { let board = hal::pac::Peripherals::take().unwrap(); }
If you use a different board, check the crate's docs on how to get access to all peripherals.
- You need a timer to blink LEDs, as the LED is on and off for certain amounts of time. To access the timer peripheral add this line:
#![allow(unused)] fn main() { let mut timer = Timer::new(board.TIMER0); }
- If we want to use the onboard LEDs, we need to find out how to access them. Check the datasheet of your board to find out which GPIO pins they are connected to. For the nrf52840-DK you'll find the information here.
The onboard LEDs are part of the P0 Pins. LED1 is p0.13. To gain access this group of pins add this line:
#![allow(unused)] fn main() { let pins = P0Parts::new(board.P0); }
Switching the Light on
- Configure pin p0.13 into a push-pull-output with Low Level:
#![allow(unused)] fn main() { let mut led_1 = pins.p0_13.into_push_pull_output(Level::Low); }
- The
embedded-hal
crate provides a generic API to access the different resources of a board, independent of board model. This makes development easier and your code more portable. We want to use it to set a pin high or low, or set delays for the Timer.
To access it, add it as a dependency to your Cargo.toml
# Cargo.toml
[dependencies]
cortex-m = "0.6.3"
cortex-m-rt = "0.6.12"
# TODO(4) enter your HAL here
nrf52840-hal = "0.11.0"
+embedded-hal = "0.2.4"
[features]
and then, in hello.rs
, bring its DelayMs
and OutputPin
Traits into scope so we can use them:
#![allow(unused)] fn main() { use embedded_hal::{ blocking::delay::DelayMs, digital::v2::OutputPin, }; }
- Add a delay of 1000 milliseconds to your
main()
function:
#![allow(unused)] fn main() { timer.delay_ms(1000u32); }
- Run the program!
LED1 on your microcontroller should light up for a second. Then the program ends.
Blinking the LED
- Open a loop:
#![allow(unused)] fn main() { loop { }; }
- Inside the loop add the following lines:
#![allow(unused)] fn main() { led_1.set_high().unwrap(); timer.delay_ms(1000u32); led_1.set_low().unwrap(); timer.delay_ms(1000u32); }
- Run the program.
LED1 should blink continuously.