From 14d76fb10ece51f1f57620e249cdc48fd43700a0 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 21 Feb 2023 16:17:36 +0100 Subject: [PATCH 01/47] add pages to book --- embedded-workshop-book/src/SUMMARY.md | 2 ++ embedded-workshop-book/src/button-implementation.md | 0 embedded-workshop-book/src/uarte-implementation.md | 0 3 files changed, 2 insertions(+) create mode 100644 embedded-workshop-book/src/button-implementation.md create mode 100644 embedded-workshop-book/src/uarte-implementation.md diff --git a/embedded-workshop-book/src/SUMMARY.md b/embedded-workshop-book/src/SUMMARY.md index 696a806..99701c3 100644 --- a/embedded-workshop-book/src/SUMMARY.md +++ b/embedded-workshop-book/src/SUMMARY.md @@ -26,6 +26,8 @@ - [Starting a Project from Scratch](./from-scratch.md) - [Down the Stack Workbook](./down-the-stack.md) - [BSC Exercise](./bsc-exercise.md) + - [Button Implementation](./button-implementation.md) + - [UARTE Implementation](./uarte-implementation.md) - [Advanced Workbook](./advanced-workbook.md) - [Code Organization](./code-organisation.md) - [Listing USB Devices](./listing-usb-devices.md) diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md new file mode 100644 index 0000000..e69de29 diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md new file mode 100644 index 0000000..e69de29 From 3afc29ca72a31162ca496bf3a85b3f0f8fdb697a Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 21 Feb 2023 16:22:37 +0100 Subject: [PATCH 02/47] add step by step solution --- .../src/button-implementation.md | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index e69de29..045d5ba 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -0,0 +1,44 @@ +# Write the Button Implementation +## Step-by-Step Solution + +1. Read the docs! +Read docs, section 8.7 for info about pins and pin configuration related to the buttons. Note down the pins that the buttons are connected to. +The pins need to be configured as input pins with an internal pull-up. The pins as well as the configurations are defined as types in the `nrf-hal` in the `gpio` peripheral. Add the following imports: `Input` and `PullUp`. + +2. Add the structs that represent the buttons as a group and a generic single button. + +Add the struct that represents the single button. It has only one field, `inner`. The type of this button is the pin configuration: `Pin>` + +Add the `struct` that represents the group of buttons has four fields, one for each button. The field name contains the number that corresponds to the button numeration on the board. The of type of each field is the struct that represents the generic single button. + +Add doc comments for every struct and field! + +Building this code should return a warning: field `inner` is never read + + +1. Implement the button function. + +Add an `impl` block for the `struct Button`. Add a method `is_pushed` that takes in the struct as `&self` and returns a bool, if the button is pushed. + +Now remember, the pins the buttons are connected to are configured as active low. For buttons this means, that the pin is pulled low, when the button is pushed. + +In the `nrf-hal` you can find a method to check if a single pin is low. To use it, you have to add the following line to your `nrf52840_hal` imports: `prelude::InputPin`. + + + + +4. Bring up the pins! + +Go to `pub fn init()`, the function that initializes the board's peripherals. Get your notes for the pin numbers that are reserver for the buttons. Configure each pin as degraded, pull-up input pin and bind it to a variable that makes it clear what button number it is connected to. + +Building this code brings up warnings about unused variables. + + +5. Add everything to the board struct. + +In the definition of the board struct add a field for the `struct Buttons` +In the pub `fn init()` function. Add the button field to the instantiation of the Board struct, assigning the pins you defined earlier to the respective buttons. + + + +6. Run the example! \ No newline at end of file From c1825d1185ea2fba752918b169bc7acd9de68c16 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 21 Feb 2023 16:24:41 +0100 Subject: [PATCH 03/47] add exercise intro draft --- embedded-workshop-book/src/bsc-exercise.md | 57 +++++++++++++--------- 1 file changed, 34 insertions(+), 23 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index 6aa4dbe..65eea61 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -1,37 +1,48 @@ # BSC Exercise In this exercise you will learn how to write a board support crate. -The bsc template will already contain the led and timer implementation. -The radio and USB/Power implementations will be deleted, because that just takes up unnecessary space and adds to confusion. +The template will already contain the LED and timer implementation. + +Note: Introduction to the exercise is a guided tour through the template and running the hello example. ## Learning goals * implement buttons functionality -* uarte implementation -* impl blocks, associated functions, methods +* UARTE implementation +* `impl` blocks, associated functions, methods * generate docs! +## Prerequesits + +* +## Tasks +* Write a button implementation. This entails the following steps + * `struct Buttons` with 4 fields, that represents each of the four buttons + * `struct Button` that is a wrapper for the pin that a single button is connected to + * a method `is_pushed` that checks if a single button is pushed. + * initialize the pins in `fn init()` + * add the `struct Button` to the definition and instantiation of `struct Board`. + * Run `apps/buttons.rs` to test. +* Write a UARTE implementation. + +## Knowledge + +## Representation of Peripherals +The boards peripherals are represented as nested structs. The `struct Board` contains fields that represent single peripherals or groups of peripherals as structs, which in turn either contain a field of the single peripheral or ... + +You have to add structs to represent the buttons and the UARTE peripheral to the board struct. + +## Comments + + +## impl blocks + +## visibility of structs, fields and functions: the pub keyword + + +## Hardware documentation for pin configuration -## Steps -### Write a button implementation -* add field in the board struct -* add struct for all buttons -* add struct for the single button -* Read docs, section 8.7 for info about pins and pin configuration -* add button bring up to board init -* add doc lines every where! -* add methods in impl block: - * detect button push - * debounce button function? like in knurling session, requires implementation of a second timer, just for this? -### Write Uarte implementation -* add field to the board struct -* add struct for the instance, how to figure out what the type of the inner field is -* create instance in init, add baudrate, parity etc. -* add to instantiation of board struct -* impl fmt::Write for the Uarte struct, simple write does not work because of dma -* example code with button is not a good idea for the simple button implementation. -I think this is plenty for an hour. \ No newline at end of file From bf87279d4a7622b4827089c0e58dc88a5c083492 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 21 Feb 2023 16:24:57 +0100 Subject: [PATCH 04/47] add uarte draft --- embedded-workshop-book/src/uarte-implementation.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index e69de29..596231b 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -0,0 +1,10 @@ +# Write the Uarte implementation +## Step-by-Step Solution +* add field to the board struct +* add struct for the instance, how to figure out what the type of the inner field is +* create instance in init, add baudrate, parity etc. +* add to instantiation of board struct +* impl fmt::Write for the Uarte struct, simple write does not work because of dma +* example code with button is not a good idea for the simple button implementation. + +I think this is plenty for an hour. \ No newline at end of file From dffa5d483bcaf4721aff028fbf565a39202a833f Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Wed, 22 Feb 2023 19:11:13 +0100 Subject: [PATCH 05/47] add learning goals --- embedded-workshop-book/src/bsc-exercise.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index 65eea61..a10226a 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -1,16 +1,19 @@ # BSC Exercise In this exercise you will learn how to write a board support crate. -The template will already contain the LED and timer implementation. +The template `dk_bsc/src/lib.rs` already contains the LED and Timer implementations. You will implement the buttons and the UARTE peripheral. -Note: Introduction to the exercise is a guided tour through the template and running the hello example. +Note: Introduction to the exercise is a guided tour through the template, and it's architecture. Make the participants aware of the placeholders for their implementations. run the hello example on the unmodified lib. -## Learning goals -* implement buttons functionality +## You will learn how to +* modify the `init()` function that brings up the board's peripherals +* how to configure pins +* how to write a function that checks the state of a pin +* write methods for a `struct` * UARTE implementation -* `impl` blocks, associated functions, methods -* generate docs! +* implement a Trait +* to document and generate docs for your own library! ## Prerequesits From 453eb95928c4cec956b68dba6e282cbc2aa96932 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Wed, 22 Feb 2023 19:11:41 +0100 Subject: [PATCH 06/47] add most of exercise text --- .../src/uarte-implementation.md | 55 +++++++++++++++++-- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 596231b..77b5bcf 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -1,10 +1,53 @@ # Write the Uarte implementation ## Step-by-Step Solution -* add field to the board struct -* add struct for the instance, how to figure out what the type of the inner field is -* create instance in init, add baudrate, parity etc. -* add to instantiation of board struct -* impl fmt::Write for the Uarte struct, simple write does not work because of dma -* example code with button is not a good idea for the simple button implementation. +1. Check Documentation. + The UART protocol requires four pins, they are usually labelled: +* RXD +* TXD +* CTS +* RTS + Check the documentation to find out which pins are reserved for these and what their configuration needs to be. +2. Explore the `nrf-hal` to find out what needs to be done. + + +The `nrf52840-hal` is a crate that exports all the `52840` flagged features from the `nrf-hal-common`. Let's take a look at the [Uarte module](https://github.com/nrf-rs/nrf-hal/blob/v0.14.1/nrf-hal-common/src/uarte.rs). + +In line 16 we see, that the nRF52840 uses the `hal::pac::UARTE1` peripheral. +In line 44 you find the `struct Uarte(T)`, the interface to a UARTE instance `T`. Besides the instance `T`, the instantiating method takes variables of the following types as arguments: `Pins`, `Parity` and `Baudrate`. + +A quick search of the document reveals where to find all of them: +* `Pins`: Line 463 +* `Parity` and `Baudrate`: Re-export on line 34 + +Add the following lines as import: +```rust +use hal::pac::uarte0::{ + baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; +use hal::uarte; +``` + +3. Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. + +The struct has one field labelled `inner`, it contains the `UARTE1` instance. + +4. Bring up the peripheral in the `fn init()` + +Take a closer look at the definition of the `Pins` struct. Import the types of the pin configuration that you don't have yet. Note that the third and fourth pin are each wrapped in an `Option`. +Level? +Create an instance of this struct in `fn init()` with the appropriate pins and configurations. + +Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)`. The UARTE0 instance can be found in the `periph` variable. Set parity to `INCLUDED` and the baud rate to `BAUD115200`. + + +5. Board struct + +Add a field for the Uarte struct in the Board struct. +add the field to the instance of the Board struct in `fn init()`. + +6. Implementing the `fmt::Write` trait + +We can't just write to the Uarte instance. A simple write would write from flash memory. This does not work because of EasyDMA. We have to write a function that implements the `fmt::Write` trait. This trait guarantees that the buffer is fully and successfully written on a stack allocated buffer, before it returns. + + I think this is plenty for an hour. \ No newline at end of file From a142d1579d2162c545652d46f3ccbd1ac8821c25 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Mon, 27 Feb 2023 17:00:21 +0100 Subject: [PATCH 07/47] finish draft of uarte implementation --- .../src/uarte-implementation.md | 61 ++++++++++++++++--- 1 file changed, 51 insertions(+), 10 deletions(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 77b5bcf..3b0f4ba 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -1,13 +1,17 @@ # Write the Uarte implementation ## Step-by-Step Solution -1. Check Documentation. - The UART protocol requires four pins, they are usually labelled: + +### Check Documentation. + +The UART protocol requires four pins, they are usually labelled: * RXD * TXD * CTS * RTS - Check the documentation to find out which pins are reserved for these and what their configuration needs to be. -2. Explore the `nrf-hal` to find out what needs to be done. + +Check the documentation to find out which pins are reserved for these and what their configuration needs to be. + +### Explore the `nrf-hal` to find out what needs to be done. The `nrf52840-hal` is a crate that exports all the `52840` flagged features from the `nrf-hal-common`. Let's take a look at the [Uarte module](https://github.com/nrf-rs/nrf-hal/blob/v0.14.1/nrf-hal-common/src/uarte.rs). @@ -26,11 +30,11 @@ use hal::pac::uarte0::{ use hal::uarte; ``` -3. Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. +### Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. The struct has one field labelled `inner`, it contains the `UARTE1` instance. -4. Bring up the peripheral in the `fn init()` +### Bring up the peripheral in the `fn init()` Take a closer look at the definition of the `Pins` struct. Import the types of the pin configuration that you don't have yet. Note that the third and fourth pin are each wrapped in an `Option`. Level? @@ -39,15 +43,52 @@ Create an instance of this struct in `fn init()` with the appropriate pins and c Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)`. The UARTE0 instance can be found in the `periph` variable. Set parity to `INCLUDED` and the baud rate to `BAUD115200`. -5. Board struct +### Board struct -Add a field for the Uarte struct in the Board struct. +Add a field for the `Uarte` struct in the Board struct. add the field to the instance of the Board struct in `fn init()`. -6. Implementing the `fmt::Write` trait +### Implementing the `fmt::Write` trait We can't just write to the Uarte instance. A simple write would write from flash memory. This does not work because of EasyDMA. We have to write a function that implements the `fmt::Write` trait. This trait guarantees that the buffer is fully and successfully written on a stack allocated buffer, before it returns. +What exactly does the trait guarantee? +Create a public method `write_str`. It takes a mutable reference to self and a `&str` as argument. It returns an `fmt::Result` -I think this is plenty for an hour. \ No newline at end of file +Create a buffer. The type is an array of 16 u8, set to all 0. + +To copy all data into an on-stack buffer, iterate over every chunk of the string to copy it into the buffer: + +```rust +for block in string.as_bytes().chunks(16) { + buf[..block.len()].copy_from_slice(block); + self.inner.write(&buf[..block.len()]).map_err(|_| fmt::Error)?; +} +``` +return `Ok(())` + +### Connect your computer to the virtual UART + +Use the following command to find the address of the nRF52840-DK on your computer. + +``` +ls /dev/tty* +``` + +Run the following command to run `screen` with the nRF52840-DK with 115200 baud. + +``` +screen 115200 +``` + +### Run the example. + +In another terminal window go into the folder `down-the-stack/apps`. + +Use the following command. +``` +cargo run --bin uarte_print +``` + +On your terminal window where `screen` runs, "Hello, World" should appear. \ No newline at end of file From 16fbd1c39c634fefce136e69848c81490fc42d50 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Mon, 27 Feb 2023 17:01:02 +0100 Subject: [PATCH 08/47] rm button from example --- down-the-stack/apps/src/bin/uarte_print.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/down-the-stack/apps/src/bin/uarte_print.rs b/down-the-stack/apps/src/bin/uarte_print.rs index a2aebfc..cf1e6d5 100644 --- a/down-the-stack/apps/src/bin/uarte_print.rs +++ b/down-the-stack/apps/src/bin/uarte_print.rs @@ -4,6 +4,7 @@ use cortex_m::asm; use cortex_m_rt::entry; use core::fmt::Write; + // this imports `down-the-stack/apps/lib.rs` to retrieve our global logger + panicking-behavior use apps as _; @@ -14,16 +15,17 @@ fn main() -> ! { let board = dk_bsc::init().unwrap(); - let button_1 = board.buttons.b_1; let mut uarte = board.uarte; + + + let tx_buffer = "Hello\n"; + uarte.write_str(tx_buffer).unwrap(); // this program does not `exit`; use Ctrl+C to terminate it loop { - if button_1.is_pushed() { - uarte.write_str(tx_buffer).unwrap(); - } + asm::nop(); } } From 166550667bc00d0b3bf3ba644ec7a5bd490ad23c Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Mon, 27 Feb 2023 17:06:04 +0100 Subject: [PATCH 09/47] correct uarte peripheral --- down-the-stack/dk_bsc/src/lib_solution.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 267f02b..96df221 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -13,14 +13,14 @@ use core::{ use cortex_m::asm; use embedded_hal::digital::v2::{OutputPin as _, StatefulOutputPin}; use nrf52840_hal as hal; -pub use hal::pac::{ - UARTE1, uarte0::{ - baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}}; +pub use hal::pac::uarte0::{ + baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; use hal::{ - gpio::{p0, Level, Output, Input, PullUp, Pin, Port, PushPull}, - timer::OneShot, prelude::InputPin, +gpio::{p0, Level, Output, Input, PullUp, Pin, Port, PushPull}, +timer::OneShot, prelude::InputPin, +uarte, }; use defmt; @@ -186,7 +186,7 @@ impl ops::DerefMut for Timer { /// Uarte peripheral pub struct Uarte { - inner: hal::Uarte, + inner: hal::Uarte, } impl fmt::Write for Uarte { @@ -240,7 +240,7 @@ pub fn init() -> Result { }; - let uarte = hal::uarte::Uarte::new(periph.UARTE0, pins, Parity::INCLUDED, Baudrate::BAUD115200); + let uarte = hal::uarte::Uarte::new(periph.UARTE1, pins, Parity::INCLUDED, Baudrate::BAUD115200); // --- Exercise --- 🔼 Ok(Board { From cd345aad957be77a182ac82fd66fa20c28529882 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 16:45:34 +0100 Subject: [PATCH 10/47] mark code --- down-the-stack/dk_bsc/src/lib_solution.rs | 30 ++++++++++++----------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 96df221..407b5b9 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -30,16 +30,16 @@ use defmt_rtt as _; // global logger pub struct Board { /// LEDs pub leds: Leds, - // --- Exercise --- 🔽 + // 🔽 --- Exercise Button --- 🔽 /// Buttons pub buttons: Buttons, - // --- Exercise --- 🔼 + // 🔼 --- Exercise Button --- 🔼 /// Timer pub timer: Timer, - // --- Exercise --- 🔽 + // 🔽 --- Exercise UARTE --- 🔽 /// uarte interface pub uarte: Uarte, - // --- Exercise --- 🔼 + // 🔼 --- Exercise UARTE --- 🔼 } /// All LEDs on the board @@ -103,7 +103,7 @@ impl Led { } } } -// --- Exercise --- 🔽 +// 🔽 --- Exercise Button --- 🔽 /// All buttons on the board pub struct Buttons { /// BUTTON1: pin P0.11, green LED @@ -127,7 +127,7 @@ impl Button { self.inner.is_low() == Ok(true) } } -// --- Exercise --- 🔼 +// 🔼 --- Exercise Button --- 🔼 /// A timer for creating blocking delays pub struct Timer { @@ -184,6 +184,7 @@ impl ops::DerefMut for Timer { } } +// 🔽 --- Exercise UARTE --- 🔽 /// Uarte peripheral pub struct Uarte { inner: hal::Uarte, @@ -203,6 +204,7 @@ impl fmt::Write for Uarte { Ok(()) } } +// 🔼 --- Exercise UARTE --- 🔼 /// Initializes the board /// @@ -218,19 +220,19 @@ pub fn init() -> Result { let led_3 = pins.p0_15.degrade().into_push_pull_output(Level::High); let led_4 = pins.p0_16.degrade().into_push_pull_output(Level::High); - // --- Exercise --- 🔽 + // 🔽 --- Exercise Button --- 🔽 // Buttons let b_1 = pins.p0_11.degrade().into_pullup_input(); let b_2 = pins.p0_12.degrade().into_pullup_input(); let b_3 = pins.p0_24.degrade().into_pullup_input(); let b_4 = pins.p0_25.degrade().into_pullup_input(); - // --- Exercise --- 🔼 + // 🔼 --- Exercise Button --- 🔼 defmt::debug!("I/O pins have been configured for digital output"); let timer = hal::Timer::new(periph.TIMER0); - // --- Exercise --- 🔽 + // 🔽 --- Exercise UARTE --- 🔽 // Uarte let pins = hal::uarte::Pins { rxd: pins.p0_08.degrade().into_floating_input(), @@ -241,7 +243,7 @@ pub fn init() -> Result { let uarte = hal::uarte::Uarte::new(periph.UARTE1, pins, Parity::INCLUDED, Baudrate::BAUD115200); - // --- Exercise --- 🔼 + // 🔼 --- Exercise UARTE --- 🔼 Ok(Board { leds: Leds { @@ -251,20 +253,20 @@ pub fn init() -> Result { led_4: Led { inner: led_4 }, }, - // --- Exercise --- 🔽 + // 🔽 --- Exercise Button --- 🔽 buttons: Buttons { b_1: Button { inner: b_1}, b_2: Button { inner: b_2}, b_3: Button { inner: b_3}, b_4: Button { inner: b_4}, }, - // --- Exercise --- 🔼 + // 🔼 --- Exercise Button --- 🔼 timer: Timer { inner: timer }, - // --- Exercise --- 🔽 + // 🔽 --- Exercise UARTE --- 🔽 uarte: Uarte { inner: uarte }, - // --- Exercise --- 🔼 + // 🔼 --- Exercise UARTE --- 🔼 }) } else { Err(()) From 373e791693931ca557ef2c7547ca96bfe5be8c20 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 16:46:03 +0100 Subject: [PATCH 11/47] clean text --- embedded-workshop-book/src/bsc-exercise.md | 27 ++++++++++--------- .../src/button-implementation.md | 26 ++++++++++++------ 2 files changed, 32 insertions(+), 21 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index a10226a..aed8f7e 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -15,17 +15,17 @@ Note: Introduction to the exercise is a guided tour through the template, and it * implement a Trait * to document and generate docs for your own library! -## Prerequesits +## Prerequisites +[todo!] -* ## Tasks * Write a button implementation. This entails the following steps - * `struct Buttons` with 4 fields, that represents each of the four buttons - * `struct Button` that is a wrapper for the pin that a single button is connected to - * a method `is_pushed` that checks if a single button is pushed. - * initialize the pins in `fn init()` - * add the `struct Button` to the definition and instantiation of `struct Board`. - * Run `apps/buttons.rs` to test. + ✅ `struct Buttons` with 4 fields, that represents each of the four buttons + ✅ `struct Button` that is a wrapper for the pin that a single button is connected to + ✅ a method `is_pushed` that checks if a single button is pushed. + ✅ initialize the pins in `fn init()` + ✅ add the `struct Button` to the definition and instantiation of `struct Board`. + ✅ Run `apps/buttons.rs` to test. * Write a UARTE implementation. ## Knowledge @@ -34,18 +34,19 @@ Note: Introduction to the exercise is a guided tour through the template, and it The boards peripherals are represented as nested structs. The `struct Board` contains fields that represent single peripherals or groups of peripherals as structs, which in turn either contain a field of the single peripheral or ... You have to add structs to represent the buttons and the UARTE peripheral to the board struct. +[todo!] ## Comments - +[todo!] ## impl blocks - -## visibility of structs, fields and functions: the pub keyword - +[todo!] +## Visibility of structs, fields and functions: the pub keyword +[todo!] ## Hardware documentation for pin configuration - +Go to [Nordic Infocenter](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/intro.html) to download the User Guide. You can find all the information that is relevant to this exercise in there. diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index 045d5ba..96bbd47 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -1,11 +1,12 @@ # Write the Button Implementation ## Step-by-Step Solution -1. Read the docs! -Read docs, section 8.7 for info about pins and pin configuration related to the buttons. Note down the pins that the buttons are connected to. +### Step 1: Read the docs! + +Go to [Nordic Infocenter](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/intro.html) to download the User Guide. Read docs, section 8.7 for info about pins and pin configuration related to the buttons. Note down the pins that the buttons are connected to. The pins need to be configured as input pins with an internal pull-up. The pins as well as the configurations are defined as types in the `nrf-hal` in the `gpio` peripheral. Add the following imports: `Input` and `PullUp`. -2. Add the structs that represent the buttons as a group and a generic single button. +### Step 2: Add the structs that represent the buttons as a group and a generic single button. Add the struct that represents the single button. It has only one field, `inner`. The type of this button is the pin configuration: `Pin>` @@ -13,10 +14,11 @@ Add the `struct` that represents the group of buttons has four fields, one for e Add doc comments for every struct and field! -Building this code should return a warning: field `inner` is never read +Building this code should return a warning: field `inner` is never read. + -1. Implement the button function. +### Step 3: Implement the button function. Add an `impl` block for the `struct Button`. Add a method `is_pushed` that takes in the struct as `&self` and returns a bool, if the button is pushed. @@ -27,18 +29,26 @@ In the `nrf-hal` you can find a method to check if a single pin is low. To use i -4. Bring up the pins! +### Step 4: Bring up the pins! Go to `pub fn init()`, the function that initializes the board's peripherals. Get your notes for the pin numbers that are reserver for the buttons. Configure each pin as degraded, pull-up input pin and bind it to a variable that makes it clear what button number it is connected to. Building this code brings up warnings about unused variables. -5. Add everything to the board struct. +### Step 5: Add everything to the board struct. In the definition of the board struct add a field for the `struct Buttons` In the pub `fn init()` function. Add the button field to the instantiation of the Board struct, assigning the pins you defined earlier to the respective buttons. -6. Run the example! \ No newline at end of file +### Step 6: Run the example! + +Go to `/down-the-stack/apps` + +Run the following command: + +```shell +cargo run --bin button +``` \ No newline at end of file From a1e990b1e9d9f8db266f2080bdee97ae9ff36d16 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 16:58:17 +0100 Subject: [PATCH 12/47] Intro to testing --- embedded-workshop-book/src/bsc-exercise.md | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index aed8f7e..1eb4e08 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -1,9 +1,17 @@ # BSC Exercise -In this exercise you will learn how to write a board support crate. -The template `dk_bsc/src/lib.rs` already contains the LED and Timer implementations. You will implement the buttons and the UARTE peripheral. +In this exercise you will learn how to write a board support crate by implementing buttons and the UARTE peripheral. -Note: Introduction to the exercise is a guided tour through the template, and it's architecture. Make the participants aware of the placeholders for their implementations. run the hello example on the unmodified lib. +The template `down-the-stack/dk_bsc/src/lib.rs` already contains the LED and Timer implementations. + +You can test after each step by running the following command out of `down-the-stack/apps` +``` +cargo run --bin hello +``` + +This program will not call any of the functions you are implementing, so it does not matter if they are incomplete. It will refuse to build if there are errors present in the lib! + +Note for trainer: Introduction to the exercise is a guided tour through the template, and it's architecture. Make the participants aware of the placeholders for their implementations. run the hello example on the unmodified lib. ## You will learn how to From b2adf4a8d19f4ce5d07b9bcfa8f5277b06f74fc0 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 16:59:07 +0100 Subject: [PATCH 13/47] add todo --- embedded-workshop-book/src/bsc-exercise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index 1eb4e08..a937e63 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -35,7 +35,7 @@ Note for trainer: Introduction to the exercise is a guided tour through the temp ✅ add the `struct Button` to the definition and instantiation of `struct Board`. ✅ Run `apps/buttons.rs` to test. * Write a UARTE implementation. - +[todo!] ## Knowledge ## Representation of Peripherals From 34654411087b602f9b20ade9e8ad2f9e9521b144 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 17:08:38 +0100 Subject: [PATCH 14/47] add comments and solution file --- embedded-workshop-book/src/bsc-exercise.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index a937e63..d1cd977 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -8,8 +8,9 @@ You can test after each step by running the following command out of `down-the-s ``` cargo run --bin hello ``` +This program will not call any of the functions you are implementing, so it does not matter if they are incomplete. It will refuse to build if there are errors present in the `lib.rs`! -This program will not call any of the functions you are implementing, so it does not matter if they are incomplete. It will refuse to build if there are errors present in the lib! +`down-the-stack/dk_bsc/src/lib_solution.rs` contains the full solution code. Note for trainer: Introduction to the exercise is a guided tour through the template, and it's architecture. Make the participants aware of the placeholders for their implementations. run the hello example on the unmodified lib. @@ -45,7 +46,12 @@ You have to add structs to represent the buttons and the UARTE peripheral to the [todo!] ## Comments -[todo!] +The `lib.rs` has an attribute #![deny(missing_docs)]. This means, that missing doc comments for structs are returned as compiler errors, to remind you to document your work properly. + +```rust +/// This is a doc comment +// This is a normal comment +``` ## impl blocks [todo!] From 71ad8b0b5a65c66c6381119c7e2e1c37826326d0 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 17:52:41 +0100 Subject: [PATCH 15/47] clarification --- .../src/uarte-implementation.md | 51 ++++++++++--------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 3b0f4ba..5885c05 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -1,7 +1,7 @@ # Write the Uarte implementation ## Step-by-Step Solution -### Check Documentation. +### Step 1: Check Documentation. The UART protocol requires four pins, they are usually labelled: * RXD @@ -9,12 +9,12 @@ The UART protocol requires four pins, they are usually labelled: * CTS * RTS -Check the documentation to find out which pins are reserved for these and what their configuration needs to be. +Check the User Guide in section 7.2 to find to find out which pins are reserved for these and what their configuration needs to be. -### Explore the `nrf-hal` to find out what needs to be done. +### Step 2: Explore the `nrf-hal` to find out what needs to be done. -The `nrf52840-hal` is a crate that exports all the `52840` flagged features from the `nrf-hal-common`. Let's take a look at the [Uarte module](https://github.com/nrf-rs/nrf-hal/blob/v0.14.1/nrf-hal-common/src/uarte.rs). +The `nrf52840-hal` is a crate that exports all the `52840` flagged features from the `nrf-hal-common`. Let's take a look at the nRF-Hal [Uarte module](https://github.com/nrf-rs/nrf-hal/blob/v0.14.1/nrf-hal-common/src/uarte.rs). In line 16 we see, that the nRF52840 uses the `hal::pac::UARTE1` peripheral. In line 44 you find the `struct Uarte(T)`, the interface to a UARTE instance `T`. Besides the instance `T`, the instantiating method takes variables of the following types as arguments: `Pins`, `Parity` and `Baudrate`. @@ -30,33 +30,35 @@ use hal::pac::uarte0::{ use hal::uarte; ``` -### Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. +### Step 3: Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. -The struct has one field labelled `inner`, it contains the `UARTE1` instance. +The struct has one field labelled `inner`, it contains the `UARTE1` instance: `hal::Uarte`. + +### Step 4: Bring up the peripheral in the `fn init()` -### Bring up the peripheral in the `fn init()` +Take a closer look at the definition of the `uarte::Pins` struct. Import the types of the pin configuration that you don't have yet. Note, that the third and fourth pin are each wrapped in an `Option`. +Create an instance of this struct in `fn init()` with the appropriate pins and configurations. Set the output pin's level to `Level::High`. -Take a closer look at the definition of the `Pins` struct. Import the types of the pin configuration that you don't have yet. Note that the third and fourth pin are each wrapped in an `Option`. -Level? -Create an instance of this struct in `fn init()` with the appropriate pins and configurations. +Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)` that you bind to a variable. This instantiating method takes four arguments: +* The `UARTE1` instance can be found in the `periph` variable. +* Your instance of the `uarte::Pins` struct. +* Set parity to `Parity::INCLUDED` +* set the baud rate to `Baudrate::BAUD115200`. + -Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)`. The UARTE0 instance can be found in the `periph` variable. Set parity to `INCLUDED` and the baud rate to `BAUD115200`. + +### Step 5: Board struct - -### Board struct - -Add a field for the `Uarte` struct in the Board struct. -add the field to the instance of the Board struct in `fn init()`. - -### Implementing the `fmt::Write` trait +Add a field for the `Uarte` struct in the `Board` struct. +add the field to the instance of the `Board` struct in `fn init()`. + +### Step 6: Implementing the `fmt::Write` trait We can't just write to the Uarte instance. A simple write would write from flash memory. This does not work because of EasyDMA. We have to write a function that implements the `fmt::Write` trait. This trait guarantees that the buffer is fully and successfully written on a stack allocated buffer, before it returns. -What exactly does the trait guarantee? - Create a public method `write_str`. It takes a mutable reference to self and a `&str` as argument. It returns an `fmt::Result` -Create a buffer. The type is an array of 16 u8, set to all 0. +Create a buffer. The type is an `array` of 16 u8, set to all 0. To copy all data into an on-stack buffer, iterate over every chunk of the string to copy it into the buffer: @@ -68,7 +70,8 @@ for block in string.as_bytes().chunks(16) { ``` return `Ok(())` -### Connect your computer to the virtual UART +### Step 7: Connect your computer to the virtual UART +[directions for mac present, linux and windows are missing.] Use the following command to find the address of the nRF52840-DK on your computer. @@ -79,10 +82,10 @@ ls /dev/tty* Run the following command to run `screen` with the nRF52840-DK with 115200 baud. ``` -screen 115200 +screen
115200 ``` -### Run the example. +### Step 7: Run the example. In another terminal window go into the folder `down-the-stack/apps`. From 59a08c6854610185617d1eadd58aec1139a7f1e7 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 17:53:42 +0100 Subject: [PATCH 16/47] correct message --- down-the-stack/apps/src/bin/uarte_print.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/down-the-stack/apps/src/bin/uarte_print.rs b/down-the-stack/apps/src/bin/uarte_print.rs index cf1e6d5..5e434d8 100644 --- a/down-the-stack/apps/src/bin/uarte_print.rs +++ b/down-the-stack/apps/src/bin/uarte_print.rs @@ -14,14 +14,9 @@ fn main() -> ! { // to `defmt-trace` by changing the `default = []` entry in `[features]` let board = dk_bsc::init().unwrap(); - let mut uarte = board.uarte; - - - - - let tx_buffer = "Hello\n"; + let tx_buffer = "Hello, World!\n"; uarte.write_str(tx_buffer).unwrap(); // this program does not `exit`; use Ctrl+C to terminate it From 37930c3913f39a16311d58ee555d30c144fae4a3 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 18:08:33 +0100 Subject: [PATCH 17/47] add uarte tasks --- embedded-workshop-book/src/bsc-exercise.md | 25 +++++++++++++++------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index d1cd977..a5545fd 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -28,15 +28,24 @@ Note for trainer: Introduction to the exercise is a guided tour through the temp [todo!] ## Tasks -* Write a button implementation. This entails the following steps - ✅ `struct Buttons` with 4 fields, that represents each of the four buttons - ✅ `struct Button` that is a wrapper for the pin that a single button is connected to - ✅ a method `is_pushed` that checks if a single button is pushed. - ✅ initialize the pins in `fn init()` - ✅ add the `struct Button` to the definition and instantiation of `struct Board`. +* Write a button implementation. This entails the following steps: + ✅ Add `struct Buttons` with 4 fields, that represents each of the four buttons. + ✅ Add `struct Button` that is a wrapper for the pin that a single button is connected to. + ✅ Write a method `is_pushed` that checks if a single button is pushed. + ✅ Initialize the pins in `fn init()`. + ✅ Add the `struct Button` to the definition and instantiation of `struct Board`. ✅ Run `apps/buttons.rs` to test. -* Write a UARTE implementation. -[todo!] + ✅ Run `cargo doc` out of the apps folder to find all your doc comments! +* Write a UARTE implementation. This entails the following steps: + ✅ Check the `uarte` module of the `nrf-hal` for requirements of the instantiating method. + ✅ Add `struct Uarte` that serves as wrapper for the `UARTE1` instance. + ✅ Initialize the UARTE1 peripheral in `fn init()` using the following settings: + * parity: included + * baudrate: 115200 baud + ✅ Add `struct Uarte` to the definition and instantiation of `struct Board`. + ✅ Implement the `fmt::Write` trait for `struct Uarte`. + ✅ Connect your computer to the virtual UART port with `screen` + ✅ Run `apps/uarte_print.rs` to test. ## Knowledge ## Representation of Peripherals From 5b11a4de97d61438b03264ad3e7ca90b420f5521 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 18:12:51 +0100 Subject: [PATCH 18/47] add generate docs instruction --- embedded-workshop-book/src/button-implementation.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index 96bbd47..afc4064 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -51,4 +51,12 @@ Run the following command: ```shell cargo run --bin button +``` + +### Step 7: Generate the docs! + +Out of the apps folder run the following command to build the docs for this crate and to view your written documentation! + +```shell +cargo doc ``` \ No newline at end of file From 38c963e8b0ba6e663cd05887c3d6786bc564f95d Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Fri, 10 Mar 2023 17:13:28 +0100 Subject: [PATCH 19/47] clarifications after test --- down-the-stack/apps/src/bin/button.rs | 6 ++++-- down-the-stack/apps/src/bin/uarte_print.rs | 2 ++ down-the-stack/apps/src/lib.rs | 2 +- embedded-workshop-book/src/bsc-exercise.md | 4 ++-- embedded-workshop-book/src/button-implementation.md | 4 ++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/down-the-stack/apps/src/bin/button.rs b/down-the-stack/apps/src/bin/button.rs index 7b6f2d3..3195c8d 100644 --- a/down-the-stack/apps/src/bin/button.rs +++ b/down-the-stack/apps/src/bin/button.rs @@ -1,12 +1,14 @@ #![no_main] #![no_std] -use cortex_m::asm; + use cortex_m_rt::entry; -use core::fmt::Write; + // this imports `down-the-stack/apps/lib.rs` to retrieve our global logger + panicking-behavior use apps as _; +// ⚠️ ⚠️ ⚠️ Don't change this file! ⚠️ ⚠️ ⚠️ + #[entry] fn main() -> ! { // to enable more verbose logs, go to your `Cargo.toml` and set defmt logging levels diff --git a/down-the-stack/apps/src/bin/uarte_print.rs b/down-the-stack/apps/src/bin/uarte_print.rs index 5e434d8..2df9c96 100644 --- a/down-the-stack/apps/src/bin/uarte_print.rs +++ b/down-the-stack/apps/src/bin/uarte_print.rs @@ -8,6 +8,8 @@ use core::fmt::Write; // this imports `down-the-stack/apps/lib.rs` to retrieve our global logger + panicking-behavior use apps as _; +// ⚠️ ⚠️ ⚠️ Don't change this file! ⚠️ ⚠️ ⚠️ + #[entry] fn main() -> ! { // to enable more verbose logs, go to your `Cargo.toml` and set defmt logging levels diff --git a/down-the-stack/apps/src/lib.rs b/down-the-stack/apps/src/lib.rs index 3446a8d..911961c 100644 --- a/down-the-stack/apps/src/lib.rs +++ b/down-the-stack/apps/src/lib.rs @@ -1,5 +1,5 @@ #![no_std] - +// ⚠️ ⚠️ ⚠️ Don't change this file! ⚠️ ⚠️ ⚠️ use panic_probe as _; // same panicking *behavior* as `panic-probe` but doesn't print a panic message diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index a5545fd..6441ff1 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -2,7 +2,7 @@ In this exercise you will learn how to write a board support crate by implementing buttons and the UARTE peripheral. -The template `down-the-stack/dk_bsc/src/lib.rs` already contains the LED and Timer implementations. +The template `down-the-stack/dk_bsc/src/lib.rs` already contains the LED and Timer implementations. Add your code to the designated lines. You'll find a //todo! there. You can test after each step by running the following command out of `down-the-stack/apps` ``` @@ -10,7 +10,7 @@ cargo run --bin hello ``` This program will not call any of the functions you are implementing, so it does not matter if they are incomplete. It will refuse to build if there are errors present in the `lib.rs`! -`down-the-stack/dk_bsc/src/lib_solution.rs` contains the full solution code. +`down-the-stack/dk_bsc/src/lib_solution.rs` contains the full solution code. Note for trainer: Introduction to the exercise is a guided tour through the template, and it's architecture. Make the participants aware of the placeholders for their implementations. run the hello example on the unmodified lib. diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index afc4064..9fddb63 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -38,8 +38,8 @@ Building this code brings up warnings about unused variables. ### Step 5: Add everything to the board struct. -In the definition of the board struct add a field for the `struct Buttons` -In the pub `fn init()` function. Add the button field to the instantiation of the Board struct, assigning the pins you defined earlier to the respective buttons. +In the definition of the `struct Board` add a field for the `struct Buttons`. +In the pub `fn init()` function, where `Board` is instantiated, add the button field, assigning the pins you defined earlier to the respective buttons. From 3b72b1b5304a7b9fa7cd5afb4f1e970de5f70ced Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Mon, 13 Mar 2023 13:29:44 +0100 Subject: [PATCH 20/47] address issues from testing --- .../src/uarte-implementation.md | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 5885c05..8874d5c 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -8,7 +8,7 @@ The UART protocol requires four pins, they are usually labelled: * TXD * CTS * RTS - + Check the User Guide in section 7.2 to find to find out which pins are reserved for these and what their configuration needs to be. ### Step 2: Explore the `nrf-hal` to find out what needs to be done. @@ -24,7 +24,7 @@ A quick search of the document reveals where to find all of them: * `Parity` and `Baudrate`: Re-export on line 34 Add the following lines as import: -```rust +``` use hal::pac::uarte0::{ baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; use hal::uarte; @@ -36,8 +36,11 @@ The struct has one field labelled `inner`, it contains the `UARTE1` instance: `h ### Step 4: Bring up the peripheral in the `fn init()` -Take a closer look at the definition of the `uarte::Pins` struct. Import the types of the pin configuration that you don't have yet. Note, that the third and fourth pin are each wrapped in an `Option`. +Take a closer look at the definition of the `uarte::Pins` struct in the `nrf-hal`. Compare the pin type configurations with the ones you have already imported in `lib.rs`. Add the ones you're missing. + Create an instance of this struct in `fn init()` with the appropriate pins and configurations. Set the output pin's level to `Level::High`. +Note, that the third and fourth pin are each wrapped in an `Option`. + Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)` that you bind to a variable. This instantiating method takes four arguments: * The `UARTE1` instance can be found in the `periph` variable. @@ -54,7 +57,9 @@ add the field to the instance of the `Board` struct in `fn init()`. ### Step 6: Implementing the `fmt::Write` trait -We can't just write to the Uarte instance. A simple write would write from flash memory. This does not work because of EasyDMA. We have to write a function that implements the `fmt::Write` trait. This trait guarantees that the buffer is fully and successfully written on a stack allocated buffer, before it returns. +We can't just write to the `Uarte` instance. A simple write would write from flash memory. This does not work because of EasyDMA. We have to write a function that implements the `fmt::Write` trait. This trait guarantees that the buffer is fully and successfully written on a stack allocated buffer, before it returns. + +Add `use::core::fmt;` to your imports. Create a public method `write_str`. It takes a mutable reference to self and a `&str` as argument. It returns an `fmt::Result` @@ -76,7 +81,7 @@ return `Ok(())` Use the following command to find the address of the nRF52840-DK on your computer. ``` -ls /dev/tty* +ls /dev/tty.usbmodem* ``` Run the following command to run `screen` with the nRF52840-DK with 115200 baud. @@ -94,4 +99,6 @@ Use the following command. cargo run --bin uarte_print ``` -On your terminal window where `screen` runs, "Hello, World" should appear. \ No newline at end of file +On your terminal window where `screen` runs, "Hello, World" should appear. + +You need to terminate `screen` manually. \ No newline at end of file From 9a354f2c29e1cce1890db4c7457081413497ad8b Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 14 Mar 2023 19:39:50 +0100 Subject: [PATCH 21/47] last formatting and adding code snippets --- embedded-workshop-book/src/bsc-exercise.md | 56 ++++---- .../src/button-implementation.md | 122 ++++++++++++++--- .../src/uarte-implementation.md | 129 ++++++++++++++---- 3 files changed, 233 insertions(+), 74 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index 6441ff1..7182165 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -19,54 +19,48 @@ Note for trainer: Introduction to the exercise is a guided tour through the temp * modify the `init()` function that brings up the board's peripherals * how to configure pins * how to write a function that checks the state of a pin -* write methods for a `struct` -* UARTE implementation +* implement functionality on a type * implement a Trait * to document and generate docs for your own library! ## Prerequisites -[todo!] +* `impl` keyword +* methods and associated functions +* `pub` keyword +* usage of structs to represent registers +* Trait ## Tasks -* Write a button implementation. This entails the following steps: - ✅ Add `struct Buttons` with 4 fields, that represents each of the four buttons. - ✅ Add `struct Button` that is a wrapper for the pin that a single button is connected to. - ✅ Write a method `is_pushed` that checks if a single button is pushed. - ✅ Initialize the pins in `fn init()`. - ✅ Add the `struct Button` to the definition and instantiation of `struct Board`. - ✅ Run `apps/buttons.rs` to test. - ✅ Run `cargo doc` out of the apps folder to find all your doc comments! -* Write a UARTE implementation. This entails the following steps: - ✅ Check the `uarte` module of the `nrf-hal` for requirements of the instantiating method. - ✅ Add `struct Uarte` that serves as wrapper for the `UARTE1` instance. - ✅ Initialize the UARTE1 peripheral in `fn init()` using the following settings: +### Write a button implementation. This entails the following steps: +* Add `struct Buttons` with 4 fields, that represents each of the four buttons. +* Add `struct Button` that is a wrapper for the pin that a single button is connected to. +* Write a method `is_pushed` that checks if a single button is pushed. +* Initialize the pins in `fn init()`. +* Add the `struct Button` to the definition and instantiation of `struct Board`. +* Run `apps/buttons.rs` to test. +* Run `cargo doc` out of the apps folder to find all your doc comments! +### Write a UARTE implementation. This entails the following steps: +* Check the `uarte` module of the `nrf-hal` for requirements of the instantiating method. +* Add `struct Uarte` that serves as wrapper for the `UARTE1` instance. +* Initialize the UARTE1 peripheral in `fn init()` using the following settings: * parity: included * baudrate: 115200 baud - ✅ Add `struct Uarte` to the definition and instantiation of `struct Board`. - ✅ Implement the `fmt::Write` trait for `struct Uarte`. - ✅ Connect your computer to the virtual UART port with `screen` - ✅ Run `apps/uarte_print.rs` to test. +* Add `struct Uarte` to the definition and instantiation of `struct Board`. +* Implement the `fmt::Write` trait for `struct Uarte`. +* Connect your computer to the virtual UART port with `screen`. +* Run `apps/uarte_print.rs` to test. ## Knowledge -## Representation of Peripherals -The boards peripherals are represented as nested structs. The `struct Board` contains fields that represent single peripherals or groups of peripherals as structs, which in turn either contain a field of the single peripheral or ... - -You have to add structs to represent the buttons and the UARTE peripheral to the board struct. -[todo!] - -## Comments +### Comments The `lib.rs` has an attribute #![deny(missing_docs)]. This means, that missing doc comments for structs are returned as compiler errors, to remind you to document your work properly. ```rust /// This is a doc comment // This is a normal comment ``` +### Structs represent Registers -## impl blocks -[todo!] -## Visibility of structs, fields and functions: the pub keyword -[todo!] - +[todo!] insert refresher from rust fundamentals ## Hardware documentation for pin configuration Go to [Nordic Infocenter](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/intro.html) to download the User Guide. You can find all the information that is relevant to this exercise in there. diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index 9fddb63..13810b7 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -2,52 +2,138 @@ ## Step-by-Step Solution ### Step 1: Read the docs! - -Go to [Nordic Infocenter](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/intro.html) to download the User Guide. Read docs, section 8.7 for info about pins and pin configuration related to the buttons. Note down the pins that the buttons are connected to. + +✅ Go to [Nordic Infocenter](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/intro.html) to download the **User Guide**. + +✅ Read docs, section 8.7 for info about pins and pin configuration related to the buttons. Note down the pins that the buttons are connected to. + The pins need to be configured as input pins with an internal pull-up. The pins as well as the configurations are defined as types in the `nrf-hal` in the `gpio` peripheral. Add the following imports: `Input` and `PullUp`. ### Step 2: Add the structs that represent the buttons as a group and a generic single button. -Add the struct that represents the single button. It has only one field, `inner`. The type of this button is the pin configuration: `Pin>` +✅ Add the struct that represents the single button. It has only one field, `inner`. The type of this button is the pin configuration: `Pin>` -Add the `struct` that represents the group of buttons has four fields, one for each button. The field name contains the number that corresponds to the button numeration on the board. The of type of each field is the struct that represents the generic single button. +✅ Add the `struct` that represents the group of buttons has four fields, one for each button. The field name contains the number that corresponds to the button numeration on the board. The of type of each field is the struct that represents the generic single button. -Add doc comments for every struct and field! +✅ Add doc comments for every struct and field! Building this code should return a warning: field `inner` is never read. - +
+ Solution + +```rust +/// All buttons on the board +pub struct Buttons { + /// BUTTON1: pin P0.11, green LED + pub b_1: Button, + /// BUTTON2: pin P0.12, green LED + pub b_2: Button, + /// BUTTON3: pin P0.24, green LED + pub b_3: Button, + /// BUTTON4: pin P0.25, green LED + pub b_4: Button, +} + +/// A single button +pub struct Button { + inner: Pin>, +} +``` +
### Step 3: Implement the button function. -Add an `impl` block for the `struct Button`. Add a method `is_pushed` that takes in the struct as `&self` and returns a bool, if the button is pushed. +✅ Add an `impl` block for the `struct Button`. Add a method `is_pushed` that takes in the struct as `&self` and returns a bool, if the button is pushed. -Now remember, the pins the buttons are connected to are configured as active low. For buttons this means, that the pin is pulled low, when the button is pushed. +✅ Now remember, the pins the buttons are connected to are configured as active low. For buttons this means, that the pin is pulled low, when the button is pushed. -In the `nrf-hal` you can find a method to check if a single pin is low. To use it, you have to add the following line to your `nrf52840_hal` imports: `prelude::InputPin`. +✅ In the `nrf-hal` you can find a method to check if a single pin is low. To use it, you have to add the following line to your `nrf52840_hal` imports: `prelude::InputPin`. - +
+ Solution + +```rust +impl Button { + /// returns true if button is pushed + pub fn is_pushed(&self) -> bool { + self.inner.is_low() == Ok(true) + } +} +``` +
### Step 4: Bring up the pins! -Go to `pub fn init()`, the function that initializes the board's peripherals. Get your notes for the pin numbers that are reserver for the buttons. Configure each pin as degraded, pull-up input pin and bind it to a variable that makes it clear what button number it is connected to. +✅ Go to `pub fn init()`, the function that initializes the board's peripherals. + +✅ Configure each pin as degraded, pull-up input pin and bind it to a variable that makes it clear what button number it is connected to. Building this code brings up warnings about unused variables. - + +
+ Solution + +```rust +// Buttons +let b_1 = pins.p0_11.degrade().into_pullup_input(); +let b_2 = pins.p0_12.degrade().into_pullup_input(); +let b_3 = pins.p0_24.degrade().into_pullup_input(); +let b_4 = pins.p0_25.degrade().into_pullup_input(); +``` +
### Step 5: Add everything to the board struct. -In the definition of the `struct Board` add a field for the `struct Buttons`. -In the pub `fn init()` function, where `Board` is instantiated, add the button field, assigning the pins you defined earlier to the respective buttons. +✅ In the definition of the `struct Board` add a field for the `struct Buttons`. - +✅ In the pub `fn init()` function, where `Board` is instantiated, add the button field, assigning the pins you defined earlier to the respective buttons. + +
+ Solution + +```rust +/// Components on the board +pub struct Board { + /// LEDs + pub leds: Leds, + /// Buttons + pub buttons: Buttons, + /// Timer + pub timer: Timer, +} + +// ... + +pub fn init() -> Result { + // ... + Ok(Board { + leds: Leds { + // ... + }, + buttons: Buttons { + b_1: Button { inner: b_1}, + b_2: Button { inner: b_2}, + b_3: Button { inner: b_3}, + b_4: Button { inner: b_4}, + }, + timer: Timer { inner: timer }, + }) + } else { + Err(()) + } + +} + +``` +
### Step 6: Run the example! -Go to `/down-the-stack/apps` +✅ Go to `/down-the-stack/apps`. -Run the following command: +✅ Run the following command: ```shell cargo run --bin button @@ -55,7 +141,7 @@ cargo run --bin button ### Step 7: Generate the docs! -Out of the apps folder run the following command to build the docs for this crate and to view your written documentation! +✅ Out of the apps folder run the following command to build the docs for this crate and to view your written documentation! ```shell cargo doc diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 8874d5c..80a8b87 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -9,7 +9,7 @@ The UART protocol requires four pins, they are usually labelled: * CTS * RTS -Check the User Guide in section 7.2 to find to find out which pins are reserved for these and what their configuration needs to be. +✅ Check the User Guide in section 7.2 to find to find out which pins are reserved for these and what their configuration needs to be. ### Step 2: Explore the `nrf-hal` to find out what needs to be done. @@ -23,68 +23,148 @@ A quick search of the document reveals where to find all of them: * `Pins`: Line 463 * `Parity` and `Baudrate`: Re-export on line 34 -Add the following lines as import: +✅ Add the following lines as import: ``` use hal::pac::uarte0::{ baudrate::BAUDRATE_A as Baudrate, config::PARITY_A as Parity}; use hal::uarte; ``` -### Step 3: Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. +### Step 3: Add `struct Uarte +✅ Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. The struct has one field labelled `inner`, it contains the `UARTE1` instance: `hal::Uarte`. - + +
+ Solution + +```rust +pub struct Uarte { + inner: hal::Uarte, +} +``` +
+ ### Step 4: Bring up the peripheral in the `fn init()` -Take a closer look at the definition of the `uarte::Pins` struct in the `nrf-hal`. Compare the pin type configurations with the ones you have already imported in `lib.rs`. Add the ones you're missing. +✅ Take a closer look at the definition of the `uarte::Pins` struct in the `nrf-hal`. Compare the pin type configurations with the ones you have already imported in `lib.rs`. Add the ones you're missing. -Create an instance of this struct in `fn init()` with the appropriate pins and configurations. Set the output pin's level to `Level::High`. +✅ Create an instance of this struct in `fn init()` with the appropriate pins and configurations. Set the output pin's level to `Level::High`. Note, that the third and fourth pin are each wrapped in an `Option`. - -Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)` that you bind to a variable. This instantiating method takes four arguments: +✅ Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)` that you bind to a variable. This instantiating method takes four arguments: * The `UARTE1` instance can be found in the `periph` variable. * Your instance of the `uarte::Pins` struct. * Set parity to `Parity::INCLUDED` * set the baud rate to `Baudrate::BAUD115200`. - - +
+ Solution + +```rust + let pins = hal::uarte::Pins { + rxd: pins.p0_08.degrade().into_floating_input(), + txd: pins.p0_06.degrade().into_push_pull_output(Level::High), + cts: Some(pins.p0_07.degrade().into_floating_input()), + rts: Some(pins.p0_05.degrade().into_push_pull_output(Level::High)), + }; + + + let uarte = hal::uarte::Uarte::new(periph.UARTE1, pins, Parity::INCLUDED, Baudrate::BAUD115200); +``` +
+ ### Step 5: Board struct -Add a field for the `Uarte` struct in the `Board` struct. +✅ Add a field for the `Uarte` struct in the `Board` struct. add the field to the instance of the `Board` struct in `fn init()`. - + +
+ Solution + +```rust + +pub struct Board { + /// LEDs + pub leds: Leds, + /// Buttons + pub buttons: Buttons, + /// Timer + pub timer: Timer, + /// uarte interface + pub uarte: Uarte, +} + +// ... + +pub fn init() -> Result { + + // ... + + Ok(Board { + leds: Leds { + // ... + }, + + buttons: Buttons { + // ... + }, + // 🔼 --- Exercise Button --- 🔼 + + timer: Timer { inner: timer }, + + uarte: Uarte { inner: uarte }, + }) + } else { + Err(()) + } +``` + +
+ ### Step 6: Implementing the `fmt::Write` trait We can't just write to the `Uarte` instance. A simple write would write from flash memory. This does not work because of EasyDMA. We have to write a function that implements the `fmt::Write` trait. This trait guarantees that the buffer is fully and successfully written on a stack allocated buffer, before it returns. -Add `use::core::fmt;` to your imports. +✅ Add `use::core::fmt;` to your imports. -Create a public method `write_str`. It takes a mutable reference to self and a `&str` as argument. It returns an `fmt::Result` +✅ Create a public method `write_str`. It takes a mutable reference to self and a `&str` as argument. It returns an `fmt::Result` -Create a buffer. The type is an `array` of 16 u8, set to all 0. +✅ Create a buffer. The type is an `array` of 16 u8, set to all 0. -To copy all data into an on-stack buffer, iterate over every chunk of the string to copy it into the buffer: +✅ To copy all data into an on-stack buffer, iterate over every chunk of the string to copy it into the buffer: + +
+ Solution ```rust -for block in string.as_bytes().chunks(16) { - buf[..block.len()].copy_from_slice(block); - self.inner.write(&buf[..block.len()]).map_err(|_| fmt::Error)?; +impl fmt::Write for Uarte { + + fn write_str(&mut self, s: &str) -> fmt::Result { + // Copy all data into an on-stack buffer so we never try to EasyDMA from + // flash. + let mut buf: [u8; 16] = [0; 16]; + for block in s.as_bytes().chunks(16) { + buf[..block.len()].copy_from_slice(block); + self.inner.write(&buf[..block.len()]).map_err(|_| fmt::Error)?; + } + + Ok(()) + } } ``` -return `Ok(())` +
### Step 7: Connect your computer to the virtual UART -[directions for mac present, linux and windows are missing.] +[todo!] [directions for mac present, linux and windows are missing.] -Use the following command to find the address of the nRF52840-DK on your computer. +✅ Use the following command to find the address of the nRF52840-DK on your computer. ``` ls /dev/tty.usbmodem* ``` -Run the following command to run `screen` with the nRF52840-DK with 115200 baud. +✅ Run the following command to run `screen` with the nRF52840-DK with 115200 baud. ``` screen
115200 @@ -92,9 +172,8 @@ screen
115200 ### Step 7: Run the example. -In another terminal window go into the folder `down-the-stack/apps`. +✅ In another terminal window go into the folder `down-the-stack/apps` and use the following command. -Use the following command. ``` cargo run --bin uarte_print ``` From 30fe3504438b6c1b42e826d652bd6cf9c36ae63f Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Fri, 17 Mar 2023 19:31:07 +0100 Subject: [PATCH 22/47] polish --- embedded-workshop-book/src/bsc-exercise.md | 6 +++--- embedded-workshop-book/src/button-implementation.md | 2 +- embedded-workshop-book/src/down-the-stack.md | 10 ++++++++++ embedded-workshop-book/src/uarte-implementation.md | 6 +++--- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index 7182165..c18d59a 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -2,7 +2,7 @@ In this exercise you will learn how to write a board support crate by implementing buttons and the UARTE peripheral. -The template `down-the-stack/dk_bsc/src/lib.rs` already contains the LED and Timer implementations. Add your code to the designated lines. You'll find a //todo! there. +The template `down-the-stack/dk_bsc/src/lib.rs` already contains the LED and Timer implementations. Add your code to the designated lines. You'll find a `//todo!` there. You can test after each step by running the following command out of `down-the-stack/apps` ``` @@ -12,7 +12,7 @@ This program will not call any of the functions you are implementing, so it does `down-the-stack/dk_bsc/src/lib_solution.rs` contains the full solution code. -Note for trainer: Introduction to the exercise is a guided tour through the template, and it's architecture. Make the participants aware of the placeholders for their implementations. run the hello example on the unmodified lib. + ## You will learn how to @@ -52,7 +52,7 @@ Note for trainer: Introduction to the exercise is a guided tour through the temp ## Knowledge ### Comments -The `lib.rs` has an attribute #![deny(missing_docs)]. This means, that missing doc comments for structs are returned as compiler errors, to remind you to document your work properly. +The `lib.rs` has an attribute `#![deny(missing_docs)]`. This means, that missing doc comments for structs are returned as compiler errors, to remind you to document your work properly. ```rust /// This is a doc comment diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index 13810b7..469ceae 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -13,7 +13,7 @@ The pins need to be configured as input pins with an internal pull-up. The pins ✅ Add the struct that represents the single button. It has only one field, `inner`. The type of this button is the pin configuration: `Pin>` -✅ Add the `struct` that represents the group of buttons has four fields, one for each button. The field name contains the number that corresponds to the button numeration on the board. The of type of each field is the struct that represents the generic single button. +✅ Add the `struct` that represents the group of buttons has four fields, one for each button. The field name contains the number that corresponds to the button numeration on the board. The type of each field is the struct that represents the generic single button. ✅ Add doc comments for every struct and field! diff --git a/embedded-workshop-book/src/down-the-stack.md b/embedded-workshop-book/src/down-the-stack.md index e69de29..88284e9 100644 --- a/embedded-workshop-book/src/down-the-stack.md +++ b/embedded-workshop-book/src/down-the-stack.md @@ -0,0 +1,10 @@ +# Down the Stack + +In this Session you will learn more about Rust's split crate model that includes +* the Board Support Crate +* an implementation of the Hardware Abstraction Layer +* the Peripheral Access Crate + +This session consists of lectures and two blocks of exercises: +* BSC Exercise: Implementing further features in a basic BSC +* PAC Exercise: Generating a PAC from an SVD file and writing into registers using the the generated PAC. \ No newline at end of file diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 80a8b87..b2c305e 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -30,7 +30,7 @@ use hal::pac::uarte0::{ use hal::uarte; ``` -### Step 3: Add `struct Uarte +### Step 3: Add `struct Uarte` ✅ Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. The struct has one field labelled `inner`, it contains the `UARTE1` instance: `hal::Uarte`. @@ -132,7 +132,7 @@ We can't just write to the `Uarte` instance. A simple write would write from fla ✅ Create a buffer. The type is an `array` of 16 u8, set to all 0. -✅ To copy all data into an on-stack buffer, iterate over every chunk of the string to copy it into the buffer: +✅ To copy all data into an on-stack buffer, iterate over every chunk of the string to copy it into the buffer.
Solution @@ -170,7 +170,7 @@ ls /dev/tty.usbmodem* screen
115200 ``` -### Step 7: Run the example. +### Step 8: Run the example. ✅ In another terminal window go into the folder `down-the-stack/apps` and use the following command. From bfcb572bc16e73aa54e259a19d23ea1bfa45800d Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:34:58 +0100 Subject: [PATCH 23/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 407b5b9..7274d8d 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -30,7 +30,7 @@ use defmt_rtt as _; // global logger pub struct Board { /// LEDs pub leds: Leds, - // 🔽 --- Exercise Button --- 🔽 + // 🔽 --- Button Exercise --- 🔽 /// Buttons pub buttons: Buttons, // 🔼 --- Exercise Button --- 🔼 From ab2d9081bdb7cb2b1a88b3c6162396751d2eb628 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:35:14 +0100 Subject: [PATCH 24/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 7274d8d..a81936d 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -33,7 +33,7 @@ pub struct Board { // 🔽 --- Button Exercise --- 🔽 /// Buttons pub buttons: Buttons, - // 🔼 --- Exercise Button --- 🔼 + // 🔼 --- Button Exercise --- 🔼 /// Timer pub timer: Timer, // 🔽 --- Exercise UARTE --- 🔽 From 5f079cdd88c9c19365177b02944148cbd3ebd90f Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:35:28 +0100 Subject: [PATCH 25/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index a81936d..72f6099 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -36,7 +36,7 @@ pub struct Board { // 🔼 --- Button Exercise --- 🔼 /// Timer pub timer: Timer, - // 🔽 --- Exercise UARTE --- 🔽 + // 🔽 --- UARTE Exercise --- 🔽 /// uarte interface pub uarte: Uarte, // 🔼 --- Exercise UARTE --- 🔼 From 2505e00e3289033112846b7485912b3d605eeb5a Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:35:43 +0100 Subject: [PATCH 26/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 72f6099..de04000 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -39,7 +39,7 @@ pub struct Board { // 🔽 --- UARTE Exercise --- 🔽 /// uarte interface pub uarte: Uarte, - // 🔼 --- Exercise UARTE --- 🔼 + // 🔼 --- UARTE Exercise --- 🔼 } /// All LEDs on the board From e7eef7aff9441ee131fbd8cb638c56193ba3c9cb Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:36:12 +0100 Subject: [PATCH 27/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index de04000..b1db6a8 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -103,7 +103,7 @@ impl Led { } } } -// 🔽 --- Exercise Button --- 🔽 +// 🔽 --- Button Exercise --- 🔽 /// All buttons on the board pub struct Buttons { /// BUTTON1: pin P0.11, green LED From f0bf2ec6c3672201e3bfd8cd7620aa8addd0fd07 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:36:25 +0100 Subject: [PATCH 28/47] Update embedded-workshop-book/src/uarte-implementation.md Co-authored-by: Jonathan Pallant --- embedded-workshop-book/src/uarte-implementation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index b2c305e..66ece96 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -109,7 +109,7 @@ pub fn init() -> Result { buttons: Buttons { // ... }, - // 🔼 --- Exercise Button --- 🔼 + // 🔼 --- Button Exercise --- 🔼 timer: Timer { inner: timer }, From 5fc64c53a26c602048ebf683a4c2ccedee2cdac6 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:37:28 +0100 Subject: [PATCH 29/47] Update embedded-workshop-book/src/uarte-implementation.md Co-authored-by: Jonathan Pallant --- embedded-workshop-book/src/uarte-implementation.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 66ece96..5ba4475 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -124,7 +124,11 @@ pub fn init() -> Result { ### Step 6: Implementing the `fmt::Write` trait -We can't just write to the `Uarte` instance. A simple write would write from flash memory. This does not work because of EasyDMA. We have to write a function that implements the `fmt::Write` trait. This trait guarantees that the buffer is fully and successfully written on a stack allocated buffer, before it returns. +We want to implement the `fmt::Write` trait so that users can call `write!` on our Uarte object + +When implementing this, we can't just write to the `Uarte` instance because a simple write of a string literal would try and read the string literal from flash memory. This does not work because the EasyDMA peripheral in the nRF52 series can only access RAM, not flash. + +Instead our implementation must ensure all the strings are copied to a stack allocated buffer and that buffer is passed to the Uarte's `write` method. ✅ Add `use::core::fmt;` to your imports. From b5c3480d25f5c01945a838dcad7fb37626c182b9 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:37:53 +0100 Subject: [PATCH 30/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index b1db6a8..c181fee 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -127,7 +127,7 @@ impl Button { self.inner.is_low() == Ok(true) } } -// 🔼 --- Exercise Button --- 🔼 +// 🔼 --- Button Exercise --- 🔼 /// A timer for creating blocking delays pub struct Timer { From a3f653de2310ab382feb620b431a6be764a1199d Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:38:15 +0100 Subject: [PATCH 31/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index c181fee..ff43568 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -184,7 +184,7 @@ impl ops::DerefMut for Timer { } } -// 🔽 --- Exercise UARTE --- 🔽 +// 🔽 --- UARTE Exercise --- 🔽 /// Uarte peripheral pub struct Uarte { inner: hal::Uarte, From 89ee72eb493fb60b99c452d3ef32559b8858b509 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:38:46 +0100 Subject: [PATCH 32/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index ff43568..aea1eb6 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -204,7 +204,7 @@ impl fmt::Write for Uarte { Ok(()) } } -// 🔼 --- Exercise UARTE --- 🔼 +// 🔼 --- UARTE Exercise --- 🔼 /// Initializes the board /// From 274767bc51d444c68c694c224f6f3c460e032e4c Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:39:09 +0100 Subject: [PATCH 33/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index aea1eb6..e9ef633 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -220,7 +220,7 @@ pub fn init() -> Result { let led_3 = pins.p0_15.degrade().into_push_pull_output(Level::High); let led_4 = pins.p0_16.degrade().into_push_pull_output(Level::High); - // 🔽 --- Exercise Button --- 🔽 + // 🔽 --- Button Exercise --- 🔽 // Buttons let b_1 = pins.p0_11.degrade().into_pullup_input(); let b_2 = pins.p0_12.degrade().into_pullup_input(); From d6470363d475faa453ed18ab608055c13c936891 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:39:46 +0100 Subject: [PATCH 34/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index e9ef633..2a4d16d 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -226,7 +226,7 @@ pub fn init() -> Result { let b_2 = pins.p0_12.degrade().into_pullup_input(); let b_3 = pins.p0_24.degrade().into_pullup_input(); let b_4 = pins.p0_25.degrade().into_pullup_input(); - // 🔼 --- Exercise Button --- 🔼 + // 🔼 --- Button Exercise --- 🔼 defmt::debug!("I/O pins have been configured for digital output"); From dc9232f25e9b83752991a790d3e0263c6be082f2 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:40:11 +0100 Subject: [PATCH 35/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 2a4d16d..360c5d3 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -232,7 +232,7 @@ pub fn init() -> Result { let timer = hal::Timer::new(periph.TIMER0); - // 🔽 --- Exercise UARTE --- 🔽 + // 🔽 --- UARTE Exercise --- 🔽 // Uarte let pins = hal::uarte::Pins { rxd: pins.p0_08.degrade().into_floating_input(), From 81b665770363394fc4243fa0675d007c9d051b59 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:40:40 +0100 Subject: [PATCH 36/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 360c5d3..47739d9 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -243,7 +243,7 @@ pub fn init() -> Result { let uarte = hal::uarte::Uarte::new(periph.UARTE1, pins, Parity::INCLUDED, Baudrate::BAUD115200); - // 🔼 --- Exercise UARTE --- 🔼 + // 🔼 --- UARTE Exercise --- 🔼 Ok(Board { leds: Leds { From 4fb74152945edf8b205c9b9828ac86b9b68d2411 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:41:08 +0100 Subject: [PATCH 37/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 47739d9..0f574fb 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -260,7 +260,7 @@ pub fn init() -> Result { b_3: Button { inner: b_3}, b_4: Button { inner: b_4}, }, - // 🔼 --- Exercise Button --- 🔼 + // 🔼 --- Button Exercise --- 🔼 timer: Timer { inner: timer }, From 8de826d0bc41ce40cc7b2feb9c0211a59b7f45dd Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:41:28 +0100 Subject: [PATCH 38/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 0f574fb..2929700 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -253,7 +253,7 @@ pub fn init() -> Result { led_4: Led { inner: led_4 }, }, - // 🔽 --- Exercise Button --- 🔽 + // 🔽 --- Button Exercise --- 🔽 buttons: Buttons { b_1: Button { inner: b_1}, b_2: Button { inner: b_2}, From 1db5935bbb0b2ef7d2733237e22aae4813756f4b Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:41:47 +0100 Subject: [PATCH 39/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 2929700..131e7bf 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -264,7 +264,7 @@ pub fn init() -> Result { timer: Timer { inner: timer }, - // 🔽 --- Exercise UARTE --- 🔽 + // 🔽 --- UARTE Exercise --- 🔽 uarte: Uarte { inner: uarte }, // 🔼 --- Exercise UARTE --- 🔼 }) From 08654a53daf6dcf7bb92791b8ecd8b5669d13eaf Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:42:19 +0100 Subject: [PATCH 40/47] Update down-the-stack/dk_bsc/src/lib_solution.rs Co-authored-by: Jonathan Pallant --- down-the-stack/dk_bsc/src/lib_solution.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 131e7bf..8bd5576 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -266,7 +266,7 @@ pub fn init() -> Result { // 🔽 --- UARTE Exercise --- 🔽 uarte: Uarte { inner: uarte }, - // 🔼 --- Exercise UARTE --- 🔼 + // 🔼 --- UARTE Exercise --- 🔼 }) } else { Err(()) From ee29b74c7f915d0bad6970b6a509cab37c252708 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:42:51 +0100 Subject: [PATCH 41/47] Update embedded-workshop-book/src/bsc-exercise.md Co-authored-by: Jonathan Pallant --- embedded-workshop-book/src/bsc-exercise.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embedded-workshop-book/src/bsc-exercise.md b/embedded-workshop-book/src/bsc-exercise.md index c18d59a..43957d2 100644 --- a/embedded-workshop-book/src/bsc-exercise.md +++ b/embedded-workshop-book/src/bsc-exercise.md @@ -1,6 +1,6 @@ # BSC Exercise -In this exercise you will learn how to write a board support crate by implementing buttons and the UARTE peripheral. +In this exercise you will learn how to write a *Board Support Crate* (or BSC, also known as a *Board Support Package*) by implementing support for handling button presses, and support for using the UARTE peripheral. The template `down-the-stack/dk_bsc/src/lib.rs` already contains the LED and Timer implementations. Add your code to the designated lines. You'll find a `//todo!` there. From f981189222f5609e67e6e14c8f2ff09e039248fe Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 14:43:38 +0100 Subject: [PATCH 42/47] Update embedded-workshop-book/src/uarte-implementation.md Co-authored-by: Jonathan Pallant --- embedded-workshop-book/src/uarte-implementation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 5ba4475..d198b8c 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -136,7 +136,7 @@ Instead our implementation must ensure all the strings are copied to a stack all ✅ Create a buffer. The type is an `array` of 16 u8, set to all 0. -✅ To copy all data into an on-stack buffer, iterate over every chunk of the string to copy it into the buffer. +✅ To copy all data into an on-stack buffer, *iterate* over *chunks* of the string and copy them into the buffer (noting that the chunk length may be less than the requested size if you are at the end of the input string).
Solution From debd7658b7dbd51c42deb25474d09479cf4fa597 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Mon, 20 Mar 2023 15:17:43 +0100 Subject: [PATCH 43/47] rm led color comment --- down-the-stack/dk_bsc/src/lib_solution.rs | 8 ++++---- embedded-workshop-book/src/button-implementation.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/down-the-stack/dk_bsc/src/lib_solution.rs b/down-the-stack/dk_bsc/src/lib_solution.rs index 8bd5576..9fd2940 100644 --- a/down-the-stack/dk_bsc/src/lib_solution.rs +++ b/down-the-stack/dk_bsc/src/lib_solution.rs @@ -106,13 +106,13 @@ impl Led { // 🔽 --- Button Exercise --- 🔽 /// All buttons on the board pub struct Buttons { - /// BUTTON1: pin P0.11, green LED + /// BUTTON1: pin P0.11 pub b_1: Button, - /// BUTTON2: pin P0.12, green LED + /// BUTTON2: pin P0.12 pub b_2: Button, - /// BUTTON3: pin P0.24, green LED + /// BUTTON3: pin P0.24 pub b_3: Button, - /// BUTTON4: pin P0.25, green LED + /// BUTTON4: pin P0.25 pub b_4: Button, } diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index 469ceae..814aca9 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -25,13 +25,13 @@ Building this code should return a warning: field `inner` is never read. ```rust /// All buttons on the board pub struct Buttons { - /// BUTTON1: pin P0.11, green LED + /// BUTTON1: pin P0.11 pub b_1: Button, - /// BUTTON2: pin P0.12, green LED + /// BUTTON2: pin P0.12 pub b_2: Button, - /// BUTTON3: pin P0.24, green LED + /// BUTTON3: pin P0.24 pub b_3: Button, - /// BUTTON4: pin P0.25, green LED + /// BUTTON4: pin P0.25 pub b_4: Button, } From 7701ae869645ad9d6e70f18f68156f1ff9e82fd3 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 15:19:13 +0100 Subject: [PATCH 44/47] Update embedded-workshop-book/src/uarte-implementation.md Co-authored-by: Jonathan Pallant --- embedded-workshop-book/src/uarte-implementation.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index d198b8c..0c4f31a 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -14,7 +14,7 @@ The UART protocol requires four pins, they are usually labelled: ### Step 2: Explore the `nrf-hal` to find out what needs to be done. -The `nrf52840-hal` is a crate that exports all the `52840` flagged features from the `nrf-hal-common`. Let's take a look at the nRF-Hal [Uarte module](https://github.com/nrf-rs/nrf-hal/blob/v0.14.1/nrf-hal-common/src/uarte.rs). +The `nrf52840-hal` is a crate that exports all the `52840` flagged features from the `nrf-hal-common`. Let's take a look at the `nrf52840-hal`'s [Uarte module](https://github.com/nrf-rs/nrf-hal/blob/v0.14.1/nrf-hal-common/src/uarte.rs). In line 16 we see, that the nRF52840 uses the `hal::pac::UARTE1` peripheral. In line 44 you find the `struct Uarte(T)`, the interface to a UARTE instance `T`. Besides the instance `T`, the instantiating method takes variables of the following types as arguments: `Pins`, `Parity` and `Baudrate`. From 5e5ccb510b6e274dd1d708a04e3970bb58073a8a Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 15:20:19 +0100 Subject: [PATCH 45/47] Update embedded-workshop-book/src/uarte-implementation.md Co-authored-by: Jonathan Pallant --- embedded-workshop-book/src/uarte-implementation.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 0c4f31a..fae6264 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -32,8 +32,11 @@ use hal::uarte; ### Step 3: Add `struct Uarte` -✅ Add `struct Uarte` that serves as a wrapper for the `UARTE1` instance. -The struct has one field labelled `inner`, it contains the `UARTE1` instance: `hal::Uarte`. +✅ Add `struct Uarte` that serves as a wrapper for underlying HAL UART driver. + +The struct has one field labelled `inner` which is of type `hal::Uarte` but with the type parameter `T` being set to `hal::pac::UARTE1`. + +The main difference between using our `Uarte` object and the underlying HAL `Uarte` object is that *ours* will be pre-configured for the correct pins and baud rate, according to the layout of our nRF52840-DK board and the Virtual COM Port interface chip on the other end of the UART link.
Solution From b09dd739f88b48e2594a07d5c95202aeddb2a952 Mon Sep 17 00:00:00 2001 From: Tanks Transfeld Date: Mon, 20 Mar 2023 15:21:07 +0100 Subject: [PATCH 46/47] Update embedded-workshop-book/src/uarte-implementation.md Co-authored-by: Jonathan Pallant --- embedded-workshop-book/src/uarte-implementation.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index fae6264..705d95b 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -55,7 +55,9 @@ pub struct Uarte { ✅ Create an instance of this struct in `fn init()` with the appropriate pins and configurations. Set the output pin's level to `Level::High`. Note, that the third and fourth pin are each wrapped in an `Option`. -✅ Create an interface to the UARTE1 instance with `uarte::Uarte::new(...)` that you bind to a variable. This instantiating method takes four arguments: +✅ Create a Uarte driver with `hal::uarte::Uarte::new(...)` and bind it to a variable called `uarte` - we will stash this in our own `Uarte` struct later. + +Creating the Uarte driver requires four arguments: * The `UARTE1` instance can be found in the `periph` variable. * Your instance of the `uarte::Pins` struct. * Set parity to `Parity::INCLUDED` From ee0f7b1145d8357b82646ca5b06f935cad51afdb Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Mon, 20 Mar 2023 15:48:21 +0100 Subject: [PATCH 47/47] add links to html doc --- embedded-workshop-book/src/button-implementation.md | 4 +--- embedded-workshop-book/src/uarte-implementation.md | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/embedded-workshop-book/src/button-implementation.md b/embedded-workshop-book/src/button-implementation.md index 814aca9..8c0118b 100644 --- a/embedded-workshop-book/src/button-implementation.md +++ b/embedded-workshop-book/src/button-implementation.md @@ -3,9 +3,7 @@ ### Step 1: Read the docs! -✅ Go to [Nordic Infocenter](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/intro.html) to download the **User Guide**. - -✅ Read docs, section 8.7 for info about pins and pin configuration related to the buttons. Note down the pins that the buttons are connected to. +✅ Read the [User Guide section 8.7](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/hw_buttons_leds.html?cp=5_0_4_7_6) for info about pins and pin configuration related to the buttons. Note down the pins that the buttons are connected to. The pins need to be configured as input pins with an internal pull-up. The pins as well as the configurations are defined as types in the `nrf-hal` in the `gpio` peripheral. Add the following imports: `Input` and `PullUp`. diff --git a/embedded-workshop-book/src/uarte-implementation.md b/embedded-workshop-book/src/uarte-implementation.md index 705d95b..b1f3dc7 100644 --- a/embedded-workshop-book/src/uarte-implementation.md +++ b/embedded-workshop-book/src/uarte-implementation.md @@ -9,7 +9,7 @@ The UART protocol requires four pins, they are usually labelled: * CTS * RTS -✅ Check the User Guide in section 7.2 to find to find out which pins are reserved for these and what their configuration needs to be. +✅ Check the [User Guide in section 7.2](https://infocenter.nordicsemi.com/topic/ug_nrf52840_dk/UG/dk/vir_com_port.html) to find to find out which pins are reserved for these and what their configuration needs to be. ### Step 2: Explore the `nrf-hal` to find out what needs to be done.