github.com/aykevl/tinygo@v0.5.0/src/runtime/runtime_atmega.go (about)

     1  // +build avr,atmega
     2  
     3  package runtime
     4  
     5  import (
     6  	"device/avr"
     7  )
     8  
     9  // Sleep for a given period. The period is defined by the WDT peripheral, and is
    10  // on most chips (at least) 3 bits wide, in powers of two from 16ms to 2s
    11  // (0=16ms, 1=32ms, 2=64ms...). Note that the WDT is not very accurate: it can
    12  // be off by a large margin depending on temperature and supply voltage.
    13  //
    14  // TODO: disable more peripherals etc. to reduce sleep current.
    15  func sleepWDT(period uint8) {
    16  	// Configure WDT
    17  	avr.Asm("cli")
    18  	avr.Asm("wdr")
    19  	// Start timed sequence.
    20  	*avr.WDTCSR |= avr.WDTCSR_WDCE | avr.WDTCSR_WDE
    21  	// Enable WDT and set new timeout
    22  	*avr.WDTCSR = avr.WDTCSR_WDIE | avr.RegValue(period)
    23  	avr.Asm("sei")
    24  
    25  	// Set sleep mode to idle and enable sleep mode.
    26  	// Note: when using something other than idle, the UART won't work
    27  	// correctly. This needs to be fixed, though, so we can truly sleep.
    28  	*avr.SMCR = (0 << 1) | avr.SMCR_SE
    29  
    30  	// go to sleep
    31  	avr.Asm("sleep")
    32  
    33  	// disable sleep
    34  	*avr.SMCR = 0
    35  }