tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/l3gd20/i2c.go (about) 1 package l3gd20 2 3 import ( 4 "encoding/binary" 5 "time" 6 7 "tinygo.org/x/drivers" 8 "tinygo.org/x/drivers/internal/legacy" 9 ) 10 11 const ( 12 fifoLen = 32 * 3 * 2 13 ) 14 15 type DevI2C struct { 16 addr uint8 17 // sensitivity or range. 18 mul int32 19 bus drivers.I2C 20 buf [1]byte 21 // gyro databuf. 22 databuf [6]byte 23 data [3]int32 24 } 25 26 func NewI2C(bus drivers.I2C, addr uint8) *DevI2C { 27 return &DevI2C{ 28 addr: addr, 29 bus: bus, 30 mul: sensMul250, 31 } 32 } 33 34 // Initializes and configures the device. 35 func (d *DevI2C) Configure(cfg Config) error { 36 err := cfg.validate() 37 if err != nil { 38 return err 39 } 40 err = d.Reboot() 41 if err != nil { 42 return err 43 } 44 // Reset then switch to normal mode and enable all three channels. 45 err = d.write8(CTRL_REG1, 0) 46 if err != nil { 47 return err 48 } 49 err = d.write8(CTRL_REG1, reg1NormalBits) 50 if err != nil { 51 return err 52 } 53 // Reset REG2 values to default 54 err = d.write8(CTRL_REG3, 0) 55 if err != nil { 56 return err 57 } 58 59 // Set sensitivity 60 switch cfg.Range { 61 case 1: // debugging range 62 d.mul = 1 63 cfg.Range = Range_2000 64 case Range_250: 65 d.mul = sensMul250 66 case Range_500: 67 d.mul = sensMul500 68 case Range_2000: 69 d.mul = sensMul2000 70 default: 71 return ErrBadRange 72 } 73 err = d.write8(CTRL_REG4, cfg.Range) 74 if err != nil { 75 return err 76 } 77 // Finally verify whomai register and return error if 78 // board is not who it says it is. Some counterfeit boards 79 // have incorrect whomai but can still be used. 80 whoami, err := d.read8(WHOAMI) 81 if err != nil { 82 return err 83 } 84 if whoami != expectedWHOAMI && whoami != expectedWHOAMI_H { 85 return ErrBadIdentity 86 } 87 return nil 88 } 89 90 func (d *DevI2C) Update() error { 91 err := legacy.ReadRegister(d.bus, d.addr, OUT_X_L, d.databuf[:2]) 92 if err != nil { 93 return err 94 } 95 err = legacy.ReadRegister(d.bus, d.addr, OUT_Y_L, d.databuf[2:4]) 96 if err != nil { 97 return err 98 } 99 err = legacy.ReadRegister(d.bus, d.addr, OUT_Z_L, d.databuf[4:6]) 100 if err != nil { 101 return err 102 } 103 x := int16(binary.LittleEndian.Uint16(d.databuf[0:])) 104 y := int16(binary.LittleEndian.Uint16(d.databuf[2:])) 105 z := int16(binary.LittleEndian.Uint16(d.databuf[4:])) 106 d.data[0] = d.mul * int32(x) 107 d.data[1] = d.mul * int32(y) 108 d.data[2] = d.mul * int32(z) 109 return nil 110 } 111 112 // Reboot sets reboot bit in CTRL_REG5 to true and unsets it. 113 func (d *DevI2C) Reboot() error { 114 reg5, err := d.read8(CTRL_REG5) 115 if err != nil { 116 return err 117 } 118 // Write reboot bit and then unset it. 119 err = d.write8(CTRL_REG5, reg5|reg5RebootBit) 120 if err != nil { 121 return err 122 } 123 time.Sleep(50 * time.Microsecond) 124 return d.write8(CTRL_REG5, reg5&^reg5RebootBit) 125 } 126 127 // AngularVelocity returns result in microradians per second. 128 func (d *DevI2C) AngularVelocity() (x, y, z int32) { 129 return d.data[0], d.data[1], d.data[2] 130 } 131 132 // func (d DevI2C) Update(measurement) 133 134 func (d DevI2C) read8(reg uint8) (byte, error) { 135 err := legacy.ReadRegister(d.bus, d.addr, reg, d.buf[:1]) 136 return d.buf[0], err 137 } 138 139 func (d DevI2C) write8(reg uint8, val byte) error { 140 d.buf[0] = val 141 return legacy.WriteRegister(d.bus, d.addr, reg, d.buf[:1]) 142 }