Microchip® Advanced Software Framework

Quick Start Guide for TCC - Callback

The supported board list:

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

In this use case, the TCC will be used to generate a PWM signal, with a varying duty cycle. Here the pulse width is increased each time the timer count matches the set compare value. When the PWM signal connects to LED, LED will light. To see the waveform, you may need an oscilloscope. SAMHA1G16A Xpro LED is PA00 which isn't connected out, use PA04 instead, so we can't see LED blink but only see the waveform from oscilloscope.

The PWM output is set up as follows:

Board Pin Connect to
SAM D21 Xpro PB30 LED0
SAM R21 Xpro PA19 LED0
SAM L21 Xpro PB10 LED0
SAM L22 Xpro PC27 LED0
SAM DA1 Xpro PB30 LED0
SAM C21 Xpro PA15 LED0
SAM HA1G16A Xpro PA04 NULL

The TCC module will be set up as follows:

  • GCLK generator 0 (GCLK main) clock source
  • Use double buffering write when set top, compare, or pattern through API
  • No dithering on the counter or compare
  • No prescaler
  • Single Slope PWM wave generation
  • GCLK reload action
  • Don't run in standby
  • No faults or waveform extensions
  • No inversion of waveform output
  • No capture enabled
  • Count upward
  • Don't perform one-shot operations
  • No event input enabled
  • No event action
  • No event generation enabled
  • Counter starts on 0

Quick Start

Prerequisites

There are no prerequisites for this use case.

Code

Add to the main application source file, before any functions:

#if SAMR30G
#define CONF_PWM_MODULE LED_0_PWM3CTRL_MODULE
#define CONF_PWM_CHANNEL LED_0_PWM3CTRL_CHANNEL
#define CONF_PWM_OUTPUT LED_0_PWM3CTRL_OUTPUT
#define CONF_PWM_OUT_PIN LED_0_PWM3CTRL_PIN
#define CONF_PWM_OUT_MUX LED_0_PWM3CTRL_MUX
#elif SAMR30E
#define CONF_PWM_MODULE LED_1_PWM2CTRL_MODULE
#define CONF_PWM_CHANNEL LED_1_PWM2CTRL_CHANNEL
#define CONF_PWM_OUTPUT LED_1_PWM2CTRL_OUTPUT
#define CONF_PWM_OUT_PIN LED_1_PWM2CTRL_PIN
#define CONF_PWM_OUT_MUX LED_1_PWM2CTRL_MUX
#else
#define CONF_PWM_MODULE LED_0_PWM4CTRL_MODULE
#define CONF_PWM_CHANNEL LED_0_PWM4CTRL_CHANNEL
#define CONF_PWM_OUTPUT LED_0_PWM4CTRL_OUTPUT
#define CONF_PWM_OUT_PIN LED_0_PWM4CTRL_PIN
#define CONF_PWM_OUT_MUX LED_0_PWM4CTRL_MUX
#endif

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

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

struct tcc_module *const module_inst)
{
static uint32_t delay = 10;
static uint32_t i = 0;
if (--delay) {
return;
}
delay = 10;
i = (i + 0x0800) & 0xFFFF;
tcc_set_compare_value(module_inst,
(TCC_MATCH_CAPTURE_CHANNEL_0 + CONF_PWM_CHANNEL),
i + 1);
}

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

static void configure_tcc(void)
{
struct tcc_config config_tcc;
config_tcc.counter.period = 0xFFFF;
config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
config_tcc.compare.match[CONF_PWM_CHANNEL] = 0xFFFF;
config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT] = CONF_PWM_OUT_PIN;
config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT] = CONF_PWM_OUT_MUX;
}
static void configure_tcc_callbacks(void)
{
(enum tcc_callback)(TCC_CALLBACK_CHANNEL_0 + CONF_PWM_CHANNEL));
(enum tcc_callback)(TCC_CALLBACK_CHANNEL_0 + CONF_PWM_CHANNEL));
}

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

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.
      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 counter width, wave generation mode, and the compare channel 0 value.
      config_tcc.counter.period = 0xFFFF;
      config_tcc.compare.wave_generation = TCC_WAVE_GENERATION_SINGLE_SLOPE_PWM;
      config_tcc.compare.match[CONF_PWM_CHANNEL] = 0xFFFF;
    4. Alter the TCC settings to configure the PWM output on a physical device pin.
      config_tcc.pins.enable_wave_out_pin[CONF_PWM_OUTPUT] = true;
      config_tcc.pins.wave_out_pin[CONF_PWM_OUTPUT] = CONF_PWM_OUT_PIN;
      config_tcc.pins.wave_out_pin_mux[CONF_PWM_OUTPUT] = CONF_PWM_OUT_MUX;
    5. Configure the TCC module with the desired settings.
    6. Enable the TCC module to start the timer and begin PWM signal generation.
  3. Configure the TCC callbacks.
    1. Register the Compare Channel 0 Match callback functions with the driver.
    2. Enable the Compare Channel 0 Match callback so that it will be called by the driver when appropriate.
      (enum tcc_callback)(TCC_CALLBACK_CHANNEL_0 + CONF_PWM_CHANNEL));

Use Case

Code

Copy-paste the following code to your user application:

while (true) {
}

Workflow

  1. Enter an infinite loop while the PWM wave is generated via the TCC module.
    while (true) {
    }