embedded-trainings-2020/embedded-workshop-book/src/dealing-with-registers.md
2020-07-15 16:28:37 +02:00

2.3 KiB

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.

Open the src/bin/events.rs file.

We'll read the code and explain, what it does.

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.

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.

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.