From 0e69e657b4e93ef660ce96272f55340e1c4f014b Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Thu, 20 Jun 2024 09:01:10 +0200 Subject: [PATCH 01/14] Update the 02-requirements/README.md Updated to mention the 2021 edition in stead of 2018 --- microbit/src/02-requirements/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/microbit/src/02-requirements/README.md b/microbit/src/02-requirements/README.md index df1826a74..cac6071a9 100644 --- a/microbit/src/02-requirements/README.md +++ b/microbit/src/02-requirements/README.md @@ -3,10 +3,10 @@ The primary knowledge requirement to read this book is to know *some* Rust. It's hard for me to quantify *some* but at least I can tell you that you don't need to fully grok generics, but you do need to know how to *use* closures. You also -need to be familiar with the idioms of the [2018 edition], in particular with +need to be familiar with the idioms of the [2021 edition], in particular with the fact that `extern crate` is not necessary in the 2018 edition. -[2018 edition]: https://rust-lang-nursery.github.io/edition-guide/ +[2021 edition]: https://rust-lang-nursery.github.io/edition-guide/ Also, to follow this material you'll need the following hardware: From a29cb2747d13c98c6b0a79722d1820f75c5ea4b5 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Sun, 9 Jun 2024 00:43:29 +0200 Subject: [PATCH 02/14] Typo: Change `vI` to `v1` --- microbit/src/03-setup/IDE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/microbit/src/03-setup/IDE.md b/microbit/src/03-setup/IDE.md index 62260861e..5d915802b 100644 --- a/microbit/src/03-setup/IDE.md +++ b/microbit/src/03-setup/IDE.md @@ -13,7 +13,7 @@ Some IDEs fail to understand the code, because they fail to determine whether a is defined in the microbit or microbit-v2 codebase. If you fail to get auto-completion to work, you may want to try to edit the `Cargo.toml` files you encounter through this book, and remove all references to the version of microbit you are not using. That is: - in the `Cargo.toml` file you must remove the dependency and features you do not use (the part guarded by `#[cfg(feature = "vI")]` and the guard itself) + in the `Cargo.toml` file you must remove the dependency and features you do not use (the part guarded by `#[cfg(feature = "v1")]` and the guard itself) # IDE configuration From 9bb86eabcbfc0d68e9d850ffccd2e5f52f7e96ec Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Sun, 9 Jun 2024 00:47:19 +0200 Subject: [PATCH 03/14] Update crate versions in 03-setup Cargo.toml: * edition 2018 -> 2021 * cortex-m 0.7.3 -> 0.7.7, added feature `critical-section-single-core` * cortex-m-rt 0.7.0 -> 0.7.3 * rtt-target 0.3.1 -> 0.5.0, removed feature `cortex-m` * panic-rtt-target 0.1.2 -> 0.1.3, removed feature `cortex-m` src/main.rs: * To prevent a link error regarding undefined symbols (`_critical_section_1_0_acquire` and `_critical_section_1_0_release`) I have added `use cortex_m as _;` The code compiles, and I see the RTT output from cargo embed. --- microbit/src/03-setup/Cargo.toml | 10 +++++----- microbit/src/03-setup/IDE.md | 2 +- microbit/src/03-setup/src/main.rs | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/microbit/src/03-setup/Cargo.toml b/microbit/src/03-setup/Cargo.toml index 45466cf5b..23442fb1c 100644 --- a/microbit/src/03-setup/Cargo.toml +++ b/microbit/src/03-setup/Cargo.toml @@ -2,10 +2,10 @@ name = "rtt-check" version = "0.1.0" authors = ["Henrik Böving "] -edition = "2018" +edition = "2021" [dependencies] -cortex-m = "0.7.3" -cortex-m-rt = "0.7.0" -rtt-target = { version = "0.3.1", features = ["cortex-m"] } -panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] } +cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7.3" +rtt-target = "0.5.0" +panic-rtt-target = "0.1.3" diff --git a/microbit/src/03-setup/IDE.md b/microbit/src/03-setup/IDE.md index 5d915802b..0d74d0e53 100644 --- a/microbit/src/03-setup/IDE.md +++ b/microbit/src/03-setup/IDE.md @@ -28,4 +28,4 @@ When editing the IntelliJ build configuration, here are a few non-default values You'll need to replace the default value `run` by the command `embed FLAGS`, * You should enable "Emulate terminal in output console". Otherwise, your program will fail to print text to a terminal * You should ensure that the working directory is `microbit/src/N-name`, with `N-name` being the directory of the chapter you -are reading. You can not run from the `src` directory since it contains no cargo file. \ No newline at end of file +are reading. You can not run from the `src` directory since it contains no cargo file. diff --git a/microbit/src/03-setup/src/main.rs b/microbit/src/03-setup/src/main.rs index 981cc40d6..7b5f37129 100644 --- a/microbit/src/03-setup/src/main.rs +++ b/microbit/src/03-setup/src/main.rs @@ -4,6 +4,7 @@ use panic_rtt_target as _; use rtt_target::{rtt_init_print, rprintln}; +use cortex_m as _; use cortex_m_rt::entry; #[entry] From 5aad8b3b161843a61d45a7ba8843ccd0340b78e9 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Wed, 12 Jun 2024 21:30:17 +0200 Subject: [PATCH 04/14] Update crate versions in 05-led-roulette Cargo.toml * edition 2018 -> 2021 * microbit-v2 0.12.0 -> 0.14.0 * microbit 0.12.0 -> 0.14.0 * cortex-m 0.7.3 -> 0.7.7, added feature `critical-section-single-core` * cortex-m-rt 0.7.0 -> 0.7.3 * rtt-target 0.3.1 -> 0.5.0, removed feature `cortex-m` * panic-rtt-target 0.1.2 -> 0.1.3, removed feature `cortex-m` --- microbit/src/05-led-roulette/Cargo.toml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/microbit/src/05-led-roulette/Cargo.toml b/microbit/src/05-led-roulette/Cargo.toml index 1f405fb85..409f0f2f1 100644 --- a/microbit/src/05-led-roulette/Cargo.toml +++ b/microbit/src/05-led-roulette/Cargo.toml @@ -2,28 +2,28 @@ name = "led-roulette" version = "0.1.0" authors = ["Henrik Böving "] -edition = "2018" +edition = "2021" [dependencies.microbit-v2] -version = "0.12.0" +version = "0.14.0" optional = true [dependencies.microbit] -version = "0.12.0" +version = "0.14.0" optional = true [dependencies] -cortex-m = "0.7.3" -cortex-m-rt = "0.7.0" +cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] } +cortex-m-rt = "0.7.3" panic-halt = "0.2.0" -#rtt-target = { version = "0.3.1", features = ["cortex-m"] } -#panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] } +# rtt-target = "0.5.0" +# panic-rtt-target = "0.1.3" [dev-dependencies] # Sneak in dependencies for examples which clash with panic-hal when generating # docs with rustdoc. -rtt-target = { version = "0.3.1", features = ["cortex-m"] } -panic-rtt-target = { version = "0.1.2", features = ["cortex-m"] } +rtt-target = "0.5.0" +panic-rtt-target = "0.1.3" [features] v2 = ["microbit-v2"] From 456c3020ba40f512124cea88060cca5bd8f1efd9 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Wed, 12 Jun 2024 21:48:07 +0200 Subject: [PATCH 05/14] Update the shown examples to reflect the new crate version --- microbit/src/05-led-roulette/build-it.md | 32 ++++++++++++------------ microbit/src/05-led-roulette/debug-it.md | 11 ++++---- 2 files changed, 22 insertions(+), 21 deletions(-) diff --git a/microbit/src/05-led-roulette/build-it.md b/microbit/src/05-led-roulette/build-it.md index 7b979efc1..0147eb430 100644 --- a/microbit/src/05-led-roulette/build-it.md +++ b/microbit/src/05-led-roulette/build-it.md @@ -42,20 +42,20 @@ With the `rust-std` component in place you can now cross compile the program usi # For micro:bit v2 $ cargo build --features v2 --target thumbv7em-none-eabihf Compiling semver-parser v0.7.0 - Compiling typenum v1.12.0 Compiling cortex-m v0.6.3 + Compiling proc-macro2 v1.0.85 (...) - Compiling microbit-v2 v0.10.1 - Finished dev [unoptimized + debuginfo] target(s) in 33.67s + Compiling microbit-v2 v0.14.0 + Finished dev [unoptimized + debuginfo] target(s) in 4.33s # For micro:bit v1 $ cargo build --features v1 --target thumbv6m-none-eabi - Compiling fixed v1.2.0 - Compiling syn v1.0.39 - Compiling cortex-m v0.6.3 + Compiling semver-parser v0.7.0 + Compiling proc-macro2 v1.0.85 + Compiling cortex-m v0.7.7 (...) - Compiling microbit v0.10.1 - Finished dev [unoptimized + debuginfo] target(s) in 22.73s + Compiling microbit v0.14.0 + Finished dev [unoptimized + debuginfo] target(s) in 2.79s ``` > **NOTE** Be sure to compile this crate *without* optimizations. The provided Cargo.toml @@ -80,16 +80,16 @@ ELF Header: Type: EXEC (Executable file) Machine: ARM Version: 0x1 - Entry point address: 0x117 + Entry point address: 0x101 Start of program headers: 52 (bytes into file) - Start of section headers: 793112 (bytes into file) + Start of section headers: 777140 (bytes into file) Flags: 0x5000400 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 4 Size of section headers: 40 (bytes) - Number of section headers: 21 - Section header string table index: 19 + Number of section headers: 23 + Section header string table index: 21 # For micro:bit v1 # equivalent to `readelf -h target/thumbv6m-none-eabi/debug/led-roulette` @@ -105,16 +105,16 @@ ELF Header: Type: EXEC (Executable file) Machine: ARM Version: 0x1 - Entry point address: 0xC1 + Entry point address: 0xA9 Start of program headers: 52 (bytes into file) - Start of section headers: 693196 (bytes into file) + Start of section headers: 776152 (bytes into file) Flags: 0x5000200 Size of this header: 52 (bytes) Size of program headers: 32 (bytes) Number of program headers: 4 Size of section headers: 40 (bytes) - Number of section headers: 22 - Section header string table index: 20 + Number of section headers: 23 + Section header string table index: 21 ``` Next, we'll flash the program into our microcontroller. diff --git a/microbit/src/05-led-roulette/debug-it.md b/microbit/src/05-led-roulette/debug-it.md index 285d107c2..134913abc 100644 --- a/microbit/src/05-led-roulette/debug-it.md +++ b/microbit/src/05-led-roulette/debug-it.md @@ -45,22 +45,23 @@ $ gdb target/thumbv6m-none-eabi/debug/led-roulette > as long as it does not crash, you are fine. Next we will have to connect to the GDB stub. It runs on `localhost:1337` per default so in order to -connect to it run the following: +connect to it run the following on the gdb commandline (`(gdb)`): ```shell (gdb) target remote :1337 Remote debugging using :1337 -0x00000116 in nrf52833_pac::{{impl}}::fmt (self=0xd472e165, f=0x3c195ff7) at /home/nix/.cargo/registry/src/github.com-1ecc6299db9ec823/nrf52833-pac-0.9.0/src/lib.rs:157 -157 #[derive(Copy, Clone, Debug)] +(...) +0x00000100 in cortex_m::delay::Delay::delay_us (self=0xedbeff37, us=439704628) at src/delay.rs:56 +56 self.syst.set_reload(ticks - 1); ``` Next what we want to do is get to the main function of our program. -We will do this by first setting a breakpoint there and the continuing +We will do this by first setting a breakpoint there and then continuing program execution until we hit the breakpoint: ``` (gdb) break main -Breakpoint 1 at 0x104: file src/05-led-roulette/src/main.rs, line 9. +Breakpoint 1 at 0x15c: file src/05-led-roulette/src/main.rs, line 9. Note: automatically using hardware breakpoints for read-only addresses. (gdb) continue Continuing. From 8fc7b9f29848e693c642550ccefde66352da1061 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Tue, 18 Jun 2024 09:37:57 +0200 Subject: [PATCH 06/14] Update examples to the new crate versions --- microbit/src/05-led-roulette/light-it-up.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/microbit/src/05-led-roulette/light-it-up.md b/microbit/src/05-led-roulette/light-it-up.md index 617965d0a..96c152b06 100644 --- a/microbit/src/05-led-roulette/light-it-up.md +++ b/microbit/src/05-led-roulette/light-it-up.md @@ -38,15 +38,17 @@ a look at it and then we can go through it step by step: use cortex_m_rt::entry; use panic_halt as _; -use microbit::board::Board; -use microbit::hal::prelude::*; +use microbit::{ + board::Board, + hal::gpio::Level, +}; #[entry] fn main() -> ! { - let mut board = Board::take().unwrap(); + let board = Board::take().unwrap(); - board.display_pins.col1.set_low().unwrap(); - board.display_pins.row1.set_high().unwrap(); + board.display_pins.col1.into_push_pull_output(Level::Low); + board.display_pins.row1.into_push_pull_output(Level::High); loop {} } @@ -57,7 +59,7 @@ However, the main function looks pretty different to what we have seen up to now The first line is related to how most HALs written in Rust work internally. As discussed before they are built on top of PAC crates which own (in the Rust sense) -all the peripherals of a chip. `let mut board = Board::take().unwrap();` basically takes all +all the peripherals of a chip. `let board = Board::take().unwrap();` basically takes all these peripherals from the PAC and binds them to a variable. In this specific case we are not only working with a HAL but with an entire BSP, so this also takes ownership of the Rust representation of the other chips on the board. @@ -82,8 +84,8 @@ to the GDB stub: $ # Your GDB debug command from the last section (gdb) target remote :1337 Remote debugging using :1337 -cortex_m_rt::Reset () at /home/nix/.cargo/registry/src/github.com-1ecc6299db9ec823/cortex-m-rt-0.6.12/src/lib.rs:489 -489 pub unsafe extern "C" fn Reset() -> ! { +(...) +0x00000100 in microbit_common::display::nonblocking::control::{impl#0}::initialise_for_display (self=0xaf0a8041) (gdb) ``` From b90938aa14837c9f260c763a7ee69e215ab49ced Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Tue, 18 Jun 2024 10:32:03 +0200 Subject: [PATCH 07/14] Introduce embedded-hal, and refactor to use the OuputPin trait as before The microbit crate apparently don't reexport the hal's OutputPin trail, there for add embedded-hal as a dependency. --- microbit/src/05-led-roulette/Cargo.toml | 1 + microbit/src/05-led-roulette/light-it-up.md | 16 +++++++--------- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/microbit/src/05-led-roulette/Cargo.toml b/microbit/src/05-led-roulette/Cargo.toml index 409f0f2f1..8159715d7 100644 --- a/microbit/src/05-led-roulette/Cargo.toml +++ b/microbit/src/05-led-roulette/Cargo.toml @@ -15,6 +15,7 @@ optional = true [dependencies] cortex-m = { version = "0.7.7", features = ["critical-section-single-core"] } cortex-m-rt = "0.7.3" +embedded-hal = "1.0.0" panic-halt = "0.2.0" # rtt-target = "0.5.0" # panic-rtt-target = "0.1.3" diff --git a/microbit/src/05-led-roulette/light-it-up.md b/microbit/src/05-led-roulette/light-it-up.md index 96c152b06..7132f4a40 100644 --- a/microbit/src/05-led-roulette/light-it-up.md +++ b/microbit/src/05-led-roulette/light-it-up.md @@ -5,7 +5,7 @@ In this chapter we are going to make one of the many LEDs on the back of the mic basically the "Hello World" of embedded programming. In order to get this task done we will use one of the traits provided by `embedded-hal`, specifically the [`OutputPin`] trait which allows us to turn a pin on or off. -[`OutputPin`]: https://docs.rs/embedded-hal/0.2.6/embedded_hal/digital/v2/trait.OutputPin.html +[`OutputPin`]: https://docs.rs/embedded-hal/1.0.0/embedded_hal/digital/trait.OutputPin.html ## The micro:bit LEDs @@ -37,18 +37,16 @@ a look at it and then we can go through it step by step: #![no_std] use cortex_m_rt::entry; +use embedded_hal::digital::OutputPin; use panic_halt as _; -use microbit::{ - board::Board, - hal::gpio::Level, -}; +use microbit::board::Board, #[entry] fn main() -> ! { - let board = Board::take().unwrap(); + let mut board = Board::take().unwrap(); - board.display_pins.col1.into_push_pull_output(Level::Low); - board.display_pins.row1.into_push_pull_output(Level::High); + board.display_pins.col1.set_low().unwrap(); + board.display_pins.row1.set_high().unwrap(); loop {} } @@ -59,7 +57,7 @@ However, the main function looks pretty different to what we have seen up to now The first line is related to how most HALs written in Rust work internally. As discussed before they are built on top of PAC crates which own (in the Rust sense) -all the peripherals of a chip. `let board = Board::take().unwrap();` basically takes all +all the peripherals of a chip. `let mut board = Board::take().unwrap();` basically takes all these peripherals from the PAC and binds them to a variable. In this specific case we are not only working with a HAL but with an entire BSP, so this also takes ownership of the Rust representation of the other chips on the board. From e5a01049d8c2af7c60d17d21bee3c188768f9106 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Thu, 20 Jun 2024 09:29:34 +0200 Subject: [PATCH 08/14] Moved the 05-led-roulette light-it-up example to a project example --- .../05-led-roulette/examples/light-it-up.rs | 18 ++++++++++++++++++ microbit/src/05-led-roulette/light-it-up.md | 19 +------------------ 2 files changed, 19 insertions(+), 18 deletions(-) create mode 100644 microbit/src/05-led-roulette/examples/light-it-up.rs diff --git a/microbit/src/05-led-roulette/examples/light-it-up.rs b/microbit/src/05-led-roulette/examples/light-it-up.rs new file mode 100644 index 000000000..fa87192de --- /dev/null +++ b/microbit/src/05-led-roulette/examples/light-it-up.rs @@ -0,0 +1,18 @@ +#![deny(unsafe_code)] +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::digital::OutputPin; +use panic_halt as _; +use microbit::board::Board; + +#[entry] +fn main() -> ! { + let mut board = Board::take().unwrap(); + + board.display_pins.col1.set_low().unwrap(); + board.display_pins.row1.set_high().unwrap(); + + loop {} +} diff --git a/microbit/src/05-led-roulette/light-it-up.md b/microbit/src/05-led-roulette/light-it-up.md index 7132f4a40..1d2fcd5b9 100644 --- a/microbit/src/05-led-roulette/light-it-up.md +++ b/microbit/src/05-led-roulette/light-it-up.md @@ -32,24 +32,7 @@ The code required to light up an LED in the matrix is actually quite simple but a look at it and then we can go through it step by step: ```rust -#![deny(unsafe_code)] -#![no_main] -#![no_std] - -use cortex_m_rt::entry; -use embedded_hal::digital::OutputPin; -use panic_halt as _; -use microbit::board::Board, - -#[entry] -fn main() -> ! { - let mut board = Board::take().unwrap(); - - board.display_pins.col1.set_low().unwrap(); - board.display_pins.row1.set_high().unwrap(); - - loop {} -} +{{#include examples/light-it-up.rs}} ``` The first few lines until the main function just do some basic imports and setup we already looked at before. From 93aee670326c82e262fb1605c0fdaec1ed4ab224 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Tue, 18 Jun 2024 18:33:23 +0200 Subject: [PATCH 09/14] Update 05-led-roulette/it-blinks.md to the updated crates --- microbit/src/05-led-roulette/it-blinks.md | 42 +++++++++++++++-------- 1 file changed, 27 insertions(+), 15 deletions(-) diff --git a/microbit/src/05-led-roulette/it-blinks.md b/microbit/src/05-led-roulette/it-blinks.md index 4fe091636..bc7707bc0 100644 --- a/microbit/src/05-led-roulette/it-blinks.md +++ b/microbit/src/05-led-roulette/it-blinks.md @@ -5,12 +5,12 @@ Now we're going to take a brief look into delay abstractions provided by `embedd before combining this with the GPIO abstractions from the previous chapter in order to finally make an LED blink. -`embedded-hal` provides us with two abstractions to delay the execution of our program: -[`DelayUs`] and [`DelayMs`]. Both of them essentially work the exact same way except -that they accept different units for their delay function. +`embedded-hal` provides us with an abstractions to delay the execution of our program: +[`DelayNs`]. This abstraction provides three functions `delay_ns`, `delay_us` and `delay_ms` +that delays execution for nano, micro or mili seconds respectively. They essentially work +the exact same way except that they accept different units for their delay function. -[`DelayUs`]: https://docs.rs/embedded-hal/0.2.6/embedded_hal/blocking/delay/trait.DelayUs.html -[`DelayMs`]: https://docs.rs/embedded-hal/0.2.6/embedded_hal/blocking/delay/trait.DelayMs.html +[`DelayNs`]: https://docs.rs/embedded-hal/1.0.0/embedded_hal/blocking/delay/trait.DelayNs.html Inside our MCU, several so-called "timers" exist. They can do various things regarding time for us, including simply pausing the execution of our program for a fixed amount of time. A very @@ -22,21 +22,25 @@ simple delay-based program that prints something every second might for example #![no_std] use cortex_m_rt::entry; -use rtt_target::{rtt_init_print, rprintln}; +use embedded_hal::delay::DelayNS; +use rtt_target::{ + rtt_init_print, + rprintln, +}; use panic_rtt_target as _; use microbit::board::Board; use microbit::hal::timer::Timer; -use microbit::hal::prelude::*; #[entry] fn main() -> ! { rtt_init_print!(); - let mut board = Board::take().unwrap(); + + let board = Board::take().unwrap(); let mut timer = Timer::new(board.TIMER0); loop { - timer.delay_ms(1000u16); + timer.delay_ms(1_000u32); rprintln!("1000 ms passed"); } } @@ -47,20 +51,20 @@ Note that we changed our panic implementation from `panic_halt` to RTT lines from `Cargo.toml` and comment the `panic-halt` one out, since Rust only allows one panic implementation at a time. -In order to actually see the prints we have to change `Embed.toml` like this: +In order to actually see the prints we have to change `Embed.toml` like shown on the marked lines (`<--- Here`): ``` [default.general] # chip = "nrf52833_xxAA" # uncomment this line for micro:bit V2 # chip = "nrf51822_xxAA" # uncomment this line for micro:bit V1 [default.reset] -halt_afterwards = false +halt_afterwards = false <--- Here [default.rtt] -enabled = true +enabled = true <--- Here [default.gdb] -enabled = false +enabled = false <--- Here ``` And now after putting the code into `src/main.rs` and another quick `cargo embed` (again with the same flags you used before) @@ -78,15 +82,22 @@ a mash-up of the one above and the one that turned an LED on in the last section #![no_std] use cortex_m_rt::entry; -use rtt_target::{rtt_init_print, rprintln}; +use rtt_target::{ + rtt_init_print, + rprintln, +}; use panic_rtt_target as _; +use embedded_hal::{ + delay::DelayNS, + digital::OutputPin, +}; use microbit::board::Board; use microbit::hal::timer::Timer; -use microbit::hal::prelude::*; #[entry] fn main() -> ! { rtt_init_print!(); + let mut board = Board::take().unwrap(); let mut timer = Timer::new(board.TIMER0); @@ -98,6 +109,7 @@ fn main() -> ! { row1.set_low().unwrap(); rprintln!("Dark!"); timer.delay_ms(1_000_u16); + row1.set_high().unwrap(); rprintln!("Light!"); timer.delay_ms(1_000_u16); From 8ee50c15ac6f5d429a205aa0eb5a3bc2c0ba4e60 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Thu, 20 Jun 2024 09:57:22 +0200 Subject: [PATCH 10/14] Moved the 05-led-roulette it-blinks examples to project examples --- .../05-led-roulette/examples/it-blinks-1.rs | 28 +++++++ .../05-led-roulette/examples/it-blinks-2.rs | 38 ++++++++++ microbit/src/05-led-roulette/it-blinks.md | 73 ++----------------- 3 files changed, 71 insertions(+), 68 deletions(-) create mode 100644 microbit/src/05-led-roulette/examples/it-blinks-1.rs create mode 100644 microbit/src/05-led-roulette/examples/it-blinks-2.rs diff --git a/microbit/src/05-led-roulette/examples/it-blinks-1.rs b/microbit/src/05-led-roulette/examples/it-blinks-1.rs new file mode 100644 index 000000000..cc9f66b96 --- /dev/null +++ b/microbit/src/05-led-roulette/examples/it-blinks-1.rs @@ -0,0 +1,28 @@ +#![deny(unsafe_code)] +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use embedded_hal::delay::DelayNs; +use rtt_target::{ + rtt_init_print, + rprintln, +}; +use panic_rtt_target as _; +use microbit::board::Board; +use microbit::hal::timer::Timer; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + + let board = Board::take().unwrap(); + + let mut timer = Timer::new(board.TIMER0); + + loop { + timer.delay_ms(1_000u32); + rprintln!("1000 ms passed"); + } +} + diff --git a/microbit/src/05-led-roulette/examples/it-blinks-2.rs b/microbit/src/05-led-roulette/examples/it-blinks-2.rs new file mode 100644 index 000000000..f37c9ab0d --- /dev/null +++ b/microbit/src/05-led-roulette/examples/it-blinks-2.rs @@ -0,0 +1,38 @@ +#![deny(unsafe_code)] +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use rtt_target::{ + rtt_init_print, + rprintln, +}; +use panic_rtt_target as _; +use embedded_hal::{ + delay::DelayNs, + digital::OutputPin, +}; +use microbit::board::Board; +use microbit::hal::timer::Timer; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + + let mut board = Board::take().unwrap(); + + let mut timer = Timer::new(board.TIMER0); + + board.display_pins.col1.set_low().unwrap(); + let mut row1 = board.display_pins.row1; + + loop { + row1.set_low().unwrap(); + rprintln!("Dark!"); + timer.delay_ms(1_000_u32); + + row1.set_high().unwrap(); + rprintln!("Light!"); + timer.delay_ms(1_000_u32); + } +} diff --git a/microbit/src/05-led-roulette/it-blinks.md b/microbit/src/05-led-roulette/it-blinks.md index bc7707bc0..ce8f39c95 100644 --- a/microbit/src/05-led-roulette/it-blinks.md +++ b/microbit/src/05-led-roulette/it-blinks.md @@ -16,34 +16,8 @@ Inside our MCU, several so-called "timers" exist. They can do various things reg including simply pausing the execution of our program for a fixed amount of time. A very simple delay-based program that prints something every second might for example look like this: -```rs -#![deny(unsafe_code)] -#![no_main] -#![no_std] - -use cortex_m_rt::entry; -use embedded_hal::delay::DelayNS; -use rtt_target::{ - rtt_init_print, - rprintln, -}; -use panic_rtt_target as _; -use microbit::board::Board; -use microbit::hal::timer::Timer; - -#[entry] -fn main() -> ! { - rtt_init_print!(); - - let board = Board::take().unwrap(); - - let mut timer = Timer::new(board.TIMER0); - - loop { - timer.delay_ms(1_000u32); - rprintln!("1000 ms passed"); - } -} +``` rust +{{#include examples/it-blinks-1.rs}} ``` Note that we changed our panic implementation from `panic_halt` to @@ -52,7 +26,7 @@ RTT lines from `Cargo.toml` and comment the `panic-halt` one out, since Rust only allows one panic implementation at a time. In order to actually see the prints we have to change `Embed.toml` like shown on the marked lines (`<--- Here`): -``` +```toml [default.general] # chip = "nrf52833_xxAA" # uncomment this line for micro:bit V2 # chip = "nrf51822_xxAA" # uncomment this line for micro:bit V1 @@ -76,45 +50,8 @@ Now we've arrived at the point where we can combine our new knowledge about GPIO in order to actually make an LED on the back of the micro:bit blink. The resulting program is really just a mash-up of the one above and the one that turned an LED on in the last section and looks like this: -```rs -#![deny(unsafe_code)] -#![no_main] -#![no_std] - -use cortex_m_rt::entry; -use rtt_target::{ - rtt_init_print, - rprintln, -}; -use panic_rtt_target as _; -use embedded_hal::{ - delay::DelayNS, - digital::OutputPin, -}; -use microbit::board::Board; -use microbit::hal::timer::Timer; - -#[entry] -fn main() -> ! { - rtt_init_print!(); - - let mut board = Board::take().unwrap(); - - let mut timer = Timer::new(board.TIMER0); - - board.display_pins.col1.set_low().unwrap(); - let mut row1 = board.display_pins.row1; - - loop { - row1.set_low().unwrap(); - rprintln!("Dark!"); - timer.delay_ms(1_000_u16); - - row1.set_high().unwrap(); - rprintln!("Light!"); - timer.delay_ms(1_000_u16); - } -} +``` rust +{{#include examples/it-blinks-2.rs}} ``` And after putting the code into `src/main.rs` and a final `cargo embed` (with the proper flags) From 11f9aa1cf1dc9b71d27555bfaeda03ff967f7326 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Tue, 18 Jun 2024 20:50:30 +0200 Subject: [PATCH 11/14] Update 05-led-roulette/the-challenge.md to the new crate versions. --- microbit/src/05-led-roulette/the-challenge.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/microbit/src/05-led-roulette/the-challenge.md b/microbit/src/05-led-roulette/the-challenge.md index 613c56a31..a2f2de699 100644 --- a/microbit/src/05-led-roulette/the-challenge.md +++ b/microbit/src/05-led-roulette/the-challenge.md @@ -25,10 +25,11 @@ you can use the display API provided by the BSP. It works like this: use cortex_m_rt::entry; use rtt_target::rtt_init_print; use panic_rtt_target as _; +use embedded-hal::delay::DelayNS; use microbit::{ board::Board, display::blocking::Display, - hal::{prelude::*, Timer}, + hal::Timer, }; #[entry] @@ -36,8 +37,13 @@ fn main() -> ! { rtt_init_print!(); let board = Board::take().unwrap(); + let mut timer = Timer::new(board.TIMER0); let mut display = Display::new(board.display_pins); + + // Setup the display delay so the math works as expected later. + display.set_delay_ms(1); + let light_it_all = [ [1, 1, 1, 1, 1], [1, 1, 1, 1, 1], @@ -48,9 +54,11 @@ fn main() -> ! { loop { // Show light_it_all for 1000ms - display.show(&mut timer, light_it_all, 1000); + display.show(&mut timer, light_it_all, 1_000); + // clear the display again display.clear(); + timer.delay_ms(1000_u32); } } From ef9cde79422c61618ac70d7a05b3974aff40afe8 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Thu, 20 Jun 2024 09:59:02 +0200 Subject: [PATCH 12/14] Moved the 05-led-roulette the-challenge example to project examples --- .../05-led-roulette/examples/the-challenge.rs | 45 +++++++++++++++++++ microbit/src/05-led-roulette/the-challenge.md | 45 +------------------ 2 files changed, 46 insertions(+), 44 deletions(-) create mode 100644 microbit/src/05-led-roulette/examples/the-challenge.rs diff --git a/microbit/src/05-led-roulette/examples/the-challenge.rs b/microbit/src/05-led-roulette/examples/the-challenge.rs new file mode 100644 index 000000000..4f69c4814 --- /dev/null +++ b/microbit/src/05-led-roulette/examples/the-challenge.rs @@ -0,0 +1,45 @@ +#![deny(unsafe_code)] +#![no_main] +#![no_std] + +use cortex_m_rt::entry; +use rtt_target::rtt_init_print; +use panic_rtt_target as _; +use embedded_hal::delay::DelayNs; +use microbit::{ + board::Board, + display::blocking::Display, + hal::Timer, +}; + +#[entry] +fn main() -> ! { + rtt_init_print!(); + + let board = Board::take().unwrap(); + + let mut timer = Timer::new(board.TIMER0); + let mut display = Display::new(board.display_pins); + + // Setup the display delay so the math works as expected later. + display.set_delay_ms(1); + + let light_it_all = [ + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + [1, 1, 1, 1, 1], + ]; + + loop { + // Show light_it_all for 1000ms + display.show(&mut timer, light_it_all, 1_000); + + // clear the display again + display.clear(); + + timer.delay_ms(1000_u32); + } +} + diff --git a/microbit/src/05-led-roulette/the-challenge.md b/microbit/src/05-led-roulette/the-challenge.md index a2f2de699..8e84999c0 100644 --- a/microbit/src/05-led-roulette/the-challenge.md +++ b/microbit/src/05-led-roulette/the-challenge.md @@ -18,50 +18,7 @@ Since working with the LED pins separately is quite annoying you can use the display API provided by the BSP. It works like this: ```rust -#![deny(unsafe_code)] -#![no_main] -#![no_std] - -use cortex_m_rt::entry; -use rtt_target::rtt_init_print; -use panic_rtt_target as _; -use embedded-hal::delay::DelayNS; -use microbit::{ - board::Board, - display::blocking::Display, - hal::Timer, -}; - -#[entry] -fn main() -> ! { - rtt_init_print!(); - - let board = Board::take().unwrap(); - - let mut timer = Timer::new(board.TIMER0); - let mut display = Display::new(board.display_pins); - - // Setup the display delay so the math works as expected later. - display.set_delay_ms(1); - - let light_it_all = [ - [1, 1, 1, 1, 1], - [1, 1, 1, 1, 1], - [1, 1, 1, 1, 1], - [1, 1, 1, 1, 1], - [1, 1, 1, 1, 1], - ]; - - loop { - // Show light_it_all for 1000ms - display.show(&mut timer, light_it_all, 1_000); - - // clear the display again - display.clear(); - - timer.delay_ms(1000_u32); - } -} +{{#include examples/the-challenge.rs}} ``` Equipped with this API your task basically boils down to just having From 308915005742cc4c1c3e633ede36a5bcf9970776 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Tue, 18 Jun 2024 23:19:28 +0200 Subject: [PATCH 13/14] Update 05-led-roulette/my-solution.md and examples/my-solution.rs --- .../05-led-roulette/examples/my-solution.rs | 7 +++ microbit/src/05-led-roulette/my-solution.md | 60 ++++++++++--------- 2 files changed, 38 insertions(+), 29 deletions(-) diff --git a/microbit/src/05-led-roulette/examples/my-solution.rs b/microbit/src/05-led-roulette/examples/my-solution.rs index b75bccd04..21ddfeba0 100644 --- a/microbit/src/05-led-roulette/examples/my-solution.rs +++ b/microbit/src/05-led-roulette/examples/my-solution.rs @@ -21,8 +21,13 @@ fn main() -> ! { rtt_init_print!(); let board = Board::take().unwrap(); + let mut timer = Timer::new(board.TIMER0); let mut display = Display::new(board.display_pins); + + // Setup the display delay so the math works as expected later. + display.set_delay_ms(1); + let mut leds = [ [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], @@ -37,7 +42,9 @@ fn main() -> ! { for current_led in PIXELS.iter() { leds[last_led.0][last_led.1] = 0; leds[current_led.0][current_led.1] = 1; + display.show(&mut timer, leds, 30); + last_led = *current_led; } } diff --git a/microbit/src/05-led-roulette/my-solution.md b/microbit/src/05-led-roulette/my-solution.md index 37b06beac..9135fbe16 100644 --- a/microbit/src/05-led-roulette/my-solution.md +++ b/microbit/src/05-led-roulette/my-solution.md @@ -21,7 +21,7 @@ $ cargo embed --features v1 --target thumbv6m-none-eabi --release (...) ``` -If you want to debug your "release" mode binary you'll have to use a different GDB command: +If you want to debug your "release" mode binary you'll have to use a different GDB command to load the other binary: ``` console # For micro:bit v2 @@ -41,24 +41,25 @@ $ cargo size --features v2 --target thumbv7em-none-eabihf -- -A led-roulette : section size addr .vector_table 256 0x0 -.text 26984 0x100 -.rodata 2732 0x6a68 +.text 33564 0x100 +.rodata 4824 0x6a68 .data 0 0x20000000 +.gnu.sgstubs 0 ox9700 .bss 1092 0x20000000 .uninit 0 0x20000444 -.debug_abbrev 33941 0x0 -.debug_info 494113 0x0 -.debug_aranges 23528 0x0 -.debug_ranges 130824 0x0 -.debug_str 498781 0x0 -.debug_pubnames 143351 0x0 -.debug_pubtypes 124464 0x0 +.debug_loc 5446 0x0 +.debug_abbrev 22709 0x0 +.debug_info 630006 0x0 +.debug_aranges 22488 0x0 +.debug_ranges 186616 0x0 +.debug_str 726748 0x0 +.comment 64 0x0 .ARM.attributes 58 0x0 -.debug_frame 69128 0x0 -.debug_line 290580 0x0 -.debug_loc 1449 0x0 -.comment 109 0x0 -Total 1841390 +.debug_frame 71712 0x0 +.debug_line 320979 0x0 +.debug_pubnames 702 0x0 +.debug_pubtypes 71 0x0 +Total 2027335 $ cargo size --features v2 --target thumbv7em-none-eabihf --release -- -A @@ -66,24 +67,25 @@ $ cargo size --features v2 --target thumbv7em-none-eabihf --release -- -A led-roulette : section size addr .vector_table 256 0x0 -.text 6332 0x100 -.rodata 648 0x19bc +.text 6516 0x100 +.rodata 612 0x19bc .data 0 0x20000000 +.gnu.sgstubs 0 0x1ce0 .bss 1076 0x20000000 .uninit 0 0x20000434 -.debug_loc 9036 0x0 -.debug_abbrev 2754 0x0 -.debug_info 96460 0x0 -.debug_aranges 1120 0x0 -.debug_ranges 11520 0x0 -.debug_str 71325 0x0 -.debug_pubnames 32316 0x0 -.debug_pubtypes 29294 0x0 +.debug_loc 10784 0x0 +.debug_abbrev 3159 0x0 +.debug_info 63612 0x0 +.debug_aranges 1040 0x0 +.debug_ranges 11576 0x0 +.debug_str 69813 0x0 +.comment 64 0x0 .ARM.attributes 58 0x0 -.debug_frame 2108 0x0 -.debug_line 19303 0x0 -.comment 109 0x0 -Total 283715 +.debug_frame 2084 0x0 +.debug_line 18180 0x0 +.debug_pubnames 702 0x0 +.debug_pubtypes 71 0x0 +Total 189603 # micro:bit v1 $ cargo size --features v1 --target thumbv6m-none-eabi -- -A From c6e0e7a87e531be4a056261a505f01978f6789a3 Mon Sep 17 00:00:00 2001 From: Niki Guldbrand Date: Thu, 20 Jun 2024 10:08:52 +0200 Subject: [PATCH 14/14] microbit version 0.15.0 crates has been released A new version of the microbit crates has been released. Cargo.toml * microbit-v2 0.14.0 -> 0.15.0 Which updated HAL crates to version 0.18.0 * microbit 0.14.0 -> 0.15.0 In connection with this I moved all the examples in the book out of book text and made them project examples, and used an include statement, like it's done in `my-solution`, which makes checking the examples faster, and I also cought a couple of typos I made when I updated the text, which rust-analyser didn't like. The examples can be run manually with commands like: `cargo embed --target thumbv7em-none-eabihf --features v2 --example it-blinks-1` Don't know if this messes with any automatic tests yet. --- microbit/src/05-led-roulette/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/microbit/src/05-led-roulette/Cargo.toml b/microbit/src/05-led-roulette/Cargo.toml index 8159715d7..52e314d05 100644 --- a/microbit/src/05-led-roulette/Cargo.toml +++ b/microbit/src/05-led-roulette/Cargo.toml @@ -5,11 +5,11 @@ authors = ["Henrik Böving "] edition = "2021" [dependencies.microbit-v2] -version = "0.14.0" +version = "0.15.0" optional = true [dependencies.microbit] -version = "0.14.0" +version = "0.15.0" optional = true [dependencies]