5 Using TCB in Sleep Mode

Use case description: Configure TCB to generate an overflow interrupt every second, even when the microcontroller is in Standby sleep mode, and toggle a GPIO pin (PB5).

Result: TCB overflow interrupt will be triggered every one second, regardless of the running mode of the microcontroller (Idle/Standby). In the Interrupt Service Routine (ISR), the on-board LED, corresponding to PB5, will be toggled.

TCBn is by default disabled in Standby sleep mode; as soon as the microcontroller enters sleep mode, TCB will be halted. The module can stay fully operational in Standby sleep mode if the Run In Standby (RUNSTDBY) bit in the TCBn.CTRLA register is written to ‘1’.

Configuring the System Clock for Sleep Mode

To obtain an interrupt of one second for the 16-bit TCB timer, the input frequency must be as low as possible. For this, the internal 32 kHz oscillator can be used. There is no need to use a frequency divider, so the prescaler for CLK_PER must be disabled. There are three steps in the configuration process:

  1. Disable the CLK_PER prescaler - The following code snippet will demonstrate how to disable the CLK_PER prescaler.
    ccp_write_io( (void *) &CLKCTRL.MCLKCTRLB , (0 << CLKCTRL_PEN_bp)); 
  2. Select the internal 32 kHz oscillator - The following code snippet will switch the system clock source to the internal 32 kHz oscillator.
    ccp_write_io( (void *) &CLKCTRL.MCLKCTRLA, (CLKCTRL_CLKSEL_OSCULP32K_gc));
  3. Wait for the clock switch process to complete - The following code snippet will demonstrate how to wait for the clock source switching process to finish.
    while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm)
    {
        ;
    }
    

Configuring the Sleep Mode Operation

Sleep modes are used to shut down peripherals and clock domains in the device to save power. The Sleep Controller (SLPCTRL) controls and handles the transitions between Active and sleep mode. Four modes are available: One Active mode in which software is executed and three sleep modes. The available sleep modes are Idle, Standby, and Power-Down.

The interrupts are used to wake the device from sleep. The available interrupt wake-up sources depend on the configured sleep mode. When an interrupt occurs, the device will wake up and execute the interrupt service routine before continuing normal program execution from the first instruction following the SLEEP instruction.
Figure 5-1. SLPCTRL.CTRLA Register

The TCB module can run while the microcontroller is in Standby sleep mode. The Power-Down sleep mode disables TCB completely.

For this use case, the ATmega4809 microcontroller will be configured to enter sleep in Standby sleep mode. Entering sleep must also be enabled. The following code enables the sleep operation and configures the ATmega4809 microcontroller to enter Standby sleep mode when the SLEEP instruction is executed.
SLPCTRL.CTRLA = SLPCTRL_SMODE_gm | SLPCTRL_SMODE_STDBY_gc;

Configuring TCB in Periodic Interrupt Mode

The following configuration must be made to the registers:
  • TCBn.CCMP
  • TCBn.CTRLA

The TCB Capture/Compare register must be loaded with a comparison value which will trigger an interrupt. For this document, a value of one second for the periodic interrupt has been chosen. With an input frequency of 32.768 kHz, the 16-bit counter will make a complete cycle in two seconds (the maximum value of a 16-bit number is 65535). Since the maximum value the 16-bit TCB counter can achieve is 65535 for the two seconds maximum period, the CCMP register must be loaded with half of the maximum value – 32768 (0x7FFF). The following code snippet loads the TCB0.CCMP register with 0x7FFF.

TCB0.CCMP = 0x7fff; 
Figure 5-2. TCBn.CTRLA Register Configuration

Prescaling is not needed, so the divider value will be ‘0’. Also, the timer must be enabled. For the TCB to still generate an interrupt while in Standby sleep mode, the RUNSTDBY bit must also be enabled. The following code snippet sets the clock divider to ‘0’, enables the timer, and allows the timer to run in Standby sleep mode.

TCB0.CTRLA = TCB_CLKSEL_CLKDIV1_gc | TCB_ENABLE_bm | TCB_RUNSTDBY_bm;

To trigger a periodic interrupt, the CAPT bit of the TCB0.INTCTRL register must be enabled. The following code snippet enables the interrupt.

TCB0.INTCTRL = TCB_CAPT_bm;
Note:
  1. The global interrupts must be also enabled. This can be done at a later step in the software program.
  2. All operations are halted in Power-Down sleep mode.

Configuring a Pin as Output for Visualizing Interrupt Occurrence

To visualize the periodic interrupt occurrence, the PB5 pin will be configured in Output mode. The following code sets PB5 as output low.

PORTB_DIR |= PIN5_bm;
PORTB_OUT |= PIN5_bm;
Tip: The full code example is also available in the Appendix section.

An MCC generated code example for AVR128DA48, with the same functionality as the one described in this section, can be found here: