Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

At a Glance

Table of Contents
excludeAt a Glance

Prerequisites

Blinking LED

Now, let's modify the getting_started project to toggle an LED once a second. First, we'll use our Hardware Abstraction Library (HAL). As a refresher, the key purpose of a HAL is to abstract platform details into a common, portable API to allow developers to write high-level application code independently of the underlying hardware.

At this point, you should be familiar with the basics of our build system and flashed your first project. You should also be aware of our Git Workflow and Coding Standards.

Code Block
# Move to the firmware folder (if you weren't already there)
cd ~/shared/firmware
# Checkout the wip_getting_started branch (just in case)
git checkout wip_getting_started
# Check what branch we're on and if we have any changes
# This should say something along the lines of "nothing to commit, working directory clean"
git status

Controlling an LED - HAL

Let's update getting_started for basic General Purpose Input/Output (GPIO) pin control. We'll assume that our LED is an active-low (turns on when output is 0) and connected to PC9 (port C, pin 9).

Code Block
languagecpp
titlemain.c
// Turns the LED on and sits forever
#include <stdbool.h>
#include "gpio.h"
#include "log.h"

int main(void) {
  LOG_DEBUG("Hello World!\n");

  // Init GPIO module
  gpio_init();

  // Set up PC9 as an output, default to output 0 (GND)
  GPIOAddressGpioAddress led = {
    .port = GPIO_PORT_CB,  //
    .pin = 95,             //
  };
  GPIOSettingsGpioSettings gpio_settings = {
    .direction = GPIO_DIR_OUT,  //
    .state = GPIO_STATE_LOWHIGH,    //
  };
  gpio_init_pin(&led, &gpio_settings);

  // Add infinite loop so we don't exit
  while (true) {
  }

  return 0;
}

...

Code Block
# Just make we're following the style guide :)
make format
make lint


# Build and flash to the DiscoveryController boardBoard
make program PROJECT=getting_started PROBE=stlink-v2

Great! You should see a solid LED on the Discovery boardController Board. This is pretty simple.

Blinking an LED - HAL

Let's add a lot more code! Now, we'll use our soft timers to toggle the LED once a second.

Code Block
languagecpp
titlemain.c
// Blink an LED
#include <stdbool.h>
#include "gpio.h"
#include "interrupt.h"
#include "log.h"
#include "soft_timer.h"
#include "wait.h"

#define BLINK_LED_TIMEOUT_SECS 1

// Timeout callback
static void prv_blink_timeout(SoftTimerIDSoftTimerId timer_id, void *context) {
  GPIOAddressGpioAddress *led = context;
  gpio_toggle_state(led);

  LOG_DEBUG("Toggling LED\n");

  // Schedule another timer - this creates a periodic timer
  soft_timer_start_seconds(BLINK_LED_TIMEOUT_SECS, prv_blink_timeout, &led, NULL);
}

int main(void) {
  LOG_DEBUG("Hello World!\n");

  // Initialize our modules
  gpio_init();
  interrupt_init();
  soft_timer_init();

  // Set up the pin
  GPIOAddressGpioAddress led = {
    .port = GPIO_PORT_CB,  //
    .pin = 95,             //
  };
  GPIOSettingsGpioSettings gpio_settings = {
    .direction = GPIO_DIR_OUT,  //
    .state = GPIO_STATE_LOWHIGH,    //
  };
  gpio_init_pin(&led, &gpio_settings);

  // Begin a timer
  soft_timer_start_seconds(BLINK_LED_TIMEOUT_SECS, prv_blink_timeout, &led, NULL);

  // Infinite loop
  while (true) {
    // Wait for interrupts
    wait();
  }

  return 0;
}

...

Woah, there's a lot going on here! Do you understand how everything works?

Code Breakdown - HAL

First, it really helps to have the firmware folder open in your editor so you can reference our source code.

...

Try playing with the code - adjust the timeout, replace wait(), change the LED, add another LED at a different interval, etc.

Cleanup and Commit - HAL

You should know the drill:

...

In all honesty, we should've committed our code when we first got a solid LED. The jump from a solid LED to blinking LED is definitely worth a commit.

Blinking LED - Registers

Just for fun, let's take a look at what something like this might look like when accessing registers directly. For this, the STM32F0 reference manual is indespensible. It will tell you everything you'll ever need to know about working with the STM32F0.

...