KM3NeT CLB  2.0
KM3NeT CLB v2 Embedded Software
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
lsm303d.c
1 /*
2  * KM3NeT CLB v2 Firmware
3  * ----------------------
4  *
5  * Copyright 2012-2016 KM3NeT Collaboration
6  *
7  * All Rights Reserved.
8  *
9  *
10  * File : lsm303.c
11  * Created : 24 mrt. 2016
12  * Author : Vincent van Beveren
13  */
14 
15 #include "drv/i2c/lsm303d.h"
16 
17 
18 #define _AUTO_INC_REG 0x80
19 #define _REG_TEMP_OUT_L 0x05
20 #define _REG_TEMP_OUT_H 0x06
21 
22 #define _REG_STATUS_M 0x07
23 
24 #define _REG_OUT_X_L_M 0x08
25 #define _REG_OUT_X_H_M 0x09
26 #define _REG_OUT_Y_L_M 0x0A
27 #define _REG_OUT_Y_H_M 0x0B
28 #define _REG_OUT_Z_L_M 0x0C
29 #define _REG_OUT_Z_H_M 0x0D
30 
31 #define _REG_WHO_AM_I 0xF
32 #define _REG_WHO_AM_I_LSM303D_ID 0x49
33 
34 #define _REG_CTRL1 0x20
35 #define _REG_CTRL1_A_ODR_SHIFT 4
36 #define _REG_CTRL1_A_ORD_MASK 0xF0
37 #define _REG_CTRL1_BDU 0x40
38 
39 #define _REG_CTRL2 0x21
40 #define _REG_CTRL2_ABW_SHIFT 6
41 #define _REG_CTRL2_ABW_MASK 0xC0
42 #define _REG_CTRL2_AFS_SHIFT 3
43 #define _REG_CTRL2_AFS_MASK 0x38
44 #define _REG_CTRL2_AST 0x02
45 
46 
47 #define _REG_CTRL5 0x24
48 #define _REG_CTRL5_TEMP_EN 0x80
49 #define _REG_CTRL5_M_RES_HIGH 0x60
50 #define _REG_CTRL5_M_RES_LOW 0x00
51 #define _REG_CTRL5_M_RES_MASK 0x60
52 #define _REG_CTRL5_M_ODR_SHIFT 2
53 #define _REG_CTRL5_M_ORD_MASK 0x1C
54 
55 
56 #define _REG_CTRL6 0x25
57 #define _REG_CTRL6_MFS_SHIFT 5
58 #define _REG_CTRL6_MFS_MASK 0x60
59 
60 
61 #define _REG_CTRL7 0x26
62 #define _REG_CTRL7_AHPM_MASK 0xC0
63 #define _REG_CTRL7_AHPM_SHIFT 6
64 #define _REG_CTRL7_AFDS 0x20
65 #define _REG_CTRL7_T_ONLY 0x10
66 #define _REG_CTRL7_MD_SHIFT 0
67 #define _REG_CTRL7_MLP 0x4
68 #define _REG_CTRL7_MD_MASK 0x3
69 
70 
71 
72 #define _REG_OUT_X_L_A 0x28
73 #define _REG_OUT_X_H_A 0x29
74 #define _REG_OUT_Y_L_A 0x2A
75 #define _REG_OUT_Y_H_A 0x2B
76 #define _REG_OUT_Z_L_A 0x2C
77 #define _REG_OUT_Z_H_A 0x2D
78 
79 
80 
81 bool lsm303DReadTemp(I2C_Device * dev, uint8_t addr, uint16_t * temp)
82 {
83  uint8_t data[2];
84  if (!i2cReadReg(dev, addr, _REG_TEMP_OUT_L | _AUTO_INC_REG , data, sizeof(data)))
85  return errRebase("LSM303");
86 
87  *temp = _lsm303RawDataToI16(data);
88 
89  return true;
90 }
91 
92 bool lsm303DValid(I2C_Device * dev, uint8_t addr, bool * isLSM303D)
93 {
94 
95 
96  uint8_t reg_val;
97  if (!i2cReadReg(dev, addr, _REG_WHO_AM_I, &reg_val, 1)) return errRebase("LSM303");
98  if (reg_val == _REG_WHO_AM_I_LSM303D_ID)
99  *isLSM303D = true;
100  else
101  *isLSM303D = false;
102 
103  return true;
104 }
105 
106 bool lsm303DMagnetRead(I2C_Device * dev, uint8_t addr, Lsm303Axis * result)
107 {
108  uint8_t data[6];
109  if (!i2cReadReg(dev, addr, _REG_OUT_X_L_M | _AUTO_INC_REG, data, sizeof(data)))
110  return false;
111 
112  _lsm303RawDataToAxis(data, result);
113 
114  return true;
115 }
116 
117 
118 bool lsm303DAccelRead(I2C_Device * dev, uint8_t addr, Lsm303Axis * result)
119 {
120  uint8_t data[6];
121  if (!i2cReadReg(dev, addr, _REG_OUT_X_L_A | _AUTO_INC_REG, data, sizeof(data)))
122  return errRebase("LSM303");
123 
124  _lsm303RawDataToAxis(data, result);
125 
126  return true;
127 }
128 
129 
130 bool lsm303DMagnetCfg(I2C_Device * dev, uint8_t addr, Lsm303DMagCfg config)
131 {
132  uint8_t t;
133 
134  t = config.hiRes ? _REG_CTRL5_M_RES_HIGH : _REG_CTRL5_M_RES_LOW;
135  t |= (config.magRate << _REG_CTRL5_M_ODR_SHIFT) & _REG_CTRL5_M_ORD_MASK;
136 
137  if (!_lsm303RmwReg(dev, addr, _REG_CTRL5, t, _REG_CTRL5_M_RES_MASK | _REG_CTRL5_M_ORD_MASK))
138  return errRebase("LSM303");
139 
140  t = (config.magScale << _REG_CTRL6_MFS_SHIFT) & _REG_CTRL6_MFS_MASK;
141 
142  if (!i2cWriteReg(dev, addr, _REG_CTRL6, &t, 1))
143  return errRebase("LSM303");
144 
145  t = (config.magMode << _REG_CTRL7_MD_SHIFT) & _REG_CTRL7_MD_MASK;
146  t |= config.lowPower ? _REG_CTRL7_MLP : 0;
147 
148  if (!_lsm303RmwReg(dev, addr, _REG_CTRL7, t, _REG_CTRL7_MD_MASK | _REG_CTRL7_MLP))
149  return errRebase("LSM303");
150 
151  return true;
152 }
153 
154 bool lsm303DAccelCfg(I2C_Device * dev, uint8_t addr, Lsm303DAccCfg config)
155 {
156  uint8_t t;
157 
158  t = (config.accRate << _REG_CTRL1_A_ODR_SHIFT) & _REG_CTRL1_A_ORD_MASK;
159 
160  if (!_lsm303RmwReg(dev, addr, _REG_CTRL1, t, _REG_CTRL1_A_ORD_MASK))
161  return errRebase("LSM303");
162 
163  t = (config.accAAF << _REG_CTRL2_ABW_SHIFT) & _REG_CTRL2_ABW_MASK;
164  t |= (config.accScale << _REG_CTRL2_AFS_SHIFT) & _REG_CTRL2_AFS_MASK;
165  if (config.selfTest) t |= _REG_CTRL2_AST;
166 
167  if (!i2cWriteReg(dev, addr, _REG_CTRL2, &t, 1))
168  return errRebase("LSM303");
169 
170  t = (config.accHPF << _REG_CTRL7_AHPM_SHIFT) & _REG_CTRL7_AHPM_MASK;
171  if (config.filterAcc) t |= _REG_CTRL7_AFDS;
172 
173  if (!_lsm303RmwReg(dev, addr, _REG_CTRL7, t, _REG_CTRL7_AFDS | _REG_CTRL7_AHPM_MASK))
174  return errRebase("LSM303");
175 
176  return true;
177 }
178 
179 bool lsm303DCfg(I2C_Device * dev, uint8_t addr, Lsm303DCfg config)
180 {
181 
182  uint8_t t;
183 
184  if (config.bdu) t = _REG_CTRL1_BDU; else t = 0;
185 
186  if (!_lsm303RmwReg(dev, addr, _REG_CTRL1, t, _REG_CTRL1_BDU))
187  return errRebase("LSM303");
188 
189 
190  if (config.temp) t = _REG_CTRL5_TEMP_EN; else t = 0;
191 
192  if (!_lsm303RmwReg(dev, addr, _REG_CTRL5, t, _REG_CTRL5_TEMP_EN))
193  return errRebase("LSM303");
194 
195  if (config.tempOnly) t |= _REG_CTRL7_T_ONLY; else t = 0;
196 
197  if (!_lsm303RmwReg(dev, addr, _REG_CTRL7, t, _REG_CTRL7_T_ONLY))
198  return errRebase("LSM303");
199 
200  return true;
201 }
202 
uint16_t accAAF
Anti-alias filter, one of LSM303D_ACCAAF_*.
Definition: lsm303d.h:119
Axis structure for 3D information.
Definition: lsm303.h:31
uint8_t magMode
Magnetic sensor mode selection, LSM303D_MAGMODE_*.
Definition: lsm303d.h:101
uint16_t accScale
Accelerometer scale, one of LSM303D_ACCSCALE_*.
Definition: lsm303d.h:121
bool filterAcc
Filter acceleration data.
Definition: lsm303d.h:123
bool lsm303DMagnetCfg(I2C_Device *dev, uint8_t addr, Lsm303DMagCfg config)
Set the Magnet configuration.
Definition: lsm303d.c:130
bool _lsm303RmwReg(I2C_Device *dev, uint8_t addr, uint8_t reg, uint8_t val, uint8_t mask)
Internal function shared for both LSM303 drivers.
Definition: lsm303.c:22
Generic LSM303D configuration.
Definition: lsm303d.h:82
bool hiRes
High resolution.
Definition: lsm303d.h:103
bool selfTest
Enabled self-test.
Definition: lsm303d.h:122
uint16_t accRate
Accelerometer rate , one of LSM303D_ACCRATE_*.
Definition: lsm303d.h:118
uint8_t magRate
Magnet rate, use one of LSM303D_MAGRATE_*.
Definition: lsm303d.h:100
static uint16_t _lsm303RawDataToI16(uint8_t *data)
Function shared for both LSM303 drivers.
Definition: lsm303.h:41
void _lsm303RawDataToAxis(uint8_t *data, Lsm303Axis *axis)
Internal function shared for both LSM303 drivers.
Definition: lsm303.c:15
Accelerator configuration structure.
Definition: lsm303d.h:117
bool lsm303DAccelRead(I2C_Device *dev, uint8_t addr, Lsm303Axis *result)
Read the accelerometer information.
Definition: lsm303d.c:118
bool tempOnly
!&lt; Temperature sensor (coupled to magnet)
Definition: lsm303d.h:85
Structure defines OpenCores I2C Device.
Definition: dev_i2c.h:55
bool lowPower
Magnet in low power mode.
Definition: lsm303d.h:102
bool temp
!&lt; Block data update
Definition: lsm303d.h:84
Magnet configuration.
Definition: lsm303d.h:98
bool i2cReadReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *rd, int rdLen)
Reads from the I2C device register.
Definition: i2c.c:188
bool i2cWriteReg(I2C_Device *dev, i2cAddr addr, uint8_t regNo, uint8_t *wr, int wrLen)
Writes to the I2C device register.
Definition: i2c.c:247
bool lsm303DValid(I2C_Device *dev, uint8_t addr, bool *isLSM303)
Checks whether or not the LSM303D is valid.
Definition: lsm303d.c:92
bool lsm303DMagnetRead(I2C_Device *dev, uint8_t addr, Lsm303Axis *result)
Read the magnet information.
Definition: lsm303d.c:106
uint16_t accHPF
High-pass filter, one of LSM303D_ACCHPF_*.
Definition: lsm303d.h:120
bool lsm303DAccelCfg(I2C_Device *dev, uint8_t addr, Lsm303DAccCfg config)
Set the accelerometer configuration.
Definition: lsm303d.c:154
static bool errRebase(const char *name)
Rebases the cause of the error message.
Definition: err.h:104
bool lsm303DCfg(I2C_Device *dev, uint8_t addr, Lsm303DCfg config)
Sets the generic device configuration parameters.
Definition: lsm303d.c:179
Driver for the ST LSM303Dx Compass sensor.
uint8_t magScale
Magnet scale, use one of LSM303D_MAGSCALEE_*.
Definition: lsm303d.h:99