gobot.io/x/gobot@v1.16.0/drivers/i2c/drv2605l_driver.go (about) 1 package i2c 2 3 import ( 4 "gobot.io/x/gobot" 5 ) 6 7 // DRV2605Mode - operating mode 8 type DRV2605Mode uint8 9 10 // Operating modes, for use in SetMode() 11 const ( 12 DRV2605ModeIntTrig DRV2605Mode = 0x00 13 DRV2605ModeExtTrigEdge = 0x01 14 DRV2605ModeExtTrigLvl = 0x02 15 DRV2605ModePWMAnalog = 0x03 16 DRV2605ModeAudioVibe = 0x04 17 DRV2605ModeRealtime = 0x05 18 DRV2605ModeDiagnose = 0x06 19 DRV2605ModeAutocal = 0x07 20 ) 21 22 const ( 23 drv2605Address = 0x5A 24 25 drv2605RegStatus = 0x00 26 drv2605RegMode = 0x01 27 28 drv2605Standby = 0x40 29 30 drv2605RegRTPin = 0x02 31 drv2605RegLibrary = 0x03 32 drv2605RegWaveSeq1 = 0x04 33 drv2605RegWaveSeq2 = 0x05 34 drv2605RegWaveSeq3 = 0x06 35 drv2605RegWaveSeq4 = 0x07 36 drv2605RegWaveSeq5 = 0x08 37 drv2605RegWaveSeq6 = 0x09 38 drv2605RegWaveSeq7 = 0x0A 39 drv2605RegWaveSeq8 = 0x0B 40 41 drv2605RegGo = 0x0C 42 drv2605RegOverdrive = 0x0D 43 drv2605RegSustainPos = 0x0E 44 drv2605RegSustainNeg = 0x0F 45 drv2605RegBreak = 0x10 46 drv2605RegAudioCtrl = 0x11 47 drv2605RegAudioMinLevel = 0x12 48 drv2605RegAudioMaxLevel = 0x13 49 drv2605RegAudioMinDrive = 0x14 50 drv2605RegAudioMaxDrive = 0x15 51 drv2605RegRatedV = 0x16 52 drv2605RegClampV = 0x17 53 drv2605RegAutocalComp = 0x18 54 drv2605RegAutocalEmp = 0x19 55 drv2605RegFeedback = 0x1A 56 drv2605RegControl1 = 0x1B 57 drv2605RegControl2 = 0x1C 58 drv2605RegControl3 = 0x1D 59 drv2605RegControl4 = 0x1E 60 drv2605RegVBat = 0x21 61 drv2605RegLRAResoPeriod = 0x22 62 ) 63 64 // DRV2605LDriver is the gobot driver for the TI/Adafruit DRV2605L Haptic Controller 65 // 66 // Device datasheet: http://www.ti.com/lit/ds/symlink/drv2605l.pdf 67 // 68 // Inspired by the Adafruit Python driver by Sean Mealin. 69 // 70 // Basic use: 71 // 72 // haptic := i2c.NewDRV2605Driver(adaptor) 73 // haptic.SetSequence([]byte{1, 13}) 74 // haptic.Go() 75 // 76 type DRV2605LDriver struct { 77 name string 78 connector Connector 79 connection Connection 80 Config 81 } 82 83 // NewDRV2605LDriver creates a new driver for the DRV2605L device. 84 // 85 // Params: 86 // conn Connector - the Adaptor to use with this Driver 87 // 88 // Optional params: 89 // i2c.WithBus(int): bus to use with this driver 90 // i2c.WithAddress(int): address to use with this driver 91 // 92 func NewDRV2605LDriver(conn Connector, options ...func(Config)) *DRV2605LDriver { 93 driver := &DRV2605LDriver{ 94 name: gobot.DefaultName("DRV2605L"), 95 connector: conn, 96 Config: NewConfig(), 97 } 98 99 for _, option := range options { 100 option(driver) 101 } 102 103 return driver 104 } 105 106 // Name returns the name of the device. 107 func (d *DRV2605LDriver) Name() string { 108 return d.name 109 } 110 111 // SetName sets the name of the device. 112 func (d *DRV2605LDriver) SetName(name string) { 113 d.name = name 114 } 115 116 // Connection returns the connection of the device. 117 func (d *DRV2605LDriver) Connection() gobot.Connection { 118 return d.connector.(gobot.Connection) 119 } 120 121 // Start initializes the device. 122 func (d *DRV2605LDriver) Start() (err error) { 123 if err := d.initialize(); err != nil { 124 return err 125 } 126 return nil 127 } 128 129 func (d *DRV2605LDriver) writeByteRegisters(regValPairs []struct{ reg, val uint8 }) (err error) { 130 for _, rv := range regValPairs { 131 if err = d.connection.WriteByteData(rv.reg, rv.val); err != nil { 132 break 133 } 134 } 135 return err 136 } 137 138 func (d *DRV2605LDriver) initialize() (err error) { 139 bus := d.GetBusOrDefault(d.connector.GetDefaultBus()) 140 address := d.GetAddressOrDefault(drv2605Address) 141 142 d.connection, err = d.connector.GetConnection(address, bus) 143 if err != nil { 144 return 145 } 146 147 feedback, err := d.connection.ReadByteData(drv2605RegFeedback) 148 if err != nil { 149 return 150 } 151 152 control, err := d.connection.ReadByteData(drv2605RegControl3) 153 if err != nil { 154 return 155 } 156 157 err = d.writeByteRegisters([]struct{ reg, val uint8 }{ 158 // leave standby, enter "internal trig" mode 159 {drv2605RegMode, 0}, 160 // turn off real-time play 161 {drv2605RegRTPin, 0}, 162 // init wave sequencer with "strong click" 163 {drv2605RegWaveSeq1, 1}, 164 {drv2605RegWaveSeq1, 0}, 165 // no physical parameter tweaks 166 {drv2605RegSustainPos, 0}, 167 {drv2605RegSustainNeg, 0}, 168 {drv2605RegBreak, 0}, 169 // set up ERM open loop 170 {drv2605RegFeedback, feedback & 0x7f}, 171 {drv2605RegControl3, control | 0x20}, 172 }) 173 174 return 175 } 176 177 // SetMode sets the device in one of the eight modes as described in the 178 // datasheet. Defaults to mode 0, internal trig. 179 func (d *DRV2605LDriver) SetMode(newMode DRV2605Mode) (err error) { 180 mode, err := d.connection.ReadByteData(drv2605RegMode) 181 if err != nil { 182 return err 183 } 184 185 // clear mode bits (lower three bits) 186 mode &= 0xf8 187 // set new mode bits 188 mode |= uint8(newMode) 189 190 err = d.connection.WriteByteData(drv2605RegMode, mode) 191 192 return err 193 } 194 195 // SetStandbyMode controls device low power mode 196 func (d *DRV2605LDriver) SetStandbyMode(standby bool) (err error) { 197 modeVal, err := d.connection.ReadByteData(drv2605RegMode) 198 if err != nil { 199 return err 200 } 201 if standby { 202 modeVal |= drv2605Standby 203 } else { 204 modeVal &= 0xFF ^ drv2605Standby 205 } 206 207 err = d.connection.WriteByteData(drv2605RegMode, modeVal) 208 209 return err 210 } 211 212 // SelectLibrary selects which waveform library to play from, 1-7. 213 // See datasheet for more info. 214 func (d *DRV2605LDriver) SelectLibrary(library uint8) (err error) { 215 err = d.connection.WriteByteData(drv2605RegLibrary, library&0x7) 216 return err 217 } 218 219 // GetPauseWaveform returns a special waveform ID used in SetSequence() to encode 220 // pauses between waveforms. Time is specified in tens of milliseconds 221 // ranging from 0ms (delayTime10MS = 0) to 1270ms (delayTime10MS = 127). 222 // Times out of range are clipped to fit. 223 func (d *DRV2605LDriver) GetPauseWaveform(delayTime10MS uint8) (pauseID uint8) { 224 if delayTime10MS > 127 { 225 delayTime10MS = 127 226 } 227 228 return delayTime10MS | 0x80 229 } 230 231 // SetSequence sets the sequence of waveforms to be played by the sequencer, 232 // specified by waveform id as described in the datasheet. 233 // The sequencer can play at most 8 waveforms in sequence, longer 234 // sequences will be truncated. 235 // A waveform id of zero marks the end of the sequence. 236 // Pauses can be encoded using GetPauseWaveform(). 237 func (d *DRV2605LDriver) SetSequence(waveforms []uint8) (err error) { 238 if len(waveforms) < 8 { 239 waveforms = append(waveforms, 0) 240 } 241 if len(waveforms) > 8 { 242 waveforms = waveforms[0:8] 243 } 244 for i, w := range waveforms { 245 if err = d.connection.WriteByteData(uint8(drv2605RegWaveSeq1+i), w); err != nil { 246 return err 247 } 248 } 249 return nil 250 } 251 252 // Go plays the current sequence of waveforms. 253 func (d *DRV2605LDriver) Go() (err error) { 254 err = d.connection.WriteByteData(drv2605RegGo, 1) 255 return err 256 } 257 258 // Halt halts the device. 259 func (d *DRV2605LDriver) Halt() (err error) { 260 if d.connection != nil { 261 // stop playback 262 if err = d.connection.WriteByteData(drv2605RegGo, 0); err != nil { 263 return err 264 } 265 266 // enter standby 267 return d.SetStandbyMode(true) 268 } 269 return 270 }