From 71ad8b0b5a65c66c6381119c7e2e1c37826326d0 Mon Sep 17 00:00:00 2001 From: Mirabellensaft Date: Tue, 7 Mar 2023 17:52:41 +0100 Subject: [PATCH] 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`.