1s interrupt with a 32.768kHz crystal oscillator

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

The following code is taken from the example code of AVR Butterfly.

void RTC_init(void)
{
    Delay(1000);            // wait for 1 sec to let the Xtal stabilize after a power-on,

    __disable_interrupt();  // disabel global interrupt

    cbi(TIMSK2, TOIE2);             // disable OCIE2A and TOIE2

    ASSR = (1<<AS2);        // select asynchronous operation of Timer2

    TCNT2 = 0;              // clear TCNT2A
    TCCR2A |= (1<<CS22) | (1<<CS20);             // select precaler: 32.768 kHz / 128 = 1 sec between each overflow
    
    while((ASSR & (0x01 | 0x04)));       // wait for TCN2UB and TCR2UB to be cleared

    TIFR2 = 0xFF;           // clear interrupt-flags
    sbi(TIMSK2, TOIE2);     // enable Timer2 overflow interrupt

    OCR2A = 200;    // set timer2 compare value
    while(ASSR & 0x02);       // wait for OCR2UB to be cleared

    __enable_interrupt();                 // enable global interrupt
}

It is to achieve an interrupt every second to wake the system up with a 32.768kHz crystal oscillator. My question is, if it is better to put these two lines in the ISR:

TCCR2A = TCCR2A;  // dummy write
while(ASSR & 0x01);       // wait for TCR2UB to be cleared

because of the following description from the data sheet:

Quote:

Reading of the TCNT2 Register shortly after wake-up from Power-save may give an incorrect
result. Since TCNT2 is clocked on the asynchronous TOSC clock, reading TCNT2 must be
done through a register synchronized to the internal I/O clock domain. Synchronization takes
place for every rising TOSC1 edge. When waking up from Power-save mode, and the I/O clock
(clkI/O) again becomes active, TCNT2 will read as the previous value (before entering sleep)
until the next rising TOSC1 edge. The phase of the TOSC clock after waking up from Power-
save mode is essentially unpredictable, as it depends on the wake-up time. The recommended
procedure for reading TCNT2 is thus as follows:
1. Write any value to either of the registers OCR2A or TCCR2A.
2. Wait for the corresponding Update Busy Flag to be cleared.
3. Read TCNT2.

Thank
Owen

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK, I'll bite: Even if sleeping, what need is there to read TCNT2 in the ISR? And if not, what is the question about the need?

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:
OK, I'll bite: Even if sleeping, what need is there to read TCNT2 in the ISR? And if not, what is the question about the need?
Perhaps it is not necessary to read TCNT2 in the ISR, but that two lines solve another problem:
Quote:
If Timer/Counter2 is used to wake the device up from Power-save or ADC Noise
Reduction mode, precautions must be taken if the user wants to re-enter one of
these modes: The interrupt logic needs one TOSC1 cycle to be reset. If the time
between wake-up and re-entering sleep mode is less than one TOSC1 cycle, the
interrupt will not occur, and the device will fail to wake up. If the user is in doubt
whether the time before re-entering Power-save or ADC Noise Reduction mode is
sufficient, the following algorithm can be used to ensure that one TOSC1 cycle has
elapsed:
1. Write a value to TCCR2A, TCNT2, or OCR2A.
2. Wait until the corresponding Update Busy Flag in ASSR returns to zero.
3. Enter Power-save or ADC Noise Reduction mode.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well what do you do after wake-up? If you only count seconds then that is very fast operation and needs the workaround. If you do something that takes more time than async timer tick the you don't need it.

You also don't use sleep in the interrup so it is not wise to spend too much time waiting in it. you can do the dummy write which triggers the sync logic but do the waiting before sleep in main. if further stuff needs to be done after interrupt but before sleeping like writing the time to lcd then it can be done no matter how long it takes and the async update period could be over by then.