This repository is a collection of pairs of programs between nRF52840 DK and STM32F401-Nucleo, sending data with UART (universal asynchronous receiver-transmitter). The nRF52840 DK is the sender and the Nucleo the receiver (reversing messages is left as an exercise to the reader 😛).
The goal of this repository is to provide simple examples on how to sending data between boards, not teaching UART. The nRF52840 uses UARTE, and the Nucleo uses USART, an UART that support synchronous operations as well.
Those boards were chosen because they are cheap and off the shelves (translate: I had them at home). I use STM32F401 Nucleo but any Nucleo for the stm32f4xx family of chips would work (with special caveat: look up pins, more on that in the nucleo section.
The code snipets are in increasing level of difficulty.
- Nucleo D8/PA9 (tx) - nRF52 p1.07 (rx)
- Nucleo D2/PA10 (rx)- nRF52 p1.08 (tx)
- GND - GND
Some programs are interracting, with the nRF52 as the sender and the Nucleo as the receiver. They are of increasing order of difficulty.
Open one terminal window per microcontroller and run:
cargo rb <project name>
For example, to try interracting program #3, you would:
[terminal nrf]
cargo rb uarte
[terminal nucleo]
cargo rb usart
To try interracting program #4, you would:
[terminal nrf]
cargo rb lightning
[terminal nucleo]
cargo rb lightning
Most programs have the same name but I kept "uarte" and "usart" as this is how the protocol is named in nrf52840-hal
and stm32f4xx-hal
respectively.
Interracting? | nRF52/Nucleo code | What does it do? | |
---|---|---|---|
1 | No | minimal_01.rs |
It says hi👋 |
2 | No | blinky_02.rs |
.. blinks a led💡 |
3 | yes | uarte_03.rs/usart_03.rs |
Sending byte beer emoji back and forth: nRF52 says: look at this 🍻 we got back! |
4 | yes | lightning_04.rs |
nRF52 is blinking the led of the nucleo 💡 |
5 | yes | button_05.rs |
nRF52 is blinking the led of the nucleo 💡, but with a button |
5_b | yes | button_05_b.rs |
The Nucleo is toggling the led of the nRF **💡 |
5_c | yes | button_05_c.rs |
The Nucleo is toggling the led of the nRF **💡, with COBS |
5_d | yes | button_05_d.rs |
The Nucleo is toggling the led of the nRF **💡, with COBS, with a blocking buffert |
6 | yes | postcard_06.rs |
nRF52 is blinking the led of the nucleo 💡, with a proper instruction using cobs command. |
7 | yes | pws_07.rs |
nRF52 is dimming(*) the light of the nucleo 🔅💡🔅 |
8 | yes | interval_08.rs |
nRF52 is blinking the light of the nucleo, with intervals. The light can be dimmed 🔅💡🔅. |
*ATM the dimmer function is very bad, and need to be fixed (the incrementation must be based on a function, not magic numbers).
** Special request from Twitter ⭐, to send data from the Nucleo to the nRF52 instead. The Nucleo can turn on the light of the nRF with one byte (0/1, program b), and with COBS (program c and d). The only difference is that in button_05_c
, the sender and receiver send and take one byte at a time. In button_05_d
, the whole buffer is written with a blocking write, and read as a full buffer on arrival.
All projects are written with RTIC, a concurrency framework for Cortex-M devices.
RTIC shines in simplifying concurrency - messages are passed between #[task]
s with different levels of priority, guaranteeing deadlock and datarace free execution, and many other guarantees.
Source:AdaFruit
UART (universal asynchronous receiver-transmitter) is a serial protocol. Others are for example SPI, I2C, USB. UART is asynchronous, i.e. it has no clock but the transmitter and receiver have agreed on a baud rate. Since they are not in sync it becomes difficult to do anything faster than 1MHz!
The advantage is that both sides can initiate a transfer. On the contrary, SPI and I2C initiate a master (controller) and one or more slaves (peripheral devices). Here, only the master can initiate a transfer.
The disadvantage is that it is only point-to-point, i.e. you can not talk to several devices on a common bus as you can with SPI and I2C.
There are some differences with the pin configuration that are noteworthy.
On the Nucleo, you must look up which functionality is available for each pin. According to the Nucleo board manual, you will need to use PA2 and PA3 if you want to use USART2. If the docs recommends to look up the solder bridges, it is a good idea to do so. If solder bridges are open, there is no communication and the project does not work.
In this mini projects, we are using USART1, so according to the datasheet we use PA9 and PA10.
Are we done?
Not at all!
You need to configure alternate functions. On STM32, pins can have different functions so you need to specify which function you are going to use with the alternate functions table:
For USART1, we need alternate function 7 (AF07).
So the configuration will look like this:
#[local]
struct Local {
// leds, etc
usart: usart: Serial<USART1, (PA9<Alternate<PushPull, 7>>, PA10<Alternate<PushPull, 7>>), u8>,
}
On the nRF52840 development board, you can use any pin. Or almost any pins! According to the connector interface, some pins have default settings. Connector P6 and P24 should be avoided, as per the figure.
The first programs communicate with each other by sending 0
s and 1
s, for example to turn the light on and off.
From program #6 I use postcard.rs
, COBS is used to frame instructions in "efficient, reliable, unambiguous" packets, because you don't want to send instructions as a cave woman.
A great crate to do that is postcard-rs.
All programs in this project are done with the Knurling App template. If you want to do your own, follow the steps in the documentation!
I do use default logging level debug. You can change that level in the respective .cargo/config
files.
[env]
DEFMT_LOG="debug"
Licensed under either of
-
Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
-
MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be licensed as above, without any additional terms or conditions.