mirror of
https://github.com/ferrous-systems/embedded-trainings-2020.git
synced 2025-02-04 03:42:20 +00:00
finish draft of uarte implementation
This commit is contained in:
parent
453eb95928
commit
a142d1579d
1 changed files with 51 additions and 10 deletions
|
@ -1,13 +1,17 @@
|
||||||
# Write the Uarte implementation
|
# Write the Uarte implementation
|
||||||
## Step-by-Step Solution
|
## 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
|
* RXD
|
||||||
* TXD
|
* TXD
|
||||||
* CTS
|
* CTS
|
||||||
* RTS
|
* 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).
|
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;
|
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.
|
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`.
|
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?
|
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`.
|
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()`.
|
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.
|
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.
|
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 <adress of mc> 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.
|
Loading…
Reference in a new issue