Data Structures | Defines | Typedefs | Functions

rtc.h File Reference

#include <avr/io.h>

Go to the source code of this file.

Data Structures

struct  hl_time_s
 store current time More...

Defines

#define F_RTC_OSC   (32768)
 nominal frequency of low-frequency oscillator

Typedefs

typedef struct hl_time_s hl_time_t
 store current time

Functions

void hl_rtc_init_osc (void)
 activate low-frequency oscillator
void hl_rtc_init (void)
 initialize low-frequency timer
void hl_sleep_for_tick (uint16_t ms)
 enter power-save mode until next timer overflow or other wake-up event
hl_time_t hl_get_current_time (void)
 return current time
uint16_t hl_get_timer_ticks (void)
 return current tick value
void hl_wakeup_memory (void)
 allow access to external SRAM

Detailed Description


Function Documentation

void hl_rtc_init ( void   ) 

initialize low-frequency timer

hl_rtc_init() blocks as long as timer1 indicates that the necessary time for oscillator start-up has not elapsed.

{
  /* await Overflow Compare on Timer1 - one second has elapsed */
  while ((TIFR1 & _BV(OCF1A)) == 0);
  /* stop timer1 */
  TCCR1B = 0;
  /* reset OCF1A */
  TIFR1 = _BV(OCF1A);
  /* power down timer1 */
  power_timer1_disable ();

  /* wait until previous TCCR2x updates finish */
  while (ASSR & (_BV(TCN2UB)|_BV(OCR2AUB)|_BV(TCR2AUB)|_BV(TCR2BUB)));

  /* set counter register to known state */
  TCNT2 = 0;  OCR2A = RTC_SCALE-1;

  TCCR2A = 0
    /* | _BV(COM2A1) | _BV(COM2A0) */ /* disconnect OC2A */
    /* | _BV(COM2B1) | _BV(COM2B0) */ /* disconnect OC2B */
    | _BV(WGM21) /* | _BV(WGM20) */ /* CTC mode */
    ;
  TCCR2B = 0
    /* | _BV(FOC2A) | _BV(FOC2B) */ /* no Force Output Compare */
    /* | _BV(WGM22) */ /* CTC mode */
    | RTC_PRESCALER_CONTROL
    ;
  
  TIFR2 = _BV(OCF2A); /* clear OV interrupt flag */
  TIMSK2 = 0
    /* | _BV(OCIE2B) */ | _BV(OCIE2A)
    /* | _BV(TOIE2) */
    ;
}

void hl_rtc_init_osc ( void   ) 

activate low-frequency oscillator

After calling this function, wait at least one second before starting to use the timer, as this is the time the oscillator needs to stabilize.

hl_rtc_init_osc() also starts timer1 to measure the elapsed time since startup of the oscillator. The idea is to be able to do some other initialization tasks which do not need the asynchronous oscillator.

{
  power_timer2_enable ();

  /* disable interrupts from timer during start-up */
  TIMSK2 = 0;

  /* stop timer before enabling asynchronous operation */
  TCCR2B &= ~(_BV(CS22)|_BV(CS21)|_BV(CS20));
  while (ASSR & _BV(TCR2BUB));

  /* enable asynchronous operation with quartz oscillator */
  ASSR = _BV(AS2);

  /* wait until previous TCNT update finishes */
  while (ASSR & _BV(TCN2UB));

  /* reset counter */
  TCNT2 = 0;

  /* initialize Timer1 */
  power_timer1_enable ();

  /* reset counter */
  TCNT1 = 0;
  /* OC1A/B/C disconnected; WGM: normal mode */
  TCCR1A = 0;
#define TIM1_PRESCALE (256)
  /* set compare value (round up to be on safe side) */
  OCR1A = F_CPU/TIM1_PRESCALE+1;
  /* do not generate interrupt */
  TIMSK1 = 0;
  /* reset interrupt flag */
  TIFR1 = _BV(OCF1A);
  /* input capture off; WGM: normal mode; prescaler 1:256 */
  TCCR1B = _BV(CS12); /* this starts the timer */
}

void hl_wakeup_memory ( void   )  [inline]

allow access to external SRAM

hl_wakeup_memory() needs to be called in an interrupt handler when the corresponding interrupt might have woken up the CPU from sleep and the handler is going to acces external memory. Otherwise, the acces will be routed to the USB FIFO chip.

{
  XMCRB &= ~_BV(XMM1); /* assume XMM2:0 = 010 */
}