Adafruit FeatherM0 ASF Tutorials

The source code for the tutorials can be found on GitHub.

2017-07-05 07:05

04_RTC - Real Time Counter

The goal of this project is to get accustomed to the Real Time Clock counter of the ATSAMD21.
We will use it to toggle the LED at a period of three seconds.


We have toggled the LED in the projects before. But that was in the main loop of the program. So the MCU did pretty much nothing else. Hardly an efficient use of a 32bit ARM core. The goal of this project is to free up the main loop and have the RTC counter take care of the toggling.

Schematic Source: Adafruit, License: Attribution-ShareAlike Creative Commons

The program will:

Adding a new Atmel Software Framework (ASF) Skeleton Project

Add a new ASF Skeleton Project for the 03_Button tutorial to the existing solution.

See my Step-By-Step tutorial if you are not sure how to do this.

Choosing a startup project

To make sure AtmelStudio always compiles and runs the 04_RTC project we make it the StartUp Project.

Adding the project specific Atmel Software Framework (ASF) code

The next step is to import the ASF modules needed for the specific project.

or use the ASF Wizard entry in 04_RTC's context menu.

You should see two lists:

In Selected Modules we already see:

This is the standard framework needed for any ASF application.

In Available Modules find:

And Add>> the module to the project.

This driver provides easy access to the I/O pins.

Now in Available Modules find:

And Add>> the module to the project.

This driver allows easy usage of the MCU Real Time Clock.

Also in Available Modules find:

And Add>> this module to the project.

Which helps us using a SERCOM module in USART mode.

And again in Available Modules find:

And Add>> this module to the project.

While this driver is strictly speaking not necessary for the project, it provides the printf() function for printing to the serial terminal, making printing messages more convenient.

Now press Apply. This will add all the necessary ASF code to our project.

Using the DIT Adafruit Feather Library

For this project we need to:

See my Step-By-Step tutorial if you are unsure how to do this.

RTC Clock Setup

The clock system of the ATSAMD21 is very versatile, but it also can be quite confusing to set up for a beginner. There are a couple of moving parts involved. They have to be set up correctly for the RTC to function properly.

We need to set up:

  1. A System Clock Source (SYSTEM_CLOCK_SOURCE_XOSC32K)
    These are the actual oscillators / crystals that provide the good vibrations.
    Since the FatherM0 has especially for real time clock applications a 32.768kHz crystal attached to the MCU we are going to use it.
  2. The Generic Clock Source (GCLK), the RTC is connected to (GCLK_2).
  3. The connection between the GCLK_2 an the SYSTEM_CLOCK_SOURCE_XOSC32K

In the Solution Explorer find the generated conf_clocks.h.

For step 1 find the SYSTEM_CLOCK_SOURCE_XOSC32K section. The following values worked for me:

For step 2 and 3 find the SYSTEM_CLOCK_SOURCE_XOSC32K section.

We enable the Real Time Clock generic clock source in line 149 and connect it to the SYSTEM_CLOCK_SOURCE_XOSC32K in line 151.

Writing the application code

In the Solution Explorer find the generated main.c.

All we need to import to get the whole ASF magic working is the asf.h, that was generated by the ASF wizard. The entry should already be there. The wizard took care of that for us (line 54).

Line 65 creates an instance of an RTC module data structure. This variable needs to be globally accessible throughout this compilation unit, so it can be accessed from within the callback functions.

RTC callbacks

These callback functions are implemented in lines 70..92.


This function configures and initializes the RTC counter and the callback functions.


The main function in lines 137..175 is pretty strait forward now, since the program logic is already implemented in the RTC configuration and the callback functions.

  1. We declare a variable to hold the USART module data structure, for the serial communication module we use (line 139)
  2. In line 145 we initialize the board
  3. Line 146 enables interrupts globally
    If you forget to enable the interrupts the callback functions will not work.
  4. We use the DIT Adafruit Feather Library functions to:
  5. We do not configure any callback functions for the serial communication, since we are not actually interested in talking to the terminal.

  6. In line 159 we print the welcome message
  7. Line 166 calls the rtc_count_configure() function, that sets up the RTC counter and the callback functions
  8. Line 167 enables (starts) the RTC counter
  9. Finally we enter an infinite loop (lines 173..175) that has nothing to do