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  }