Introduction.
TIM module provides time-based functionalities such as free running counter and time-based events. TIM module usually uses internal peripheral timers and timer interrupts to implement periodical time ticks, that become time units. These interrupts also trigger the application-defined events. The events can be executed inside the trigger interrupt service routine (so called interrupt-level events) or in the background task (task-level events). TIM module uses TIMDevice as timer abstraction. Hardware-specific ports are responsible for providing such objects.
Free running counter.
One of the main TIM functionalities is to provide a simple counter that will be incremented periodically with as much precision as possible. This counter is started during timer initialization by a call to TIM_Init. The current value of the counter can be obtained by a call to TIM_GetTime.
Time-based events.
Application can generate time-based events. An event is signaled when a specified amount of time passes. Time based events use free running counter to measure such time periods. When event is signaled an application-defined function (an event handler) can be called.
To create new event and connect an event handler to it the application must call TIM_InitEvent. This call returns event_id that is used to identify the event in the scope of a single TIMDevice.
To schedule an event two functions can be used: TIM_ScheduleEvent and TIM_ScheduleEventAt.
There are two types of events that differ in a way the event handlers are called:
- The "interrupt-level" events make the event handler functions execute directly in the interrupt service routine (ISR) that triggered the event. Such events must be used with care, and should be as short as possible.
- The "task-level" events do not call the event handlers from inside the ISR. Instead, they just mark that the event was triggered. The handler is executed during the next call to the TIM_TaskEventProc, which can be in turn called periodically in a OS task or inside some main loop.
The main difference between these two types of event is the response time precision. The response time for "interrupt-level" events is usually shorter, because the event handlers are called directly by the triggering interrupt. These are suited for precise time actions. The "task-level" events usually add some time overhead before the next TIM_TaskEventProc is called. These are suited for less time-critical jobs.
The type of event is declared during event setup (a call to TIM_InitEvent) but it can be changed any time by the TIM_SetEventType. The TIM_GetEventType returns the current type of an event.
Timer setup.
To setup the timer the application must call TIM_Init and provide the timer time base. This time base defines the timer resolution. It's the period between two timer ticks, expressed in nano-seconds. So for example:
would setup TIM1 with 1us resolution.
Using TIM events
Let's toggle a LED using events with HAL_TIM1 timer. Let's say we want to toggle every 200ms. To do that we setup HAL_TIM1 to count every 1ms.
Now, let's create an interrupt-level event and schedule it.
We must define the event handler:
To use the same event as task-level event, the application must periodically call TIM_TaskEventProc, for example in OS task:
void TASK_TIM(void *pvParameters)
{
while(1) {
}
}
Module configuration.
To enable the TIM module, HAL_ENABLE_TIM definition must be set to 1, in hal_config.h. The HAL_TIM_USE_INTERRUPT_EVENTS and HAL_TIM_USE_TASK_EVENTS enable or disable interrupt-level events and task-level events.
|
void | TIM_Init (TIMDevice tim, uint32_t TickTimeBase) |
|
int64_t | TIM_GetTimeInNS (TIMDevice tim) |
|
int64_t | TIM_GetTimeElapsed (TIMDevice tim, TIM_Time since) |
|
TIM_Time | TIM_NSToTimTime (TIMDevice tim, int64_t ns) |
|
int64_t | TIM_TimTimeToNS (TIMDevice tim, TIM_Time t) |
|
TIM_EventID | TIM_InitEvent (TIMDevice tim, void(*handler)(TIMDevice tim, TIM_EventID event_id, TIM_Time expire_time, void *context), TIM_EventType type, void *context) |
|
void | TIM_DeinitEvent (TIMDevice tim, TIM_EventID event_id) |
|
HALRESULT | TIM_ScheduleEvent (TIMDevice tim, TIM_EventID event_id, TIM_Time delta_time) |
|
HALRESULT | TIM_ScheduleEventAt (TIMDevice tim, TIM_EventID event_id, TIM_Time abs_time) |
|
HALRESULT | TIM_UnscheduleEvent (TIMDevice tim, TIM_EventID event_id) |
|
bool | TIM_IsEventScheduled (TIMDevice tim, TIM_EventID event_id) |
|
TIM_EventID | TIM_SetEventType (TIMDevice tim, TIM_EventID event_id, TIM_EventType type) |
|
TIM_EventType | TIM_GetEventType (TIM_EventID event_id) |
|
TIM_Time | TIM_GetTimeToEvent (TIMDevice tim, TIM_EventID event_id) |
|
TIM_EventID | TIM_GetNextEvent (TIMDevice tim) |
|
TIM_Time | TIM_GetEventTime (TIMDevice tim, TIM_EventID event_id) |
|
void | TIM_TaskEventProc (TIMDevice tim) |
|
void | TIM_InterruptProc (TIMDevice tim) |
|
TIM_Time | TIM_AddTime (TIMDevice tim, TIM_Time t1, TIM_Time t2) |
|
TIM_Time | TIM_SubtractTime (TIMDevice tim, TIM_Time t1, TIM_Time t2) |
|
int | TIM_CompareTime (TIM_Time t1, TIM_Time t2) |
|
#define TIM_Deinit |
( |
|
TIM | ) |
(TIM)->Deinit(TIM) |
Deinitializes specified timer object. Stops the running timer.
- Parameters
-
#define TIM_GetTime |
( |
|
TIM | ) |
(TIM)->GetTime(TIM) |
Returns the number of timer ticks elapsed since the timer was initialized and started running.
- Parameters
-
#define TIM_ResetCounter |
( |
|
TIM | ) |
(TIM)->ResetCounter(TIM) |
Resets specified timer's counter
- Parameters
-
#define TIM_GetCapabilities |
( |
|
TIM, |
|
|
|
Caps |
|
) |
| (TIM)->GetCapabilities(TIM, Caps) |
Resets specified timer's counter
- Parameters
-
TIM | timer handle |
Caps | pointer to description structure |
#define TIM_GetError |
( |
|
TIM, |
|
|
|
TickTimeBase |
|
) |
| (TIM)->GetError(TIM, TickTimeBase) |
Resets specified timer's counter
- Parameters
-
TIM | timer handle |
TickTimeBase | selected time base |
- Returns
- selected time base minus actual time base that can be realized by hardware (in nanoseconds)
Possible event types
Enumerator |
---|
TIM_EVENT_TYPE_NO_TYPE |
Uninitialized type of event.
|
TIM_EVENT_TYPE_INTERRUPT |
This type indicates that the event handler is called from within an interrupt service routine.
|
TIM_EVENT_TYPE_TASK |
This type indicates, that the event handler is called from a task (and NOT directly in an interrupt service routine).
|
void TIM_Init |
( |
TIMDevice |
tim, |
|
|
uint32_t |
TickTimeBase |
|
) |
| |
Initializes the specified timer object and starts the timer.
- Parameters
-
tim | timer handle |
TickTimeBase | time between timer ticks in nanoseconds |
Return timer time in nanoseconds, elapsed since the timer was started.
- Parameters
-
- Returns
- time in nanoseconds
Return timer time in nanoseconds, elapsed since the specified time.
- Parameters
-
tim | timer handle |
since | reference time |
- Returns
- time in nanoseconds
Converts nanosecond time to timer time.
- Parameters
-
tim | timer handle |
ns | time in nanoseconds |
- Returns
- time in timer format
Converts timer time to nanosecond time
- Parameters
-
tim | timer handle |
t | time in timer format |
- Returns
- time in nanoseconds
Initializes a new event and connects it's event handler.
- Parameters
-
tim | timer handle |
handler | event handler function called when event is triggered |
context | event context passed to the handler function |
type | event type - this can be TIM_EVENT_TYPE_INTERRUPT or TIM_EVENT_TYPE_TASK |
- Returns
- ID of a new event associated with timer or -1 if initialization failed
Deinitializes an event. The provided event_id will be reused.
- Parameters
-
Schedules an event to be triggered after a specified amount of time.
- Parameters
-
tim | timer handle |
event_id | event id returned by a previous call to TIM_InitEvent or TIM_SetEventType |
delta_time | - time after which event will be triggered |
- Returns
- HALRESULT_OK if schedule succeeded, other values indicate error
Schedules an event to be triggered after a specified amount of time.
- Parameters
-
tim | timer handle |
event_id | event id returned by a previous call to TIM_InitEvent or TIM_SetEventType |
abs_time | - absolute time at which event will be triggered |
- Returns
- HALRESULT_OK if schedule succeeded, other values indicate error
Unschedules an event previously scheduled with TIM_ScheduleEvent or TIM_ScheduleEventAt
- Parameters
-
tim | timer handle |
event_id | event id |
- Returns
- HALRESULT_OK if unschedule succeeded, other values indicate error
Checks if the event is scheduled.
- Parameters
-
- Returns
- true if the event is scheduled, false otherwise
Sets event type
- Parameters
-
tim | timer handler |
event_id | ID of event that's type we want to set |
type | new type of handler |
- Returns
- new Event ID
Returns event type
- Parameters
-
event_id | ID of event that's type we want to get |
- Returns
- Event type
Returns time left to execute the specified event
- Parameters
-
tim | timer handler |
event_id | ID of event |
- Returns
- time to the event
Gets the next event that will be executed.
- Parameters
-
- Returns
- Id of the next event that will be executed
Gets the time at which the given event will be executed.
- Parameters
-
tim | timer handler |
event_id | ID of the event |
- Returns
- time at which the event will be executed
Calls each handler connected to specified timer that need to be called. This function have to be always called in some loop (in task or "main").
- Parameters
-
Calls each handler connected to specified timer that need to be called. This function have to be called in specified interrupt.
- Parameters
-
Sums up two TIM times.
- Parameters
-
tim | timer handler |
t1 | augend |
t2 | addend |
- Returns
- t = t1 + t2
Subtracts two TIM times.
- Parameters
-
tim | timer handler |
t1 | minuend |
t2 | subtrahend |
- Returns
- t = t1 - t2
Compares two TIM times.
- Parameters
-
t1 | first time to compare |
t2 | second time to compare |
- Return values
-
1 | when t1 is greater than t2 |
-1 | when t2 is greater than t1 |
0 | when the times are equal |