github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/machine/machine_avrtiny.go (about)

     1  //go:build avrtiny
     2  
     3  package machine
     4  
     5  import (
     6  	"device/avr"
     7  	"runtime/volatile"
     8  	"unsafe"
     9  )
    10  
    11  const deviceName = avr.DEVICE
    12  
    13  const (
    14  	PinInput PinMode = iota
    15  	PinInputPullup
    16  	PinOutput
    17  )
    18  
    19  // Configure sets the pin to input or output.
    20  func (p Pin) Configure(config PinConfig) {
    21  	port, mask := p.getPortMask()
    22  
    23  	if config.Mode == PinOutput {
    24  		// set output bit
    25  		port.DIRSET.Set(mask)
    26  
    27  		// Note: the output state (high or low) is as it was before.
    28  	} else {
    29  		// Configure the pin as an input.
    30  		// First set up the configuration that will be used when it is an input.
    31  		pinctrl := uint8(0)
    32  		if config.Mode == PinInputPullup {
    33  			pinctrl |= avr.PORT_PIN0CTRL_PULLUPEN
    34  		}
    35  		// Find the PINxCTRL register for this pin.
    36  		ctrlAddress := (*volatile.Register8)(unsafe.Add(unsafe.Pointer(&port.PIN0CTRL), p%8))
    37  		ctrlAddress.Set(pinctrl)
    38  
    39  		// Configure the pin as input (if it wasn't an input pin before).
    40  		port.DIRCLR.Set(mask)
    41  	}
    42  }
    43  
    44  // Get returns the current value of a GPIO pin when the pin is configured as an
    45  // input or as an output.
    46  func (p Pin) Get() bool {
    47  	port, mask := p.getPortMask()
    48  	// As noted above, the PINx register is always two registers below the PORTx
    49  	// register, so we can find it simply by subtracting two from the PORTx
    50  	// register address.
    51  	return (port.IN.Get() & mask) > 0
    52  }
    53  
    54  // Set changes the value of the GPIO pin. The pin must be configured as output.
    55  func (p Pin) Set(high bool) {
    56  	port, mask := p.getPortMask()
    57  	if high {
    58  		port.OUTSET.Set(mask)
    59  	} else {
    60  		port.OUTCLR.Set(mask)
    61  	}
    62  }