finish draft of uarte implementation

This commit is contained in:
Mirabellensaft 2023-02-27 17:00:21 +01:00
parent 453eb95928
commit a142d1579d

View file

@ -1,13 +1,17 @@
# Write the Uarte implementation # Write the Uarte implementation
## Step-by-Step Solution ## Step-by-Step Solution
1. Check Documentation.
### Check Documentation.
The UART protocol requires four pins, they are usually labelled: 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. 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.
### 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.