4 Using TCB in Time-Out Check Mode
Use case description: Configure TCB in Time-Out Check mode and measure the signal time generated by a GPIO (configured as an input). The time-out will be set to one second and the event system will be used to detect the rising and falling edges of the signal generated by a GPIO (e.g., a push button in a real application). If the time-out expires, another GPIO (e.g., an LED in a real application) will be toggled in the interrupt.
Result: Use a GPIO as input to generate an event that serves as the input signal for TCB. Generate an interrupt when the time-out expires.
In the Time-Out Check mode, TCB relies on the interaction with the event system, as displayed in the figure below. In this mode, the counter counts to MAX and wraps around. On the first edge, the counter is restarted. On the second edge, the counter is stopped. If the Count (TCBn.CNT) register reaches TOP before the second edge, an interrupt will be generated. In the Freeze state, the counter will restart on a new edge. Reading count (TCBn.CNT) or the Capture/Compare (TCBn.CCMP) register, or writing the RUN bit (RUN in TCBn.STATUS) in Freeze state will have no effect.
Configuring the System Clock
To obtain a period 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:
- 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));
- 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));
- 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) { ; }
- Writing to the MCLKCTRLA and
MCLKCTRLB registers requires the IOREG key to be written to the CPU.CCP
register. This is done by using the
ccp_write_io
function from theavr/cpufunc.h
header file. - The Clock Control registers are described in Using TCB in 8-Bit PWM Mode.
Configuring TCB in Time-Out Check Mode
To generate a signal using a GPIO pin, the event system must be set up accordingly. Port B Pin 2 (PB2) will be used as an example in this document.
The following registers must be configured:
- TCB0.CCMP
- TCBn.INTCTRL
- TCBn.EVCTRL
- EVSYS.CHANNEL
- EVSYS.USER
- TCB0.CCMP Configuration
The TCB Capture/Compare register must be loaded with the value of the time-out. For this document, a value of one second for the time-out 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).
The reload value of TCB0.CCMP can be calculated, as shown below:
A value of 32767.5 cannot be translated into hex, so 32767 will be used instead.
The following code snippet will load TCB0.CCMP with
0x7FFF
time-out value.TCB0.CCMP = 0x7fff;
- TCBn.INTCTRL Configuration
Figure 4-2. TCBn.INTCTRL Register Configuration TCB0.CNT will start increasing as soon as a signal edge is detected on the event system bus. If the complementary edge of the signal is not detected within the time-out, TCB0 will trigger an interrupt. In this regard, capture or time-out interrupt must be enabled in the TCB0.INCTRL register. The following code snippet enables the interrupt.
TCB0.INTCTRL = TCB_CAPT_bm;
Note: The global interrupts must also be enabled. This can be done at a later step in the software program. - TCBn.EVCTRL Configuration
Figure 4-3. TCBn.EVCTRL Register Configuration The target is to measure the signal time between the falling edge and the rising edge of the PB2 input pin (in Idle, the pin is kept in high state). This means both CAPTEI and EDGE bits must be set to ‘
1
’. The following code snippet enables both bits in the TCB0.EVCTRL register.TCB0.EVCTRL = TCB_CAPTEI_bm | TCB_EDGE_bm;
- EVSYS.CHANNEL
Configuration
Each channel can be connected to a one-event generator. Not all generators can be connected to all channels. Refer to the table below to see which generator sources can be routed onto each channel and the generator value that must be written to EVSYS.CHANNELn to achieve this routing. The value
0x00
in EVSYS.CHANNELn turns the channel off.Figure 4-4. EVSYS.CHANNEL Register Configuration EVSYS.CHANNEL must be loaded with the value
0x4A
for PB2 to generate an input event, as represented in the following code snippet.EVSYS.CHANNEL0 = EVSYS_GENERATOR_PORT1_PIN2_gc;
- EVSYS.USER
Configuration
Each event user can be connected to one channel. Several users can be connected to the same channel. The following table lists all event system users, with their corresponding user ID number. This ID number corresponds to the USER register index, e.g., the user with ID 2 is controlled by the EVSYS.USER2 register.
Figure 4-5. EVSYS.USERTCB0 Register Configuration The user channel must be linked to the event channel already configured previously (in EVSYS.CHANNEL). The following code snippet illustrates how this can be done.
EVSYS.USERTCB0 = EVSYS_CHANNEL_CHANNEL0_gc;
An MCC generated code example for AVR128DA48, with the same functionality as the one described in this section, can be found here: