embedded-trainings-2020/embedded-workshop-book/src/dealing-with-registers.md

23 lines
2.3 KiB
Markdown
Raw Normal View History

2020-07-13 11:48:24 +00:00
# Dealing with Registers
In this and the next section we'll look into RTIC's event handling features. To explore these features we'll use the action of connecting a USB cable to the DK's port J2 as the event we'd like to handle.
2020-07-15 14:28:37 +00:00
✅ Open the `src/bin/events.rs` file.
We'll read the code and explain, what it does.
2020-07-13 11:48:24 +00:00
The example application enables the signaling of this "USB power" event in the `init` function. This is done using the low level register API generated by the [`svd2rust`] tool. The register API was generated from a SVD (System View Description) file, a file that describes all the peripherals and registers, and their memory layout, on a device. In our case the device was the nRF52840; a sample SVD file for this microcontroller can be found [here][nrf52840.svd].
[`svd2rust`]: https://crates.io/crates/svd2rust
[nrf52840.svd]: https://github.com/NordicSemiconductor/nrfx/blob/master/mdk/nrf52840.svd
In the `svd2rust` API, peripherals are represented as structs. The fields of each peripheral struct are the registers associated to that peripheral. Each register field exposes methods to `read` and `write` to the register in a *single* memory operation.
The `read` and `write` methods take closure arguments. These closures in turn grant access to a "constructor" value, usually named `r` or `w`, which provides methods to modify the bitfields of a register. At the same time the API of these "constructors" prevent you from modifying the reserved parts of the register: you cannot write arbitrary values into registers; you can only write valid values into registers.
Apart from the `read` and `write` methods there's a `modify` method that performs a read-modify-write operation on the register; this API is also closure-based. The `svd2rust`-generated API is documented in detail in the `svd2rust` crate starting at [the Peripheral API section][svd2rust-api].
[svd2rust-api]: https://docs.rs/svd2rust/0.17.0/svd2rust/#peripheral-api
In Cortex-M devices interrupt handling needs to be enabled on two sides: on the peripheral side and on the core side. The register operations done in `init` take care of the peripheral side. The core side of the operation involves writing to the registers of the Nested Vector Interrupt Controller (NVIC) peripheral. This second part doesn't need to be done by the user in RTIC applications because the framework takes care of it.