gobot.io/x/gobot@v1.16.0/platforms/dragonboard/dragonboard_adaptor.go (about) 1 package dragonboard 2 3 import ( 4 "errors" 5 "fmt" 6 "sync" 7 8 multierror "github.com/hashicorp/go-multierror" 9 "gobot.io/x/gobot" 10 "gobot.io/x/gobot/drivers/i2c" 11 "gobot.io/x/gobot/sysfs" 12 ) 13 14 // Adaptor represents a Gobot Adaptor for a DragonBoard 410c 15 type Adaptor struct { 16 name string 17 digitalPins map[int]*sysfs.DigitalPin 18 pinMap map[string]int 19 i2cBuses [3]i2c.I2cDevice 20 mutex *sync.Mutex 21 } 22 23 var fixedPins = map[string]int{ 24 "GPIO_A": 36, 25 "GPIO_B": 12, 26 "GPIO_C": 13, 27 "GPIO_D": 69, 28 "GPIO_E": 115, 29 "GPIO_F": 507, 30 "GPIO_G": 24, 31 "GPIO_H": 25, 32 "GPIO_I": 35, 33 "GPIO_J": 34, 34 "GPIO_K": 28, 35 "GPIO_L": 33, 36 37 "LED_1": 21, 38 "LED_2": 120, 39 } 40 41 // NewAdaptor creates a DragonBoard 410c Adaptor 42 func NewAdaptor() *Adaptor { 43 c := &Adaptor{ 44 name: gobot.DefaultName("DragonBoard"), 45 mutex: &sync.Mutex{}, 46 } 47 48 c.setPins() 49 return c 50 } 51 52 // Name returns the name of the Adaptor 53 func (c *Adaptor) Name() string { return c.name } 54 55 // SetName sets the name of the Adaptor 56 func (c *Adaptor) SetName(n string) { c.name = n } 57 58 // Connect initializes the board 59 func (c *Adaptor) Connect() (err error) { 60 return 61 } 62 63 // Finalize closes connection to board and pins 64 func (c *Adaptor) Finalize() (err error) { 65 c.mutex.Lock() 66 defer c.mutex.Unlock() 67 68 for _, pin := range c.digitalPins { 69 if pin != nil { 70 if e := pin.Unexport(); e != nil { 71 err = multierror.Append(err, e) 72 } 73 } 74 } 75 for _, bus := range c.i2cBuses { 76 if bus != nil { 77 if e := bus.Close(); e != nil { 78 err = multierror.Append(err, e) 79 } 80 } 81 } 82 return 83 } 84 85 // DigitalPin returns matched digitalPin for specified values 86 func (c *Adaptor) DigitalPin(pin string, dir string) (sysfsPin *sysfs.DigitalPin, err error) { 87 c.mutex.Lock() 88 defer c.mutex.Unlock() 89 90 i, err := c.translatePin(pin) 91 92 if err != nil { 93 return 94 } 95 96 if c.digitalPins[i] == nil { 97 c.digitalPins[i] = sysfs.NewDigitalPin(i) 98 if err = c.digitalPins[i].Export(); err != nil { 99 return 100 } 101 } 102 103 if err = c.digitalPins[i].Direction(dir); err != nil { 104 return 105 } 106 107 return c.digitalPins[i], nil 108 } 109 110 // DigitalRead reads digital value to the specified pin. 111 // Valids pins are the GPIO_A through GPIO_L pins from the 112 // extender (pins 23-34 on header J8), as well as the SoC pins 113 // aka all the other pins, APQ GPIO_0-GPIO_122 and PM_MPP_0-4. 114 func (c *Adaptor) DigitalRead(pin string) (val int, err error) { 115 sysfsPin, err := c.DigitalPin(pin, sysfs.IN) 116 if err != nil { 117 return 118 } 119 return sysfsPin.Read() 120 } 121 122 // DigitalWrite writes digital value to the specified pin. 123 // Valids pins are the GPIO_A through GPIO_L pins from the 124 // extender (pins 23-34 on header J8), as well as the SoC pins 125 // aka all the other pins, APQ GPIO_0-GPIO_122 and PM_MPP_0-4. 126 func (c *Adaptor) DigitalWrite(pin string, val byte) (err error) { 127 sysfsPin, err := c.DigitalPin(pin, sysfs.OUT) 128 if err != nil { 129 return err 130 } 131 return sysfsPin.Write(int(val)) 132 } 133 134 // GetConnection returns a connection to a device on a specified bus. 135 // Valid bus number is [0..1] which corresponds to /dev/i2c-0 through /dev/i2c-1. 136 func (c *Adaptor) GetConnection(address int, bus int) (connection i2c.Connection, err error) { 137 c.mutex.Lock() 138 defer c.mutex.Unlock() 139 140 if (bus < 0) || (bus > 1) { 141 return nil, fmt.Errorf("Bus number %d out of range", bus) 142 } 143 if c.i2cBuses[bus] == nil { 144 c.i2cBuses[bus], err = sysfs.NewI2cDevice(fmt.Sprintf("/dev/i2c-%d", bus)) 145 } 146 return i2c.NewConnection(c.i2cBuses[bus], address), err 147 } 148 149 // GetDefaultBus returns the default i2c bus for this platform 150 func (c *Adaptor) GetDefaultBus() int { 151 return 0 152 } 153 154 func (c *Adaptor) setPins() { 155 c.digitalPins = make(map[int]*sysfs.DigitalPin) 156 c.pinMap = fixedPins 157 for i := 0; i < 122; i++ { 158 pin := fmt.Sprintf("GPIO_%d", i) 159 c.pinMap[pin] = i 160 } 161 } 162 163 func (c *Adaptor) translatePin(pin string) (i int, err error) { 164 if val, ok := c.pinMap[pin]; ok { 165 i = val 166 } else { 167 err = errors.New("Not a valid pin") 168 } 169 return 170 }