github.com/aykevl/tinygo@v0.5.0/src/machine/machine_avr.go (about) 1 // +build avr 2 3 package machine 4 5 import ( 6 "device/avr" 7 ) 8 9 type GPIOMode uint8 10 11 const ( 12 GPIO_INPUT = iota 13 GPIO_OUTPUT 14 ) 15 16 // Set changes the value of the GPIO pin. The pin must be configured as output. 17 func (p GPIO) Set(value bool) { 18 if value { // set bits 19 port, mask := p.PortMaskSet() 20 *port = mask 21 } else { // clear bits 22 port, mask := p.PortMaskClear() 23 *port = mask 24 } 25 } 26 27 // Return the register and mask to enable a given GPIO pin. This can be used to 28 // implement bit-banged drivers. 29 // 30 // Warning: there are no separate pin set/clear registers on the AVR. The 31 // returned mask is only valid as long as no other pin in the same port has been 32 // changed. 33 func (p GPIO) PortMaskSet() (*avr.RegValue, avr.RegValue) { 34 port, mask := p.getPortMask() 35 return port, *port | avr.RegValue(mask) 36 } 37 38 // Return the register and mask to disable a given port. This can be used to 39 // implement bit-banged drivers. 40 // 41 // Warning: there are no separate pin set/clear registers on the AVR. The 42 // returned mask is only valid as long as no other pin in the same port has been 43 // changed. 44 func (p GPIO) PortMaskClear() (*avr.RegValue, avr.RegValue) { 45 port, mask := p.getPortMask() 46 return port, *port &^ avr.RegValue(mask) 47 } 48 49 // InitADC initializes the registers needed for ADC. 50 func InitADC() { 51 // set a2d prescaler so we are inside the desired 50-200 KHz range at 16MHz. 52 *avr.ADCSRA |= (avr.ADCSRA_ADPS2 | avr.ADCSRA_ADPS1 | avr.ADCSRA_ADPS0) 53 54 // enable a2d conversions 55 *avr.ADCSRA |= avr.ADCSRA_ADEN 56 } 57 58 // Configure configures a ADCPin to be able to be used to read data. 59 func (a ADC) Configure() { 60 return // no pin specific setup on AVR machine. 61 } 62 63 // Get returns the current value of a ADC pin, in the range 0..0xffff. The AVR 64 // has an ADC of 10 bits precision so the lower 6 bits will be zero. 65 func (a ADC) Get() uint16 { 66 // set the analog reference (high two bits of ADMUX) and select the 67 // channel (low 4 bits), masked to only turn on one ADC at a time. 68 // set the ADLAR bit (left-adjusted result) to get a value scaled to 16 69 // bits. This has the same effect as shifting the return value left by 6 70 // bits. 71 *avr.ADMUX = avr.RegValue(avr.ADMUX_REFS0 | avr.ADMUX_ADLAR | (a.Pin & 0x07)) 72 73 // start the conversion 74 *avr.ADCSRA |= avr.ADCSRA_ADSC 75 76 // ADSC is cleared when the conversion finishes 77 for ok := true; ok; ok = (*avr.ADCSRA & avr.ADCSRA_ADSC) > 0 { 78 } 79 80 low := uint16(*avr.ADCL) 81 high := uint16(*avr.ADCH) 82 return uint16(low) | uint16(high<<8) 83 } 84 85 // I2C on AVR. 86 type I2C struct { 87 } 88 89 // I2C0 is the only I2C interface on most AVRs. 90 var I2C0 = I2C{} 91 92 // UART 93 var ( 94 // UART0 is the hardware serial port on the AVR. 95 UART0 = UART{Buffer: NewRingBuffer()} 96 )