B.
Back to projects

nRF52 Bare Metal Suite

Photo of smooth breathing LED plugged into breadboard with nrf52 on micro:bit devboard

Overview

Tools for the nRF52 microcontroller on the microbit v2 using bare-metal C. Includes bit-banged serial, driver development for an OLED display and a custom I2C implementation. I started by manually implementing low-level protocols (such as I2C and Serial) to understand how the hardware worked. I then pivoted to using the built in peripherals for larger more complex tools (such as a firmware driver for an OLED display). All tools were programmed without the use of libraries.

What it does

  • Built a binary counter using the microbit LED matrix display and buttons by using GPIO registers to drive the display and the timer peripheral to debounce button inputs.
  • Created a smooth breathing effect on an RGB LED by using a timer peripheral and a custom Maclaurin series sine approximation to smoothly vary luminance, while hue was determined in real time from SAADC potentiometer readings. I then mapped the HSL values to RGB PWM duty cycles with a custom function.
  • Implemented a custom software based serial by bit-banging values to the UART-TX GPIO pin with timer-controlled delays. I also mirrored output to an edge connector GPIO pin for easier debugging with an oscilloscope.
  • Created a manual I2C implementation using TWI peripheral to read samples from the onboard accelerometer. I then built a motion controlled PWM synthesiser which modulated pitch based on the real time accelerometer readings using the microbit speaker with PWM when a button was pressed. To prevent jumpy sounds I used a low pass filter (rolling average with in memory buffer) to smooth raw accelerometer values.
  • Created custom drivers for microbit LED matrix display and an external OLED display using in-memory frame buffers to draw pixels, clear screen and view display state. OLED driver was also complete with an implementation of Bresenham’s line drawing algorithm.
  • Used the custom drivers to build a real time accelerometer graphing application to plot accelerometer or jerk on the OLED display. The current mode was displayed on the LED matrix display and was selected using buttons and event-driven interrupts.

Why it’s interesting

This project is interesting because I worked both directly with hardware registers when I wanted more precise control or to gain a deeper understanding and with the platform’s built-in peripheral abstractions where more control wasn’t needed. This project was also implemented on bare-metal so no drivers or external libraries were used so it gave me a deep understanding of how things work under the hood. It taught me a wide variety of things from signal processing to driver development and oscilloscope debugging.

Key Technical Points

  • Deep hardware level understanding: Was developed on bare-metal without the use of any external libraries so I learned how things worked directly on the chip below any abstractions. Even developed I2C and serial implementations without their associated peripherals to start with so I could understand how they work on a deeper level. However, I also used the peripheral implementations too to ensure I understood how to interact with them correctly.
  • Datasheet driven development: I manually configured OLED display and interfaced with accelerometer by reading datasheets and correctly writing + reading from registers.
  • Register-level peripheral control: Configured GPIO, timers, SAADC, PWM, TWI and GPIOTE interrupts directly using memory-mapped peripheral registers rather than relying on high-level wrappers. However where required (serial and later uses of I2C) I did use the CODAL implementation to prevent reinventing the wheel where I already understood key concepts.
  • Reusable abstractions: Built reusable utilities for peripheral initialisation and use to improve readability and maintainability.
  • Interrupt-driven architecture: Used timer interrupts for LED matrix refresh and graph plotting, GPIOTE interrupts with buttons and NVIC priority configuration to allow for use when microchip was busy with other tasks (e.g. application logic in graphical plotting program).
  • Composed real-time firmware application: Combined custom display firmware, button interrupts and real-time accelerometer data into a scrolling graph real time embedded program with multiple modes, a mode indicator and mode selector.

Tech Stack

Language: C/C++
Hardware: nRF52, MicroBit v2, OLED Display, RGB LED, LSM303 Accelerometer, CODAL
Peripherals: I2C/TWI, PWM, GPIOTE, SAADC, NVIC Interrupts, Timer, GPIO