Interrupts are an essential part of every microcontroller and microprocessor. If interrupts didn’t exist, then the CPU will have to keep checking if the data or peripheral it is waiting on is ready for some operation. An interrupt instead notifies the CPU that the specific peripheral has something of use which requires it’s attention.
All ARM Cortex cores have a peripheral called the Nested Vector Interrupt Controller(NVIC).
The NVIC allows a specific number of interrupts to be defined and it also allows the assigning of priorities for these interrupts. The NVIC ensures that a lower priority interrupt cannot preempt a higher priority interrupt. Whereas, if a higher priority interrupt is triggered after a lower priority interrupt, the higher priority interrupt is serviced and then CPU returns to the non interrupt state without completing the execution of the lower priority interrupt.
The project with the code for this tutorial is available on Github at https://github.com/vicara-hq/da14531-tutorials
Download the project and copy it. The project has to be placed inside the Dialog SDK6 folder. Navigate to <SDK6_ROOT>/projects/target_apps/template and paste it in this folder. The project is a modified version of the empty_peripheral_template project provided by Dialog. But to keep this tutorial series as open source as possible, all the following steps will use the SmartSnippets Studio.
We will use a DA145xx Pro motherboard with a DA14531 Tiny module daughterboard with a STEVAL-MKI160V1. The hardware setup is similar to the Dialog DA14531 I2C blog with one addition to the circuit. The STEVAL-MKI160V1 is an evaluation kit for the LSM6DS3, which is a 6-axis IMU. Other than this, we will also need a few jumpers, a breadboard and 2 4.7 kOhm resistors. If you cannot find 4.7 kOhm resistors, you can also try resistors between 1 kOhm to 10 kOhm but this might affect the working of the circuit.
The LSM6DS3 has 2 configurable interrupt pins which can be triggered by a variety of functions in the LSM6DS3. We will use the INT1 pin to find when new data is available to read.
Connect these components according to the below circuit diagram:
In this tutorial, we will use interrupts to obtain Accelerometer data from the LSM6DS3. The LSM6DS3 will configured to set the INT1 pin when new accelerometer and gyroscope data is available. We will use ST’s standard C drivers to interface with the LSM6DS3. The repository for the drivers can be found here.
The driver has an device structure which requires the user to provide 3 inputs: A read function, a write function and a handle. The read and write functions can be in I2C or in SPI. The handle is the handle structure for the peripheral used to communicate with the LSM6DS3(It can be null too).
Below are the I2C read and write functions:
In the periph_setup() function in the user_periph_setup.c file, we initialize the I2C peripheral and LSM6DS3 driver.
We initialize the IMU in the user_empty_peripheral_template.c file.
The above function performs the following actions:
The GPIO interrupt is configured in the custom callback user_app_on_init() function. For more details about the custom callback and GPIO interrupt, take a look at my tutorial on GPIOs, buttons and LEDs.
Build the project and start the debugger with the DA14531 connected to your computer. If there are any issues with the working of the circuit, the execution of the program will stop. Add the accel_data_buffer variable to the expressions window. Take a look at my DA14531 ADC tutorial to check how to view the variable values by adding them to the expressions window. Pause and resume the execution multiple times to view the values change.