github.com/usbarmory/tamago@v0.0.0-20240508072735-8612bbe1e454/soc/nxp/gpio/gpio.go (about)

     1  // NXP GPIO support
     2  // https://github.com/usbarmory/tamago
     3  //
     4  // Copyright (c) WithSecure Corporation
     5  // https://foundry.withsecure.com
     6  //
     7  // Use of this source code is governed by the license
     8  // that can be found in the LICENSE file.
     9  
    10  // Package gpio implements helpers for GPIO configuration on NXP SoCs.
    11  //
    12  // This package is only meant to be used with `GOOS=tamago GOARCH=arm` as
    13  // supported by the TamaGo framework for bare metal Go on ARM SoCs, see
    14  // https://github.com/usbarmory/tamago.
    15  package gpio
    16  
    17  import (
    18  	"errors"
    19  	"fmt"
    20  
    21  	"github.com/usbarmory/tamago/internal/reg"
    22  )
    23  
    24  // GPIO registers
    25  const (
    26  	GPIO_DR   = 0x00
    27  	GPIO_GDIR = 0x04
    28  )
    29  
    30  // GPIO controller instance
    31  type GPIO struct {
    32  	// Controller index
    33  	Index int
    34  	// Base register
    35  	Base uint32
    36  	// Clock gate register
    37  	CCGR uint32
    38  	// Clock gate
    39  	CG int
    40  
    41  	clk bool
    42  }
    43  
    44  // Pin instance
    45  type Pin struct {
    46  	num  int
    47  	data uint32
    48  	dir  uint32
    49  }
    50  
    51  // Init initializes a GPIO.
    52  func (hw *GPIO) Init(num int) (gpio *Pin, err error) {
    53  	if hw.Base == 0 || hw.CCGR == 0 {
    54  		return nil, errors.New("invalid GPIO controller instance")
    55  	}
    56  
    57  	if num > 31 {
    58  		return nil, fmt.Errorf("invalid GPIO number %d", num)
    59  	}
    60  
    61  	gpio = &Pin{
    62  		num:  num,
    63  		data: hw.Base + GPIO_DR,
    64  		dir:  hw.Base + GPIO_GDIR,
    65  	}
    66  
    67  	if !hw.clk {
    68  		// enable clock
    69  		reg.SetN(hw.CCGR, hw.CG, 0b11, 0b11)
    70  		hw.clk = true
    71  	}
    72  
    73  	return
    74  }
    75  
    76  // Out configures a GPIO as output.
    77  func (gpio *Pin) Out() {
    78  	reg.Set(gpio.dir, gpio.num)
    79  }
    80  
    81  // In configures a GPIO as input.
    82  func (gpio *Pin) In() {
    83  	reg.Clear(gpio.dir, gpio.num)
    84  }
    85  
    86  // High configures a GPIO signal as high.
    87  func (gpio *Pin) High() {
    88  	reg.Set(gpio.data, gpio.num)
    89  }
    90  
    91  // Low configures a GPIO signal as low.
    92  func (gpio *Pin) Low() {
    93  	reg.Clear(gpio.data, gpio.num)
    94  }
    95  
    96  // Value returns the GPIO signal level.
    97  func (gpio *Pin) Value() (high bool) {
    98  	return reg.Get(gpio.data, gpio.num, 1) == 1
    99  }