Firmware Programming

Overview and Folder structure

The complete firmware for the electronic board of the scoreboard is quite complex, and is composed of several different parts. To make everything more understandable (hopefully), I created an Atmel Studio Project, with different folders for each major software component.

Work files links

Full Atmel Studio project for Controller Firmware
firmware.zip

This is the complete folder structure of the project, with the files used:


  • libs
    • bt:
      bluetooth and SPP management, for BTM-222 module

    • event_queue:
      simple static queue to handle asynchronous events

    • gpio:
      general purpose macros for I/O

    • keypad:
      keymatrix routines with buttons mapping to functions

    • rf:
      software SPI libraries for CC2500 rf module, with receiving parameters

    • rtc:
      (improperly called) real time clock library to manage timings and delays

    • segments:
      helper library to use with ws2812b to achieve numbers on segment displays in an easy way

    • uart:
      serial library to use in conjunction with bt

    • ws2812b:
      optimized low level library for WS2812B intelligent pixels

  • config.h:
    pin configuration and constants define

  • Controller.c:
    main state machine

Displays driving

To display numbers on the digit displays I created some wrapper functions, that facilitate the operations sequence to determine which leds should be on and which not, starting from a decimal number.

The first step was to create some constants to represent which segments should be on, for each decimal number, according to the segments order defined in Electronics Fabbing - #7 Segments Digits. The next step was to create an array to replicate the bit state (on or off) for the number of pixels in each segment.

In the image above, every little box in the row "Pixels", is a single pixel value, where 'C' is a struct containing values for the 3 channels, Red Green and Blue.


Main FSM and Events

The firmware of the controller is essentially a complex finite state machine, that reacts to events to perform the display update. An event queue is filled as soon as some interaction occurs, coming from:

  • push buttons
    The possible events coming from the buttons are:
    • single short click
    • double click • •
    • long click ¬
    • 1 Hz repetition after long click ¬ ~ ~ etc.
    • single click and retain • ¬
    • 1 Hz repetition after click and retain • ¬ ~ ~ etc.
  • bluetooth protocol packets
  • RF radio packets
  • display refresh

The event queue is basically a circular buffer in which every element is a struct defined like this:


  • Event_type
    it defines the type of the event. It can be one of the enumeration value event_type.
    At the moment only the value NAVIGATION is used.

  • Event_Source
    it defines the source of the event. It can be one of the enumeration value source_type.
    The possible values are KEYPAD and RF_MODULE.

  • Parameter_1 / Parameter_2
    two bytes parameters to specify additional information about the event.

Below you can find a diagram recap for the main finite state machine: