32kHz Timer Implementation More...
#include "config.h"
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include "keys.h"
#include "xpal_power.h"
#include "xpal_async32khz.h"
Defines | |
#define | HL_ASYN_FAST_INC 5 |
Functions | |
void | hl_asyn_init_osc (void) |
Init async timer system - initiate oscillator startup. | |
void | hl_asyn_init_timer (void) |
init async timer system - initialize timer device | |
void | hl_asyn_init (void) |
Init async timer system. | |
ISR (TIMER2_COMPB_vect) | |
TIMER2_COMPB_vect used as 1sec, slow system timer. | |
ISR (TIMER2_COMPA_vect) | |
19,53ms timer | |
void | hl_asyn_Register1sTimer (cb_function_t fkt2call, void *arg) |
Register a call back function for the slow timer. | |
void | hl_asyn_RegisterFastTimer (cb_function_t fkt2call, void *arg) |
Register a call back function for the fast timer. | |
void | hl_asyn_StartSysTimer (void) |
Start the system Timer again. | |
void | hl_asyn_StopSysTimer (void) |
Stop the system Timer. | |
void | hl_asyn_ReportErrors (errString_t errMsg) |
Check for Error Conditions and report string for error log. | |
Variables | |
uint8_t | FastTimerInc |
Async timer overflow increment storage. | |
cb_list_t | cbListSlowFirst |
First element in slow timer callback list. | |
cb_list_t | cbListFastFirst |
First element in fast timer callback list. | |
volatile uint8_t | SysTimerStatus |
System Timer Call Status. |
32kHz Timer Implementation
void hl_asyn_init | ( | void | ) |
Init async timer system.
Initialize the 32kHz timer (timer2).
{ // init callback lists #if 0 /* not needed since data gets initialised to 0 by startup */ cbListSlowFirst = NULL; cbListFastFirst = NULL; #endif hl_asyn_init_osc (); // allow xtal to startup _delay_ms(1000); hl_asyn_init_timer (); }
void hl_asyn_Register1sTimer | ( | cb_function_t | fkt2call, | |
void * | arg | |||
) |
Register a call back function for the slow timer.
The function will add an entry to the list of functions to be called when the 1sec timer expires
The new entry is added to the front of the list.
{ cb_register_call (&cbListSlowFirst, fkt2call, arg); }
void hl_asyn_RegisterFastTimer | ( | cb_function_t | fkt2call, | |
void * | arg | |||
) |
Register a call back function for the fast timer.
The function will add an entry to the list of functions to be called when the 19,53ms timer expires
The new entry is added to the front of the list.
{ cb_register_call (&cbListFastFirst, fkt2call, arg); }
void hl_asyn_ReportErrors | ( | errString_t | errMsg | ) |
Check for Error Conditions and report string for error log.
Report error string if available.
Function will return a zero terminated string containing the async timer error msg.
{ if(SysTimerStatus & (ASYNC_SLOW_OVERRUN | ASYNC_FAST_OVERRUN)){ // One of the timers has had an overrun switch (SysTimerStatus & (ASYNC_SLOW_OVERRUN | ASYNC_FAST_OVERRUN)){ case(ASYNC_SLOW_OVERRUN): sprintf_P(errMsg, PSTR("ERR - Asyn 1s TMR OVR")); // Clear Error condition SysTimerStatus &= ~(ASYNC_SLOW_OVERRUN); break; case(ASYNC_FAST_OVERRUN): sprintf_P(errMsg, PSTR("ERR - Asyn 20ms TMR OVR")); // Clear Error condition SysTimerStatus &= ~(ASYNC_FAST_OVERRUN); break; case(ASYNC_SLOW_OVERRUN | ASYNC_FAST_OVERRUN): sprintf_P(errMsg, PSTR("ERR - Both TMR OVR")); // Clear Error condition SysTimerStatus &= ~(ASYNC_SLOW_OVERRUN | ASYNC_FAST_OVERRUN); break; default: sprintf_P(errMsg, PSTR("ERR - TMR")); break; } }else{ // No Errors detected errMsg[0] = 0; } }
void hl_asyn_StartSysTimer | ( | void | ) |
Start the system Timer again.
Restart the system timer again when it was stopped to save power
{ FastTimerInc = HL_ASYN_FAST_INC + TCNT2; OCR2A = FastTimerInc; // Compare value for next fast system timer // set fast timer status SysTimerStatus &= ~(ASYNC_FAST_STOP); /* Reset any pending interrupt */ TIFR2 = _BV(OCF2A); /* Start System Timer if not running */ TIMSK2 |= _BV(OCIE2A); }
void hl_asyn_StopSysTimer | ( | void | ) |
Stop the system Timer.
Stop the system timer to save power
{ /* Start System Timer if not running */ TIMSK2 &= ~(_BV(OCIE2A)); // set fast timer status SysTimerStatus |= ASYNC_FAST_STOP; }
ISR | ( | TIMER2_COMPB_vect | ) |
TIMER2_COMPB_vect used as 1sec, slow system timer.
Uset to create a 1s timer thatcan be synced
{ hl_pwr_SetWakeSource(HL_PWR_WAKE_BY_1S_TMR); if( (SysTimerStatus & ASYNC_SLOW_ACTIVE) == 0 ){ // this timer is not active, set execution active and process SysTimerStatus |= ASYNC_SLOW_ACTIVE; if( (SysTimerStatus & ASYNC_FAST_ACTIVE) == 0 ){ // Fast timer is not active, enable other interrupts as long // as slow functions get called sei(); callback_iterate (cbListSlowFirst); cli(); }else{ // Fast timer is active, set block flag SysTimerStatus |= ASYNC_SLOW_BLOCK; // The fast timer will call the slow timer execution when done // This will avoid recursive calls } // timer operation done, set inactive SysTimerStatus &= ~(ASYNC_SLOW_ACTIVE); }else{ // this int is still in execution, set overrun SysTimerStatus |= ASYNC_SLOW_OVERRUN; } // Run now fast timer calls ín case the fast timer was blocked // INT stays disabled for fast execution if (SysTimerStatus & ASYNC_FAST_BLOCK){ callback_iterate (cbListFastFirst); // reset blocking state SysTimerStatus &= ~(ASYNC_FAST_BLOCK); } }
ISR | ( | TIMER2_COMPA_vect | ) |
19,53ms timer
Compare value is incremented by HL_ASYN_FAST_INC during each ISR call
{ FastTimerInc += HL_ASYN_FAST_INC; OCR2A = FastTimerInc; // Compare value for next fast system timer hl_pwr_SetWakeSource(HL_PWR_WAKE_BY_SYS_TMR); if( (SysTimerStatus & ASYNC_FAST_ACTIVE) == 0 ){ // no fast int execution active, activate SysTimerStatus |= ASYNC_FAST_ACTIVE; if( (SysTimerStatus & ASYNC_SLOW_ACTIVE) == 0 ){ // Slow timer is not active, enable other interrupts as long // as fast timer functions get called sei(); callback_iterate (cbListFastFirst); cli(); }else{ // Slow timer is active, set block flag SysTimerStatus |= ASYNC_FAST_BLOCK; // The fast timer will call the slow timer execution when done // This will avoid recursive calls } // fast int execution done, set inactive SysTimerStatus &= ~(ASYNC_FAST_ACTIVE); }else{ // Fast int still in execution, set overrun SysTimerStatus |= ASYNC_FAST_OVERRUN; } // Run now 1s timer calls ín case the fast timer was blocked // INT stays disabled for slow execution if (SysTimerStatus & ASYNC_SLOW_BLOCK){ callback_iterate (cbListSlowFirst); // reset blocking state SysTimerStatus &= ~(ASYNC_SLOW_BLOCK); } }
volatile uint8_t SysTimerStatus |
System Timer Call Status.
This bitmap variable will mirror the current timer call and Interrupt status It will allow the recognition of overun effects and lock the recursive call of timer functions.