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