Skip to content

Instantly share code, notes, and snippets.

@vondraussen
Created April 19, 2020 09:33
Show Gist options
  • Save vondraussen/be35a2e0da10e9623215ec24b0c8ef74 to your computer and use it in GitHub Desktop.
Save vondraussen/be35a2e0da10e9623215ec24b0c8ef74 to your computer and use it in GitHub Desktop.

I'm using a 32.768 kHz Quarz to drive the async counter. This should work with the WDT as well.

void _pwrsave_sleep_asyn(uint16_t time) {
  uint16_t sleepCnt = time/8;

  cli();
  // switch timer2 to asynchronously mode
  // Disable the Timer/Counter2 interrupts by clearing OCIE2x and TOIE2
  TIMSK2 = 0;
  // Select clock source by setting AS2 as appropriate
  ASSR = (1<<AS2);
  initAsynTimerRegs();

  // Clear the Timer/Counter2 Interrupt Flags
  // Enable interrupts, if needed
  TIMSK2 |= (1<<TOIE2);

  set_sleep_mode(SLEEP_MODE_PWR_SAVE);

  while(sleepCnt>0) {
    sleep_enable();
#if defined(__AVR_ATmega168P__) || defined(__AVR_ATmega328P__)
    // only possible for atmega*8P
    sleep_bod_disable();
#endif
    sei();
    sleep_cpu();
    sleep_disable();
    sleepCnt--;
  }
  // setup timer for millis() replacement of rfm69 send delay (Timer2)
  ASSR = 0;
  TCCR2A = (1<<WGM21);	// CTC Mode
  TCCR2B = ((1<<CS21)|(1<<CS20)); // prescaler 32
  OCR2A = 249;
  TIMSK2 = (1<<OCIE2A); // Timer2 interrupt on Compare Match A

  sei();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment