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  )