Microchip® Advanced Software Framework

Quick Start Guide for TCC - Timer

The supported board list:

  • SAM D21/R21/L21/L22/DA1/C21/HA1G16A Xplained Pro
  • SAM D11 Xplained Pro

In this use case, the TCC will be used as a timer, to generate overflow and compare match callbacks. In the callbacks the on-board LED is toggled.

The TCC module will be set up as follows:

  • GCLK generator 1 (GCLK 32K) clock source
  • Use double buffering write when set top, compare, or pattern through API
  • No dithering on the counter or compare
  • Prescaler is divided by 64
  • GCLK reload action
  • Count upward
  • Don't run in standby
  • No waveform outputs
  • No capture enabled
  • Don't perform one-shot operations
  • No event input enabled
  • No event action
  • No event generation enabled
  • Counter starts on 0
  • Counter top set to 2000 (about 4s) and generate overflow callback
  • Channel 0 is set to compare and match value 900 and generate callback
  • Channel 1 is set to compare and match value 930 and generate callback
  • Channel 2 is set to compare and match value 1100 and generate callback
  • Channel 3 is set to compare and match value 1250 and generate callback

Quick Start

Prerequisites

For this use case, XOSC32K/OSC32K should be enabled and available through GCLK generator 1 clock source selection. Within Atmel Software Framework (ASF) it can be done through modifying conf_clocks.h. See System Clock Management Driver for more details about clock configuration.

Code

Add to the main application source file, outside of any functions:

Copy-paste the following callback function code to your user application:

static void tcc_callback_to_toggle_led(
struct tcc_module *const module_inst)
{
}

Copy-paste the following setup code to your user application:

static void configure_tcc(void)
{
struct tcc_config config_tcc;
tcc_get_config_defaults(&config_tcc, TCC0);
#if (SAMR30E)
config_tcc.counter.clock_source = GCLK_GENERATOR_0;
#else
config_tcc.counter.clock_source = GCLK_GENERATOR_1;
#endif
config_tcc.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV64;
config_tcc.counter.period = 2000;
config_tcc.compare.match[0] = 900;
config_tcc.compare.match[1] = 930;
config_tcc.compare.match[2] = 1100;
config_tcc.compare.match[3] = 1250;
tcc_init(&tcc_instance, TCC0, &config_tcc);
}
static void configure_tcc_callbacks(void)
{
tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
TCC_CALLBACK_CHANNEL_0);
tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
TCC_CALLBACK_CHANNEL_1);
tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
TCC_CALLBACK_CHANNEL_2);
tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
TCC_CALLBACK_CHANNEL_3);
tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_0);
tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_1);
tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_2);
tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_3);
}

Add to user application initialization (typically the start of main()):

configure_tcc();
configure_tcc_callbacks();

Workflow

  1. Create a module software instance structure for the TCC module to store the TCC driver state while it is in use.
    Note
    This should never go out of scope as long as the module is in use. In most cases, this should be global.
  2. Configure the TCC module.
    1. Create a TCC module configuration struct, which can be filled out to adjust the configuration of a physical TCC peripheral.
      struct tcc_config config_tcc;
    2. Initialize the TCC configuration struct with the module's default values.
      tcc_get_config_defaults(&config_tcc, TCC0);
      Note
      This should always be performed before using the configuration struct to ensure that all values are initialized to known default settings.
    3. Alter the TCC settings to configure the GCLK source, prescaler, period, and compare channel values.
      #if (SAMR30E)
      config_tcc.counter.clock_source = GCLK_GENERATOR_0;
      #else
      config_tcc.counter.clock_source = GCLK_GENERATOR_1;
      #endif
      config_tcc.counter.clock_prescaler = TCC_CLOCK_PRESCALER_DIV64;
      config_tcc.counter.period = 2000;
      config_tcc.compare.match[0] = 900;
      config_tcc.compare.match[1] = 930;
      config_tcc.compare.match[2] = 1100;
      config_tcc.compare.match[3] = 1250;
    4. Configure the TCC module with the desired settings.
      tcc_init(&tcc_instance, TCC0, &config_tcc);
    5. Enable the TCC module to start the timer.
  3. Configure the TCC callbacks.
    1. Register the Overflow and Compare Channel Match callback functions with the driver.
      tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
      tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
      TCC_CALLBACK_CHANNEL_0);
      tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
      TCC_CALLBACK_CHANNEL_1);
      tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
      TCC_CALLBACK_CHANNEL_2);
      tcc_register_callback(&tcc_instance, tcc_callback_to_toggle_led,
      TCC_CALLBACK_CHANNEL_3);
    2. Enable the Overflow and Compare Channel Match callbacks so that it will be called by the driver when appropriate.
      tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_0);
      tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_1);
      tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_2);
      tcc_enable_callback(&tcc_instance, TCC_CALLBACK_CHANNEL_3);

Use Case

Code

Copy-paste the following code to your user application:

while (true) {
}

Workflow

  1. Enter an infinite loop while the timer is running.
    while (true) {
    }