20 #define _ACC_ADDR 0x19 // For registers 00 - 3F
21 #define _MAG_ADDR 0x1E // For registers 40 - 6F
23 #define _MASK_VAL(PREFIX, VAL) ( ( PREFIX ## _MASK ) & ( ( VAL ) << ( PREFIX ## _SHIFT ) ) )
26 #define _AUTO_INC_REG 0x80
31 #define _REG_AUX_A 0x07
32 #define _REG_AUX_A_TOR 0x40 // Temperature overrun
33 #define _REG_AUX_A_TDA 0x04 // Temperature data available.
36 #define _REG_TEMP_OUT_L 0x0C
37 #define _REG_TEMP_OUT_H 0x0D
41 #define _REG_WHO_AM_I_A 0x0F
42 #define _REG_WHO_AM_I_A_ID 0x33
45 #define _REG_TEMP_CFG 0x1F
46 #define _REG_TEMP_CFG_DISABLE 0x00
47 #define _REG_TEMP_CFG_ENABLE 0xC0
51 #define _REG_CTRL1 0x20
52 #define _REG_CTRL1_A_ODR_SHIFT 4
53 #define _REG_CTRL1_A_ORD_MASK 0xF0
54 #define _REG_CTRL1_A_LP_EN 0x08
55 #define _REG_CTRL1_A_Z_EN 0x04
56 #define _REG_CTRL1_A_Y_EN 0x02
57 #define _REG_CTRL1_A_X_EN 0x01
58 #define _REG_CTRL1_A_XYZ_EN 0x07
60 #define _REG_CTRL2 0x21
62 #define _REG_CTRL2_A_HPM_SHIFT 6
63 #define _REG_CTRL2_A_HPM_MASK 0xC0
64 #define _REG_CTRL2_A_HPM_NORM_RST26 _MASK_VAL( _REG_CTRL2_A_HPM, 0x0 )
65 #define _REG_CTRL2_A_HPM_REFSIG _MASK_VAL( _REG_CTRL2_A_HPM, 0x1 )
66 #define _REG_CTRL2_A_HPM_NORM _MASK_VAL( _REG_CTRL2_A_HPM, 0x2 )
67 #define _REG_CTRL2_A_HPM_AUTORST _MASK_VAL( _REG_CTRL2_A_HPM, 0x3 )
69 #define _REG_CTRL2_A_HPCF_SHIFT 4
70 #define _REG_CTRL2_A_HPCF_MASK 0x3
71 #define _REG_CTRL2_A_HPCF(V) _MASK_VAL(_REG_CTRL2_A_HPCF, V )
72 #define _REG_CTRL2_A_FDS 0x08
73 #define _REG_CTRL2_A_HPCLICK 0x04
74 #define _REG_CTRL2_A_HPIS2 0x02
75 #define _REG_CTRL2_A_HPIS1 0x01
78 #define _REG_CTRL4_A 0x23
79 #define _REG_CTRL4_A_BDU 0x80
80 #define _REG_CTRL4_A_BLE 0x40
81 #define _REG_CTRL4_A_FS_SHIFT 4
82 #define _REG_CTRL4_A_FS_MASK 0x30
83 #define _REG_CTRL4_A_FS(V) _MASK_VAL(_REG_CTRL4_A_FS, V)
84 #define _REG_CTRL4_A_HR 0x08
85 #define _REG_CTRL4_A_ST_SHIFT 1
86 #define _REG_CTRL4_A_ST_MASK 0x06
87 #define _REG_CTRL4_A_ST(V) _MASK_VAL(_REG_CTRL4_A_ST)
88 #define _REG_CTRL4_SPI_ENABLE 0x01
90 #define _REG_OUT_X_L_A 0x28
91 #define _REG_OUT_X_H_A 0x29
92 #define _REG_OUT_Y_L_A 0x2A
93 #define _REG_OUT_Y_H_A 0x2B
94 #define _REG_OUT_Z_L_A 0x2C
95 #define _REG_OUT_Z_H_A 0x2D
99 #define _REG_WHO_AM_I_M 0x4F
100 #define _REG_WHO_AM_I_M_ID 0x40
102 #define _REG_CFGA_M 0x60
103 #define _REG_CFGA_M_COMP_TEMP_EN 0x80
104 #define _REG_CFGA_M_REBOOT 0x40
105 #define _REG_CFGA_M_SOFT_RST 0x20
106 #define _REG_CFGA_M_LP 0x10
107 #define _REG_CFGA_M_ODR_SHIFT 2
108 #define _REG_CFGA_M_ODR_MASK 0x0C
109 #define _REG_CFGA_M_ODR(V) _MASK_VAL(_REG_CFGA_M_ODR, V)
110 #define _REG_CFGA_M_MD_SHIFT 0
111 #define _REG_CFGA_M_MD_MASK 0x03
112 #define _REG_CFGA_M_MD(V) _MASK_VAL(_REG_CFGA_M_MD, V)
115 #define _REG_CFGB_M 0x61
116 #define _REG_CFGB_M_OFF_CANC_OS 0x10
117 #define _REG_CFGB_M_INT_ON_DATA_OFF 0x08
118 #define _REG_CFGB_M_SET_FREQ 0x04
119 #define _REG_CFGB_M_OFF_CANC 0x02
120 #define _REG_CFGB_M_LPF 0x01
123 #define _REG_CFGC_M 0x62
124 #define _REG_CFGC_M_INT_MAG_PIN 0x40
125 #define _REG_CFGC_M_I2C_DIS 0x20
126 #define _REG_CFGC_M_BDU 0x10
127 #define _REG_CFGC_M_BLE 0x08
128 #define _REG_CFGC_M_SELF_TEST 0x02
129 #define _REG_CFGC_M_INT_MAG 0x01
131 #define _REG_OUT_X_L_M 0x68
132 #define _REG_OUT_X_H_M 0x69
133 #define _REG_OUT_Y_L_M 0x6A
134 #define _REG_OUT_Y_H_M 0x6B
135 #define _REG_OUT_Z_L_M 0x6C
136 #define _REG_OUT_Z_H_M 0x6D
138 bool lsm303AgrHasTemp(
I2C_Device *dev,
bool * hasData)
142 *hasData = t & _REG_AUX_A_TDA ?
true :
false;
154 if (!
i2cReadReg(dev, _ACC_ADDR, _REG_TEMP_OUT_L | _AUTO_INC_REG , data,
sizeof(data)))
166 if (!
i2cReadReg(dev, _MAG_ADDR, _REG_WHO_AM_I_M, ®_m, 1))
return errRebase(
"LSM303AGR");
167 if (!
i2cReadReg(dev, _ACC_ADDR, _REG_WHO_AM_I_A, ®_a, 1))
return errRebase(
"LSM303AGR");
168 if (reg_m == _REG_WHO_AM_I_M_ID)
171 *isLSM303Agr =
false;
179 if (!
i2cReadReg(dev, _MAG_ADDR, _REG_OUT_X_L_M | _AUTO_INC_REG, data,
sizeof(data)))
191 if (!
i2cReadReg(dev, _ACC_ADDR, _REG_OUT_X_L_A | _AUTO_INC_REG, data,
sizeof(data)))
204 t = config.
lp ? _REG_CFGA_M_LP : 0;
205 t|= _REG_CFGA_M_ODR(config.
rate);
206 t|= _REG_CFGA_M_MD(config.
mode);
207 t|= config.
tempCompEn ? _REG_CFGA_M_COMP_TEMP_EN : 0;
208 if (!
i2cWriteReg(dev, _MAG_ADDR, _REG_CFGA_M, &t,
sizeof(t)))
goto err;
210 t = config.
lpf ? _REG_CFGB_M_LPF : 0;
211 t|= config.
offCanc ? _REG_CFGB_M_OFF_CANC | _REG_CFGB_M_OFF_CANC_OS : 0;
212 if (!
i2cWriteReg(dev, _MAG_ADDR, _REG_CFGB_M, &t,
sizeof(t)))
goto err;
214 t = config.
bdu ? _REG_CFGC_M_BDU : 0;
215 if (!
i2cWriteReg(dev, _MAG_ADDR, _REG_CFGC_M, &t,
sizeof(t)))
goto err;
228 t = (config.
rate << _REG_CTRL1_A_ODR_SHIFT) & _REG_CTRL1_A_ORD_MASK;
229 t|= config.
pm == LSM303AGR_ACC_PM_LOW_8BIT ? _REG_CTRL1_A_LP_EN : 0;
230 t|= _REG_CTRL1_A_XYZ_EN;
231 if (!
i2cWriteReg(dev, _ACC_ADDR, _REG_CTRL1, &t, 1))
goto err;
236 t = _REG_CTRL2_A_HPCF(config.
hpcf);
237 t|= config.
fds ? _REG_CTRL2_A_FDS : 0;
238 t|= _REG_CTRL2_A_HPM_NORM;
239 if (!
i2cWriteReg(dev, _ACC_ADDR, _REG_CTRL2, &t, 1))
goto err;
246 t = config.
bdu ? _REG_CTRL4_A_BDU : 0;
247 t|= _REG_CTRL4_A_FS(config.
fs);
248 t|= config.
pm == LSM303AGR_ACC_PM_HIGH_12BIT ? _REG_CTRL4_A_HR : 0;
249 if (!
i2cWriteReg(dev, _ACC_ADDR, _REG_CTRL4_A, &t, 1))
goto err;
255 t = config.
temp ? _REG_TEMP_CFG_ENABLE : _REG_TEMP_CFG_DISABLE;
256 if (!
i2cWriteReg(dev, _ACC_ADDR, _REG_TEMP_CFG, &t,
sizeof(t)))
goto err;
Axis structure for 3D information.
bool tempCompEn
Temperature compensation enabled.
Accelerator configuration structure.
bool lsm303AgrAccCfg(I2C_Device *dev, Lsm303AgrAccCfg config)
Set the accelerometer configuration.
uint16_t hpcf
High-pass filter, one of LSM303AG_ACC_HPCF_*.
static uint16_t _lsm303RawDataToI16(uint8_t *data)
Function shared for both LSM303 drivers.
void _lsm303RawDataToAxis(uint8_t *data, Lsm303Axis *axis)
Internal function shared for both LSM303 drivers.
bool lsm303AgrAccRead(I2C_Device *dev, Lsm303Axis *result)
Read the accelerometer information.
Structure defines OpenCores I2C Device.
uint16_t mode
one of LSM303AGR_MAG_MODE_*
bool lsm303AgrMagCfg(I2C_Device *dev, Lsm303AgrMagCfg config)
Set the Magnet configuration.
bool lsm303AgrValid(I2C_Device *dev, bool *isLSM303Agr)
Checks whether or not the lsm303Agr is valid.
Driver for the ST lsm303Agr Compass sensor, which unlike the name suggests quite incompable to the LS...
#define E_INVSTATE
Generic error: Module is in a state in which.
bool i2cReadReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *rd, int rdLen)
Reads from the I2C device register.
bool i2cWriteReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *wr, int wrLen)
Writes to the I2C device register.
bool lsm303AgrTempRead(I2C_Device *dev, int16_t *result)
Reads the temperature.
bool offCanc
Offset cancellation.
uint16_t rate
One of LSM303AGR_MAG_RATE_*.
uint16_t rate
Accelerometer rate , one of LSM303AG_ACC_RATE_*.
bool temp
Temperature sensor enable.
bool bdu
Block data update.
bool lpf
Enable low-pass filter.
uint16_t fs
Full scale of accelerometer, one of LSM303AGR_ACC_FS_*.
static bool errRebase(const char *name)
Rebases the cause of the error message.
bool fds
Filter data selection.
bool errSet(uint32_t code, const char *error, const char *name)
Sets an error.
#define ERROR(CODE,...)
Expands an error code to an error code with a description (if ERROR_W_DESCR is declared).
bool bdu
Block date update enable.
bool lsm303AgrMagRead(I2C_Device *dev, Lsm303Axis *result)
Read the magnet information.