tinygo.org/x/drivers@v0.27.1-0.20240509133757-7dbca2a54349/mma8653/mma8653.go (about)

     1  // Package mma8653 provides a driver for the MMA8653 3-axis accelerometer by
     2  // Freescale/NXP.
     3  //
     4  // Datasheet:
     5  // https://www.nxp.com/docs/en/data-sheet/MMA8653FC.pdf
     6  package mma8653 // import "tinygo.org/x/drivers/mma8653"
     7  
     8  import (
     9  	"tinygo.org/x/drivers"
    10  	"tinygo.org/x/drivers/internal/legacy"
    11  )
    12  
    13  // Device wraps an I2C connection to a MMA8653 device.
    14  type Device struct {
    15  	bus         drivers.I2C
    16  	Address     uint16
    17  	sensitivity Sensitivity
    18  }
    19  
    20  // New creates a new MMA8653 connection. The I2C bus must already be
    21  // configured.
    22  //
    23  // This function only creates the Device object, it does not touch the device.
    24  func New(bus drivers.I2C) Device {
    25  	return Device{bus, Address, Sensitivity2G}
    26  }
    27  
    28  // Connected returns whether a MMA8653 has been found.
    29  // It does a "who am I" request and checks the response.
    30  func (d Device) Connected() bool {
    31  	data := []byte{0}
    32  	legacy.ReadRegister(d.bus, uint8(d.Address), WHO_AM_I, data)
    33  	return data[0] == 0x5A
    34  }
    35  
    36  // Configure sets up the device for communication.
    37  func (d *Device) Configure(speed DataRate, sensitivity Sensitivity) error {
    38  	// Set mode to STANDBY to be able to change the sensitivity.
    39  	err := legacy.WriteRegister(d.bus, uint8(d.Address), CTRL_REG1, []uint8{0})
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	// Set sensitivity (2G, 4G, 8G).
    45  	err = legacy.WriteRegister(d.bus, uint8(d.Address), XYZ_DATA_CFG, []uint8{uint8(sensitivity)})
    46  	if err != nil {
    47  		return err
    48  	}
    49  	d.sensitivity = sensitivity
    50  
    51  	// Set mode to ACTIVE and set the data rate.
    52  	err = legacy.WriteRegister(d.bus, uint8(d.Address), CTRL_REG1, []uint8{(uint8(speed) << 3) | 1})
    53  	if err != nil {
    54  		return err
    55  	}
    56  	return nil
    57  }
    58  
    59  // ReadAcceleration reads the current acceleration from the device and returns
    60  // it in µg (micro-gravity). When one of the axes is pointing straight to Earth
    61  // and the sensor is not moving the returned value will be around 1000000 or
    62  // -1000000.
    63  func (d Device) ReadAcceleration() (x int32, y int32, z int32, err error) {
    64  	data := make([]byte, 6)
    65  	err = legacy.ReadRegister(d.bus, uint8(d.Address), OUT_X_MSB, data)
    66  	shift := uint32(8)
    67  	switch d.sensitivity {
    68  	case Sensitivity4G:
    69  		shift = 7
    70  	case Sensitivity8G:
    71  		shift = 6
    72  	}
    73  	x = int32(int16((uint16(data[0])<<8)|uint16(data[1]))) * 15625 >> shift
    74  	y = int32(int16((uint16(data[2])<<8)|uint16(data[3]))) * 15625 >> shift
    75  	z = int32(int16((uint16(data[4])<<8)|uint16(data[5]))) * 15625 >> shift
    76  	return
    77  }