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 }