This timeout functionality driver uses the asynchronous Timer/Counter (TC) as time source in order to have a system tick.
Since this is the asynchronous TC module, it's convenient to use a 32KHz crystal as timeout source for real time timing. Typical tick rate is in the range 1 - 1000Hz.
The timeout functionality is a configurable number of independent timeouts that are specified in number of ticks. They can be both singleshot and periodic.
As this driver provides a software layer on top of the TC module it will have some performance penalty, so for high performance it would be recommended to implement a more specific use by implementing your own interrupt handler based on this as a reference.
Configuration is done in the configuration file : conf_tc_timeout.h
Configuration defines:
If both CONFIG_TC_TIMEOUT_CLOCK_SOURCE_TOSC and CONFIG_TC_TIMEOUT_CLOCK_SOURCE_EXCLK are undefined the IO clock is used as clock source.
First, the timeout internal setup needs to be configured and this is done by the function tc_timeout_init().
There are different functions for starting a timer:
Polling for timer status can be done with tc_timeout_test_and_clear_expired(), and this will also clear the expired flag in case of periodic timer.
A running timer can be stopped with tc_timeout_stop().
Common to all the function arguments are a timeout identifier, this is a number starting from 0 to identify the timeout. Maximum of this parameter is controlled by the configuration CONFIG_TC_TIMEOUT_COUNT.
The start timeout function uses timeout values represented in number of ticks.
First of all, the include file is needed:
Then the timeout internals need to be set up by calling:
For simple usage starting a singleshot timeout for timeout id 0 and a timeout value of 100 ticks:
Since this is a timeout layer on top of a system tick; the trigger time of a timeout is fully depending on this system tick. This means that you might not know when the next tick will count down your timeout, and this inaccuracy can be from 0 to 1 system tick.
E.g.: If you want a timeout of 1 system tick and use 1 as your timeout value, this might trigger immediately. So, if you have a requirement to wait at least 1 system tick, it would be recommended to use the requested value
However, if you know the system tick has passed or are using periodic timeout you can be confident in the timing.
Modules | |
Timer/Counter (TC) Timeout Driver internals | |
Macros | |
#define | TC_TIMEOUT_CLK_PER_TICK (CONFIG_TC_TIMEOUT_CLOCK_SOURCE_HZ / CONFIG_TC_TIMEOUT_TICK_HZ) |
Number of clocks per tick. More... | |
#define | TC_TIMEOUT_COMP (TC_TIMEOUT_CLK_PER_TICK / TC_TIMEOUT_PRESCALER - 1) |
Comparator value. More... | |
#define | TC_TIMEOUT_COMP 0 |
Comparator value. More... | |
#define | TC_TIMEOUT_PRESCALER 1 |
Prescaler value. More... | |
#define | TC_TIMEOUT_PRESCALER_MASK (1 << CS20) |
Prescaler mask bits. More... | |
#define | TC_TIMEOUT_TICK_HZ |
Actual TC timeout tick rate. More... | |
Typedefs | |
typedef uint8_t | tc_timeout_id_t |
Timeout identifier. More... | |
Functions | |
void | tc_timeout_init (void) |
Initialize TC timeout. More... | |
void | tc_timeout_start_offset (tc_timeout_id_t id, uint16_t period, uint16_t start_offset) |
Start periodic timeout with a specific start timeout. More... | |
void | tc_timeout_start_periodic (tc_timeout_id_t id, uint16_t period) |
Start periodic timeout. More... | |
void | tc_timeout_start_singleshot (tc_timeout_id_t id, uint16_t timeout) |
Start singleshot timeout. More... | |
void | tc_timeout_stop (tc_timeout_id_t id) |
Stop running timeout. More... | |
bool | tc_timeout_test_and_clear_expired (tc_timeout_id_t id) |
Test and clear expired flag for running timeout. More... | |
#define TC_TIMEOUT_CLK_PER_TICK (CONFIG_TC_TIMEOUT_CLOCK_SOURCE_HZ / CONFIG_TC_TIMEOUT_TICK_HZ) |
Number of clocks per tick.
#define TC_TIMEOUT_COMP (TC_TIMEOUT_CLK_PER_TICK / TC_TIMEOUT_PRESCALER - 1) |
Comparator value.
Referenced by tc_timeout_init().
#define TC_TIMEOUT_COMP 0 |
Comparator value.
#define TC_TIMEOUT_PRESCALER 1 |
Prescaler value.
#define TC_TIMEOUT_PRESCALER_MASK (1 << CS20) |
Prescaler mask bits.
Referenced by tc_timeout_init().
#define TC_TIMEOUT_TICK_HZ |
Actual TC timeout tick rate.
Referenced by main().
typedef uint8_t tc_timeout_id_t |
Timeout identifier.
Index for timeout to use. Limited by max value configured with CONFIG_TC_TIMEOUT_COUNT.
void tc_timeout_init | ( | void | ) |
Initialize TC timeout.
Initializes Timer/Counter for desired tick rate and starts it.
References TC_TIMEOUT_ASSR_MASK, TC_TIMEOUT_COMP, TC_TIMEOUT_OCIE, TC_TIMEOUT_OCR, TC_TIMEOUT_PRESCALER_MASK, TC_TIMEOUT_TCCRA, and TC_TIMEOUT_TIMSK.
Referenced by main().
void tc_timeout_start_offset | ( | tc_timeout_id_t | id, |
uint16_t | period, | ||
uint16_t | start_offset | ||
) |
Start periodic timeout with a specific start timeout.
id | tc_timeout_id_t |
period | Time period in number of ticks |
start_offset | Time to first timeout in number of ticks |
References tc_timeout_struct::count, cpu_irq_restore(), cpu_irq_save(), tc_timeout_struct::period, tc_timeout_active, tc_timeout_array, and tc_timeout_expired.
Referenced by tc_timeout_start_periodic(), and tc_timeout_start_singleshot().
void tc_timeout_start_periodic | ( | tc_timeout_id_t | id, |
uint16_t | period | ||
) |
Start periodic timeout.
id | tc_timeout_id_t |
period | Time period in number of ticks |
References tc_timeout_start_offset().
Referenced by main().
void tc_timeout_start_singleshot | ( | tc_timeout_id_t | id, |
uint16_t | timeout | ||
) |
Start singleshot timeout.
id | tc_timeout_id_t |
timeout | Timeout in number of ticks |
References tc_timeout_start_offset().
Referenced by main().
void tc_timeout_stop | ( | tc_timeout_id_t | id | ) |
Stop running timeout.
id | tc_timeout_id_t |
References cpu_irq_restore(), cpu_irq_save(), and tc_timeout_active.
bool tc_timeout_test_and_clear_expired | ( | tc_timeout_id_t | id | ) |
Test and clear expired flag for running timeout.
id | tc_timeout_id_t |
true | Timer have expired; clearing expired flag |
false | Timer still running |
References cpu_irq_restore(), cpu_irq_save(), and tc_timeout_expired.
Referenced by main().