gobot.io/x/gobot/v2@v2.1.0/platforms/dragonboard/dragonboard_adaptor.go (about) 1 package dragonboard 2 3 import ( 4 "fmt" 5 "sync" 6 7 multierror "github.com/hashicorp/go-multierror" 8 "gobot.io/x/gobot/v2" 9 "gobot.io/x/gobot/v2/platforms/adaptors" 10 "gobot.io/x/gobot/v2/system" 11 ) 12 13 const defaultI2cBusNumber = 0 14 15 // Adaptor represents a Gobot Adaptor for a DragonBoard 410c 16 type Adaptor struct { 17 name string 18 sys *system.Accesser 19 mutex sync.Mutex 20 pinMap map[string]int 21 *adaptors.DigitalPinsAdaptor 22 *adaptors.I2cBusAdaptor 23 } 24 25 // Valid pins are the GPIO_A through GPIO_L pins from the 26 // extender (pins 23-34 on header J8), as well as the SoC pins 27 // aka all the other pins, APQ GPIO_0-GPIO_122 and PM_MPP_0-4. 28 var fixedPins = map[string]int{ 29 "GPIO_A": 36, 30 "GPIO_B": 12, 31 "GPIO_C": 13, 32 "GPIO_D": 69, 33 "GPIO_E": 115, 34 "GPIO_F": 507, 35 "GPIO_G": 24, 36 "GPIO_H": 25, 37 "GPIO_I": 35, 38 "GPIO_J": 34, 39 "GPIO_K": 28, 40 "GPIO_L": 33, 41 42 "LED_1": 21, 43 "LED_2": 120, 44 } 45 46 // NewAdaptor creates a DragonBoard 410c Adaptor 47 // 48 // Optional parameters: 49 // 50 // adaptors.WithGpiodAccess(): use character device gpiod driver instead of sysfs 51 // adaptors.WithSpiGpioAccess(sclk, nss, mosi, miso): use GPIO's instead of /dev/spidev#.# 52 func NewAdaptor(opts ...func(adaptors.Optioner)) *Adaptor { 53 sys := system.NewAccesser() 54 c := &Adaptor{ 55 name: gobot.DefaultName("DragonBoard"), 56 sys: sys, 57 } 58 c.DigitalPinsAdaptor = adaptors.NewDigitalPinsAdaptor(sys, c.translateDigitalPin, opts...) 59 c.I2cBusAdaptor = adaptors.NewI2cBusAdaptor(sys, c.validateI2cBusNumber, defaultI2cBusNumber) 60 c.pinMap = fixedPins 61 for i := 0; i < 122; i++ { 62 pin := fmt.Sprintf("GPIO_%d", i) 63 c.pinMap[pin] = i 64 } 65 return c 66 } 67 68 // Name returns the name of the Adaptor 69 func (c *Adaptor) Name() string { return c.name } 70 71 // SetName sets the name of the Adaptor 72 func (c *Adaptor) SetName(n string) { c.name = n } 73 74 // Connect create new connection to board and pins. 75 func (c *Adaptor) Connect() error { 76 c.mutex.Lock() 77 defer c.mutex.Unlock() 78 79 if err := c.I2cBusAdaptor.Connect(); err != nil { 80 return err 81 } 82 83 return c.DigitalPinsAdaptor.Connect() 84 } 85 86 // Finalize closes connection to board and pins 87 func (c *Adaptor) Finalize() error { 88 c.mutex.Lock() 89 defer c.mutex.Unlock() 90 91 err := c.DigitalPinsAdaptor.Finalize() 92 93 if e := c.I2cBusAdaptor.Finalize(); e != nil { 94 err = multierror.Append(err, e) 95 } 96 97 return err 98 } 99 100 func (c *Adaptor) validateI2cBusNumber(busNr int) error { 101 // Valid bus number is [0..1] which corresponds to /dev/i2c-0 through /dev/i2c-1. 102 if (busNr < 0) || (busNr > 1) { 103 return fmt.Errorf("Bus number %d out of range", busNr) 104 } 105 return nil 106 } 107 108 func (c *Adaptor) translateDigitalPin(id string) (string, int, error) { 109 if line, ok := c.pinMap[id]; ok { 110 return "", line, nil 111 } 112 return "", -1, fmt.Errorf("'%s' is not a valid id for a digital pin", id) 113 }