mirror of https://github.com/periph/devices
MPU9250 experimental driver, largely inspired by https://github.com/kriswiner/MPU9250/ (#265)
Provides some basic functionality for initialization, self-test, calibrarion and reading the gyroscope and accelerometer data. Uses SPI interface, I2C is yet to be implemented via the separate transport. Signed-off-by: Eugene Dzhurinsky <jdevelop@gmail.com>pull/1/head
parent
8e1f781a4d
commit
206686751e
@ -0,0 +1,27 @@
|
||||
package accelerometer
|
||||
|
||||
const (
|
||||
ACCEL_FS_SEL_2G = 0
|
||||
ACCEL_FS_SEL_4G = 8
|
||||
ACCEL_FS_SEL_8G = 0x10
|
||||
ACCEL_FS_SEL_16G = 0x18
|
||||
|
||||
ACCEL_FS_SENS_2G = 2.0 / 32768.0
|
||||
ACCEL_FS_SENS_4G = 4.0 / 32768.0
|
||||
ACCEL_FS_SENS_8G = 8.0 / 32768.0
|
||||
ACCEL_FS_SENS_16G = 16.0 / 32768.0
|
||||
)
|
||||
|
||||
func Sensitivity(selector int) float32 {
|
||||
switch selector {
|
||||
case ACCEL_FS_SEL_2G:
|
||||
return ACCEL_FS_SENS_2G
|
||||
case ACCEL_FS_SEL_4G:
|
||||
return ACCEL_FS_SENS_4G
|
||||
case ACCEL_FS_SEL_8G:
|
||||
return ACCEL_FS_SENS_8G
|
||||
case ACCEL_FS_SEL_16G:
|
||||
return ACCEL_FS_SENS_16G
|
||||
}
|
||||
return ACCEL_FS_SENS_2G
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,329 @@
|
||||
package reg
|
||||
|
||||
const (
|
||||
MPU9250_DEFAULT_ADDRESS = 0xD1
|
||||
MPU9250_ALT_DEFAULT_ADDRESS = 0xD2
|
||||
|
||||
MPU9250_SELF_TEST_X_GYRO = 0x00
|
||||
MPU9250_SELF_TEST_Y_GYRO = 0x01
|
||||
MPU9250_SELF_TEST_Z_GYRO = 0x02
|
||||
|
||||
MPU9250_SELF_TEST_X_ACCEL = 0x0D
|
||||
MPU9250_SELF_TEST_Y_ACCEL = 0x0E
|
||||
MPU9250_SELF_TEST_Z_ACCEL = 0x0F
|
||||
|
||||
MPU9250_XG_OFFSET_H = 0x13
|
||||
MPU9250_XG_OFFSET_L = 0x14
|
||||
MPU9250_YG_OFFSET_H = 0x15
|
||||
MPU9250_YG_OFFSET_L = 0x16
|
||||
MPU9250_ZG_OFFSET_H = 0x17
|
||||
MPU9250_ZG_OFFSET_L = 0x18
|
||||
MPU9250_SMPLRT_DIV = 0x19
|
||||
MPU9250_CONFIG = 0x1A
|
||||
MPU9250_GYRO_CONFIG = 0x1B
|
||||
MPU9250_ACCEL_CONFIG = 0x1C
|
||||
MPU9250_ACCEL_CONFIG2 = 0x1D
|
||||
MPU9250_LP_ACCEL_ODR = 0x1E
|
||||
MPU9250_WOM_THR = 0x1F
|
||||
|
||||
MPU9250_FIFO_EN = 0x23
|
||||
MPU9250_I2C_MST_CTRL = 0x24
|
||||
MPU9250_I2C_SLV0_ADDR = 0x25
|
||||
MPU9250_I2C_SLV0_REG = 0x26
|
||||
MPU9250_I2C_SLV0_CTRL = 0x27
|
||||
MPU9250_I2C_SLV1_ADDR = 0x28
|
||||
MPU9250_I2C_SLV1_REG = 0x29
|
||||
MPU9250_I2C_SLV1_CTRL = 0x2A
|
||||
MPU9250_I2C_SLV2_ADDR = 0x2B
|
||||
MPU9250_I2C_SLV2_REG = 0x2C
|
||||
MPU9250_I2C_SLV2_CTRL = 0x2D
|
||||
MPU9250_I2C_SLV3_ADDR = 0x2E
|
||||
MPU9250_I2C_SLV3_REG = 0x2F
|
||||
MPU9250_I2C_SLV3_CTRL = 0x30
|
||||
MPU9250_I2C_SLV4_ADDR = 0x31
|
||||
MPU9250_I2C_SLV4_REG = 0x32
|
||||
MPU9250_I2C_SLV4_DO = 0x33
|
||||
MPU9250_I2C_SLV4_CTRL = 0x34
|
||||
MPU9250_I2C_SLV4_DI = 0x35
|
||||
MPU9250_I2C_MST_STATUS = 0x36
|
||||
MPU9250_INT_PIN_CFG = 0x37
|
||||
MPU9250_INT_ENABLE = 0x38
|
||||
|
||||
MPU9250_INT_STATUS = 0x3A
|
||||
MPU9250_ACCEL_XOUT_H = 0x3B
|
||||
MPU9250_ACCEL_XOUT_L = 0x3C
|
||||
MPU9250_ACCEL_YOUT_H = 0x3D
|
||||
MPU9250_ACCEL_YOUT_L = 0x3E
|
||||
MPU9250_ACCEL_ZOUT_H = 0x3F
|
||||
MPU9250_ACCEL_ZOUT_L = 0x40
|
||||
MPU9250_TEMP_OUT_H = 0x41
|
||||
MPU9250_TEMP_OUT_L = 0x42
|
||||
MPU9250_GYRO_XOUT_H = 0x43
|
||||
MPU9250_GYRO_XOUT_L = 0x44
|
||||
MPU9250_GYRO_YOUT_H = 0x45
|
||||
MPU9250_GYRO_YOUT_L = 0x46
|
||||
MPU9250_GYRO_ZOUT_H = 0x47
|
||||
MPU9250_GYRO_ZOUT_L = 0x48
|
||||
MPU9250_EXT_SENS_DATA_00 = 0x49
|
||||
MPU9250_EXT_SENS_DATA_01 = 0x4A
|
||||
MPU9250_EXT_SENS_DATA_02 = 0x4B
|
||||
MPU9250_EXT_SENS_DATA_03 = 0x4C
|
||||
MPU9250_EXT_SENS_DATA_04 = 0x4D
|
||||
MPU9250_EXT_SENS_DATA_05 = 0x4E
|
||||
MPU9250_EXT_SENS_DATA_06 = 0x4F
|
||||
MPU9250_EXT_SENS_DATA_07 = 0x50
|
||||
MPU9250_EXT_SENS_DATA_08 = 0x51
|
||||
MPU9250_EXT_SENS_DATA_09 = 0x52
|
||||
MPU9250_EXT_SENS_DATA_10 = 0x53
|
||||
MPU9250_EXT_SENS_DATA_11 = 0x54
|
||||
MPU9250_EXT_SENS_DATA_12 = 0x55
|
||||
MPU9250_EXT_SENS_DATA_13 = 0x56
|
||||
MPU9250_EXT_SENS_DATA_14 = 0x57
|
||||
MPU9250_EXT_SENS_DATA_15 = 0x58
|
||||
MPU9250_EXT_SENS_DATA_16 = 0x59
|
||||
MPU9250_EXT_SENS_DATA_17 = 0x5A
|
||||
MPU9250_EXT_SENS_DATA_18 = 0x5B
|
||||
MPU9250_EXT_SENS_DATA_19 = 0x5C
|
||||
MPU9250_EXT_SENS_DATA_20 = 0x5D
|
||||
MPU9250_EXT_SENS_DATA_21 = 0x5E
|
||||
MPU9250_EXT_SENS_DATA_22 = 0x5F
|
||||
MPU9250_EXT_SENS_DATA_23 = 0x60
|
||||
|
||||
MPU9250_I2C_SLV0_DO = 0x63
|
||||
MPU9250_I2C_SLV1_DO = 0x64
|
||||
MPU9250_I2C_SLV2_DO = 0x65
|
||||
MPU9250_I2C_SLV3_DO = 0x66
|
||||
MPU9250_I2C_MST_DELAY_CTRL = 0x67
|
||||
MPU9250_SIGNAL_PATH_RESET = 0x68
|
||||
MPU9250_MOT_DETECT_CTRL = 0x69
|
||||
MPU9250_USER_CTRL = 0x6A
|
||||
MPU9250_PWR_MGMT_1 = 0x6B
|
||||
MPU9250_PWR_MGMT_2 = 0x6C
|
||||
|
||||
MPU9250_FIFO_COUNTH = 0x72
|
||||
MPU9250_FIFO_COUNTL = 0x73
|
||||
MPU9250_FIFO_R_W = 0x74
|
||||
MPU9250_WHO_AM_I = 0x75
|
||||
MPU9250_XA_OFFSET_H = 0x77
|
||||
MPU9250_XA_OFFSET_L = 0x78
|
||||
|
||||
MPU9250_YA_OFFSET_H = 0x7A
|
||||
MPU9250_YA_OFFSET_L = 0x7B
|
||||
|
||||
MPU9250_ZA_OFFSET_H = 0x7D
|
||||
MPU9250_ZA_OFFSET_L = 0x7E
|
||||
|
||||
//reset values
|
||||
WHOAMI_RESET_VAL = 0x71
|
||||
POWER_MANAGMENT_1_RESET_VAL = 0x01
|
||||
DEFAULT_RESET_VALUE = 0x00
|
||||
|
||||
WHOAMI_DEFAULT_VAL = 0x68
|
||||
|
||||
//CONFIG register masks
|
||||
MPU9250_FIFO_MODE_MASK = 0x40
|
||||
MPU9250_EXT_SYNC_SET_MASK = 0x38
|
||||
MPU9250_DLPF_CFG_MASK = 0x07
|
||||
|
||||
//GYRO_CONFIG register masks
|
||||
MPU9250_XGYRO_CTEN_MASK = 0x80
|
||||
MPU9250_YGYRO_CTEN_MASK = 0x40
|
||||
MPU9250_ZGYRO_CTEN_MASK = 0x20
|
||||
MPU9250_GYRO_FS_SEL_MASK = 0x18
|
||||
MPU9250_FCHOICE_B_MASK = 0x03
|
||||
|
||||
MPU9250_GYRO_FULL_SCALE_250DPS = 0
|
||||
MPU9250_GYRO_FULL_SCALE_500DPS = 1
|
||||
MPU9250_GYRO_FULL_SCALE_1000DPS = 2
|
||||
MPU9250_GYRO_FULL_SCALE_2000DPS = 3
|
||||
|
||||
//ACCEL_CONFIG register masks
|
||||
MPU9250_AX_ST_EN_MASK = 0x80
|
||||
MPU9250_AY_ST_EN_MASK = 0x40
|
||||
MPU9250_AZ_ST_EN_MASK = 0x20
|
||||
MPU9250_ACCEL_FS_SEL_MASK = 0x18
|
||||
|
||||
MPU9250_FULL_SCALE_2G = 0
|
||||
MPU9250_FULL_SCALE_4G = 1
|
||||
MPU9250_FULL_SCALE_8G = 2
|
||||
MPU9250_FULL_SCALE_16G = 3
|
||||
|
||||
//ACCEL_CONFIG_2 register masks
|
||||
MPU9250_ACCEL_FCHOICE_B_MASK = 0xC0
|
||||
MPU9250_A_DLPF_CFG_MASK = 0x03
|
||||
|
||||
//LP_ACCEL_ODR register masks
|
||||
MPU9250_LPOSC_CLKSEL_MASK = 0x0F
|
||||
|
||||
//FIFO_EN register masks
|
||||
MPU9250_TEMP_FIFO_EN_MASK = 0x80
|
||||
MPU9250_GYRO_XOUT_MASK = 0x40
|
||||
MPU9250_GYRO_YOUT_MASK = 0x20
|
||||
MPU9250_GYRO_ZOUT_MASK = 0x10
|
||||
MPU9250_ACCEL_MASK = 0x08
|
||||
MPU9250_SLV2_MASK = 0x04
|
||||
MPU9250_SLV1_MASK = 0x02
|
||||
MPU9250_SLV0_MASK = 0x01
|
||||
|
||||
//I2C_MST_CTRL register masks
|
||||
MPU9250_MULT_MST_EN_MASK = 0x80
|
||||
MPU9250_WAIT_FOR_ES_MASK = 0x40
|
||||
MPU9250_SLV_3_FIFO_EN_MASK = 0x20
|
||||
MPU9250_I2C_MST_P_NSR_MASK = 0x10
|
||||
MPU9250_I2C_MST_CLK_MASK = 0x0F
|
||||
|
||||
//I2C_SLV0_ADDR register masks
|
||||
MPU9250_I2C_SLV0_RNW_MASK = 0x80
|
||||
MPU9250_I2C_ID_0_MASK = 0x7F
|
||||
|
||||
//I2C_SLV0_CTRL register masks
|
||||
MPU9250_I2C_SLV0_EN_MASK = 0x80
|
||||
MPU9250_I2C_SLV0_BYTE_SW_MASK = 0x40
|
||||
MPU9250_I2C_SLV0_REG_DIS_MASK = 0x20
|
||||
MPU9250_I2C_SLV0_GRP_MASK = 0x10
|
||||
MPU9250_I2C_SLV0_LENG_MASK = 0x0F
|
||||
|
||||
//I2C_SLV1_ADDR register masks
|
||||
MPU9250_I2C_SLV1_RNW_MASK = 0x80
|
||||
MPU9250_I2C_ID_1_MASK = 0x7F
|
||||
|
||||
//I2C_SLV1_CTRL register masks
|
||||
MPU9250_I2C_SLV1_EN_MASK = 0x80
|
||||
MPU9250_I2C_SLV1_BYTE_SW_MASK = 0x40
|
||||
MPU9250_I2C_SLV1_REG_DIS_MASK = 0x20
|
||||
MPU9250_I2C_SLV1_GRP_MASK = 0x10
|
||||
MPU9250_I2C_SLV1_LENG_MASK = 0x0F
|
||||
|
||||
//I2C_SLV2_ADDR register masks
|
||||
MPU9250_I2C_SLV2_RNW_MASK = 0x80
|
||||
MPU9250_I2C_ID_2_MASK = 0x7F
|
||||
|
||||
//I2C_SLV2_CTRL register masks
|
||||
MPU9250_I2C_SLV2_EN_MASK = 0x80
|
||||
MPU9250_I2C_SLV2_BYTE_SW_MASK = 0x40
|
||||
MPU9250_I2C_SLV2_REG_DIS_MASK = 0x20
|
||||
MPU9250_I2C_SLV2_GRP_MASK = 0x10
|
||||
MPU9250_I2C_SLV2_LENG_MASK = 0x0F
|
||||
|
||||
//I2C_SLV3_ADDR register masks
|
||||
MPU9250_I2C_SLV3_RNW_MASK = 0x80
|
||||
MPU9250_I2C_ID_3_MASK = 0x7F
|
||||
|
||||
//I2C_SLV3_CTRL register masks
|
||||
MPU9250_I2C_SLV3_EN_MASK = 0x80
|
||||
MPU9250_I2C_SLV3_BYTE_SW_MASK = 0x40
|
||||
MPU9250_I2C_SLV3_REG_DIS_MASK = 0x20
|
||||
MPU9250_I2C_SLV3_GRP_MASK = 0x10
|
||||
MPU9250_I2C_SLV3_LENG_MASK = 0x0F
|
||||
|
||||
//I2C_SLV4_ADDR register masks
|
||||
MPU9250_I2C_SLV4_RNW_MASK = 0x80
|
||||
MPU9250_I2C_ID_4_MASK = 0x7F
|
||||
|
||||
//I2C_SLV4_CTRL register masks
|
||||
MPU9250_I2C_SLV4_EN_MASK = 0x80
|
||||
MPU9250_SLV4_DONE_INT_EN_MASK = 0x40
|
||||
MPU9250_I2C_SLV4_REG_DIS_MASK = 0x20
|
||||
MPU9250_I2C_MST_DLY_MASK = 0x1F
|
||||
|
||||
//I2C_MST_STATUS register masks
|
||||
MPU9250_PASS_THROUGH_MASK = 0x80
|
||||
MPU9250_I2C_SLV4_DONE_MASK = 0x40
|
||||
MPU9250_I2C_LOST_ARB_MASK = 0x20
|
||||
MPU9250_I2C_SLV4_NACK_MASK = 0x10
|
||||
MPU9250_I2C_SLV3_NACK_MASK = 0x08
|
||||
MPU9250_I2C_SLV2_NACK_MASK = 0x04
|
||||
MPU9250_I2C_SLV1_NACK_MASK = 0x02
|
||||
MPU9250_I2C_SLV0_NACK_MASK = 0x01
|
||||
|
||||
//INT_PIN_CFG register masks
|
||||
MPU9250_ACTL_MASK = 0x80
|
||||
MPU9250_OPEN_MASK = 0x40
|
||||
MPU9250_LATCH_INT_EN_MASK = 0x20
|
||||
MPU9250_INT_ANYRD_2CLEAR_MASK = 0x10
|
||||
MPU9250_ACTL_FSYNC_MASK = 0x08
|
||||
MPU9250_FSYNC_INT_MODE_EN_MASK = 0x04
|
||||
MPU9250_BYPASS_EN_MASK = 0x02
|
||||
|
||||
//INT_ENABLE register masks
|
||||
MPU9250_WOM_EN_MASK = 0x40
|
||||
MPU9250_FIFO_OFLOW_EN_MASK = 0x10
|
||||
MPU9250_FSYNC_INT_EN_MASK = 0x08
|
||||
MPU9250_RAW_RDY_EN_MASK = 0x01
|
||||
|
||||
//INT_STATUS register masks
|
||||
MPU9250_WOM_INT_MASK = 0x40
|
||||
MPU9250_FIFO_OFLOW_INT_MASK = 0x10
|
||||
MPU9250_FSYNC_INT_MASK = 0x08
|
||||
MPU9250_RAW_DATA_RDY_INT_MASK = 0x01
|
||||
|
||||
//I2C_MST_DELAY_CTRL register masks
|
||||
MPU9250_DELAY_ES_SHADOW_MASK = 0x80
|
||||
MPU9250_I2C_SLV4_DLY_EN_MASK = 0x10
|
||||
MPU9250_I2C_SLV3_DLY_EN_MASK = 0x08
|
||||
MPU9250_I2C_SLV2_DLY_EN_MASK = 0x04
|
||||
MPU9250_I2C_SLV1_DLY_EN_MASK = 0x02
|
||||
MPU9250_I2C_SLV0_DLY_EN_MASK = 0x01
|
||||
|
||||
//SIGNAL_PATH_RESET register masks
|
||||
MPU9250_GYRO_RST_MASK = 0x04
|
||||
MPU9250_ACCEL_RST_MASK = 0x02
|
||||
MPU9250_TEMP_RST_MASK = 0x01
|
||||
|
||||
//MOT_DETECT_CTRL register masks
|
||||
MPU9250_ACCEL_INTEL_EN_MASK = 0x80
|
||||
MPU9250_ACCEL_INTEL_MODE_MASK = 0x40
|
||||
|
||||
//USER_CTRL register masks
|
||||
MPU9250_FIFO_EN_MASK = 0x40
|
||||
MPU9250_I2C_MST_EN_MASK = 0x20
|
||||
MPU9250_I2C_IF_DIS_MASK = 0x10
|
||||
MPU9250_FIFO_RST_MASK = 0x04
|
||||
MPU9250_I2C_MST_RST_MASK = 0x02
|
||||
MPU9250_SIG_COND_RST_MASK = 0x01
|
||||
|
||||
//PWR_MGMT_1 register masks
|
||||
MPU9250_H_RESET_MASK = 0x80
|
||||
MPU9250_SLEEP_MASK = 0x40
|
||||
MPU9250_CYCLE_MASK = 0x20
|
||||
MPU9250_GYRO_STANDBY_CYCLE_MASK = 0x10
|
||||
MPU9250_PD_PTAT_MASK = 0x08
|
||||
MPU9250_CLKSEL_MASK = 0x07
|
||||
|
||||
//PWR_MGMT_2 register masks
|
||||
MPU9250_DISABLE_XA_MASK = 0x20
|
||||
MPU9250_DISABLE_YA_MASK = 0x10
|
||||
MPU9250_DISABLE_ZA_MASK = 0x08
|
||||
MPU9250_DISABLE_XG_MASK = 0x04
|
||||
MPU9250_DISABLE_YG_MASK = 0x02
|
||||
MPU9250_DISABLE_ZG_MASK = 0x01
|
||||
|
||||
MPU9250_DISABLE_XYZA_MASK = 0x38
|
||||
MPU9250_DISABLE_XYZG_MASK = 0x07
|
||||
|
||||
//Magnetometer register maps
|
||||
MPU9250_MAG_ADDRESS = 0x0C
|
||||
|
||||
MPU9250_MAG_WIA = 0x00
|
||||
MPU9250_MAG_INFO = 0x01
|
||||
MPU9250_MAG_ST1 = 0x02
|
||||
MPU9250_MAG_XOUT_L = 0x03
|
||||
MPU9250_MAG_XOUT_H = 0x04
|
||||
MPU9250_MAG_YOUT_L = 0x05
|
||||
MPU9250_MAG_YOUT_H = 0x06
|
||||
MPU9250_MAG_ZOUT_L = 0x07
|
||||
MPU9250_MAG_ZOUT_H = 0x08
|
||||
MPU9250_MAG_ST2 = 0x09
|
||||
MPU9250_MAG_CNTL = 0x0A
|
||||
MPU9250_MAG_RSV = 0x0B //reserved mystery meat
|
||||
MPU9250_MAG_ASTC = 0x0C
|
||||
MPU9250_MAG_TS1 = 0x0D
|
||||
MPU9250_MAG_TS2 = 0x0E
|
||||
MPU9250_MAG_I2CDIS = 0x0F
|
||||
MPU9250_MAG_ASAX = 0x10
|
||||
MPU9250_MAG_ASAY = 0x11
|
||||
MPU9250_MAG_ASAZ = 0x12
|
||||
|
||||
//Magnetometer register masks
|
||||
MPU9250_WIA_MASK = 0x48
|
||||
)
|
||||
@ -0,0 +1,126 @@
|
||||
package mpu9250
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"periph.io/x/periph/conn/gpio"
|
||||
"periph.io/x/periph/conn/physic"
|
||||
"periph.io/x/periph/conn/spi"
|
||||
"periph.io/x/periph/conn/spi/spireg"
|
||||
)
|
||||
|
||||
// DebugF the debug function type.
|
||||
type DebugF = func(string, ...interface{})
|
||||
|
||||
// SpiTransport Encapsulates the SPI transport parameters.
|
||||
type SpiTransport struct {
|
||||
device spi.Conn
|
||||
cs gpio.PinOut
|
||||
debug DebugF
|
||||
}
|
||||
|
||||
// NewSpiTransport Creates the SPI transport using the provided device path and chip select pin reference.
|
||||
func NewSpiTransport(path string, cs gpio.PinOut) (*SpiTransport, error) {
|
||||
dev, err := spireg.Open(path)
|
||||
if err != nil {
|
||||
return nil, wrapf("can't open SPI %v", err)
|
||||
}
|
||||
conn, err := dev.Connect(1*physic.MegaHertz, spi.Mode0, 8)
|
||||
if err != nil {
|
||||
return nil, wrapf("can't initialize SPI %v", err)
|
||||
}
|
||||
return &SpiTransport{device: conn, cs: cs, debug: noop}, nil
|
||||
}
|
||||
|
||||
// EnableDebug Sets the debugging output using the local print function.
|
||||
func (s *SpiTransport) EnableDebug(f DebugF) {
|
||||
s.debug = f
|
||||
}
|
||||
|
||||
func (s *SpiTransport) writeByte(address byte, value byte) error {
|
||||
s.debug("write register %x value %x", address, value)
|
||||
var (
|
||||
buf = [...]byte{address, value}
|
||||
res [2]byte
|
||||
)
|
||||
if err := s.cs.Out(gpio.Low); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.device.Tx(buf[:], res[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.cs.Out(gpio.High); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SpiTransport) writeMagReg(address byte, value byte) error {
|
||||
return s.writeByte(address, value)
|
||||
}
|
||||
|
||||
func (s *SpiTransport) writeMaskedReg(address byte, mask byte, value byte) error {
|
||||
s.debug("write masked %x, mask %x, value %x", address, mask, value)
|
||||
maskedValue := mask & value
|
||||
s.debug("masked value %x", maskedValue)
|
||||
regVal, err := s.readByte(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.debug("current register %x", regVal)
|
||||
regVal = (regVal &^ maskedValue) | maskedValue
|
||||
s.debug("new value %x", regVal)
|
||||
return s.writeByte(address, regVal)
|
||||
}
|
||||
|
||||
func (s *SpiTransport) readMaskedReg(address byte, mask byte) (byte, error) {
|
||||
s.debug("read masked %x, mask %x", address, mask)
|
||||
reg, err := s.readByte(address)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
s.debug("masked value %x", reg)
|
||||
return reg & mask, nil
|
||||
}
|
||||
|
||||
func (s *SpiTransport) readByte(address byte) (byte, error) {
|
||||
s.debug("read register %x", address)
|
||||
var (
|
||||
buf = [...]byte{0x80 | address, 0}
|
||||
res [2]byte
|
||||
)
|
||||
if err := s.cs.Out(gpio.Low); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if err := s.device.Tx(buf[:], res[:]); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
s.debug("register content %x:%x", res[0], res[1])
|
||||
if err := s.cs.Out(gpio.High); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return res[1], nil
|
||||
}
|
||||
|
||||
func (s *SpiTransport) readUint16(address ...byte) (uint16, error) {
|
||||
if len(address) != 2 {
|
||||
return 0, fmt.Errorf("Only 2 bytes per read")
|
||||
}
|
||||
h, err := s.readByte(address[0])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
l, err := s.readByte(address[1])
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return uint16(h)<<8 | uint16(l), nil
|
||||
}
|
||||
|
||||
func (s *SpiTransport) printFunc(msg string, args ...interface{}) {
|
||||
fmt.Printf("SPI: "+msg+"\n", args...)
|
||||
}
|
||||
|
||||
func noop(string, ...interface{}) {}
|
||||
|
||||
var _ Proto = &SpiTransport{}
|
||||
Loading…
Reference in New Issue