github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/runtime/runtime_atmega.go (about) 1 //go:build avr && (atmega || atmega32u4) 2 3 package runtime 4 5 import ( 6 "device/avr" 7 "machine" 8 ) 9 10 func initUART() { 11 machine.InitSerial() 12 } 13 14 func putchar(c byte) { 15 machine.Serial.WriteByte(c) 16 } 17 18 func getchar() byte { 19 for machine.Serial.Buffered() == 0 { 20 Gosched() 21 } 22 v, _ := machine.Serial.ReadByte() 23 return v 24 } 25 26 func buffered() int { 27 return machine.Serial.Buffered() 28 } 29 30 // Sleep for a given period. The period is defined by the WDT peripheral, and is 31 // on most chips (at least) 3 bits wide, in powers of two from 16ms to 2s 32 // (0=16ms, 1=32ms, 2=64ms...). Note that the WDT is not very accurate: it can 33 // be off by a large margin depending on temperature and supply voltage. 34 // 35 // TODO: disable more peripherals etc. to reduce sleep current. 36 func sleepWDT(period uint8) { 37 // Configure WDT 38 avr.Asm("cli") 39 avr.Asm("wdr") 40 // Start timed sequence. 41 avr.WDTCSR.SetBits(avr.WDTCSR_WDCE | avr.WDTCSR_WDE) 42 // Enable WDT and set new timeout 43 avr.WDTCSR.SetBits(avr.WDTCSR_WDIE | period) 44 avr.Asm("sei") 45 46 // Set sleep mode to idle and enable sleep mode. 47 // Note: when using something other than idle, the UART won't work 48 // correctly. This needs to be fixed, though, so we can truly sleep. 49 avr.SMCR.Set((0 << 1) | avr.SMCR_SE) 50 51 // go to sleep 52 avr.Asm("sleep") 53 54 // disable sleep 55 avr.SMCR.Set(0) 56 }