Subversion Repositories libLSM9DS1

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 mjames 1
/*
2
  This file is part of the Arduino_LSM9DS1 library.
3
  Copyright (c) 2019 Arduino SA. All rights reserved.
4
 
5
  This library is free software; you can redistribute it and/or
6
  modify it under the terms of the GNU Lesser General Public
7
  License as published by the Free Software Foundation; either
8
  version 2.1 of the License, or (at your option) any later version.
9
 
10
  This library is distributed in the hope that it will be useful,
11
  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
  Lesser General Public License for more details.
14
 
15
  You should have received a copy of the GNU Lesser General Public
16
  License along with this library; if not, write to the Free Software
17
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18
*/
19
 
20
#include "libLSM9DS1/LSM9DS1.h"
21
 
22
#define LSM9DS1_ADDRESS            0x6b
23
 
24
#define LSM9DS1_WHO_AM_I           0x0f
25
#define LSM9DS1_CTRL_REG1_G        0x10
26
#define LSM9DS1_STATUS_REG         0x17
27
#define LSM9DS1_OUT_X_G            0x18
28
#define LSM9DS1_CTRL_REG6_XL       0x20
29
#define LSM9DS1_CTRL_REG8          0x22
30
#define LSM9DS1_OUT_X_XL           0x28
31
 
32
// magnetometer
33
#define LSM9DS1_ADDRESS_M          0x1e
34
 
35
#define LSM9DS1_CTRL_REG1_M        0x20
36
#define LSM9DS1_CTRL_REG2_M        0x21
37
#define LSM9DS1_CTRL_REG3_M        0x22
38
#define LSM9DS1_STATUS_REG_M       0x27
39
#define LSM9DS1_OUT_X_L_M          0x28
40
 
41
LSM9DS1Class::LSM9DS1Class(I2C_HandleTypeDef* i2c) :
42
  continuousMode(false), _i2c(i2c)
43
{
44
}
45
 
46
LSM9DS1Class::~LSM9DS1Class()
47
{
48
}
49
 
50
int LSM9DS1Class::begin()
51
{
52
 
53
  // reset
54
  writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG8, 0x05);
55
  writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG2_M, 0x0c);
56
 
57
  HAL_Delay(10);
58
 
59
 
60
  if (readRegister(LSM9DS1_ADDRESS, LSM9DS1_WHO_AM_I) != 0x68) {
61
    end();
62
 
63
    return 0;
64
  }
65
 
66
  if (readRegister(LSM9DS1_ADDRESS_M, LSM9DS1_WHO_AM_I) != 0x3d) {
67
    end();
68
 
69
    return 0;
70
  }
71
 
72
  writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G, 0x78); // 119 Hz, 2000 dps, 16 Hz BW
73
  writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL, 0x70); // 119 Hz, 4g
74
 
75
  writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG1_M, 0xb4); // Temperature compensation enable, medium performance, 20 Hz
76
  writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG2_M, 0x00); // 4 gauss
77
  writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG3_M, 0x00); // Continuous conversion mode
78
 
79
  return 1;
80
}
81
 
82
void LSM9DS1Class::setContinuousMode() {
83
  // Enable FIFO (see docs https://www.st.com/resource/en/datasheet/DM00103319.pdf)
84
  writeRegister(LSM9DS1_ADDRESS, 0x23, 0x02);
85
  // Set continuous mode
86
  writeRegister(LSM9DS1_ADDRESS, 0x2E, 0xC0);
87
 
88
  continuousMode = true;
89
}
90
 
91
void LSM9DS1Class::setOneShotMode() {
92
  // Disable FIFO (see docs https://www.st.com/resource/en/datasheet/DM00103319.pdf)
93
  writeRegister(LSM9DS1_ADDRESS, 0x23, 0x00);
94
  // Disable continuous mode
95
  writeRegister(LSM9DS1_ADDRESS, 0x2E, 0x00);
96
 
97
  continuousMode = false;
98
}
99
 
100
void LSM9DS1Class::end()
101
{
102
  writeRegister(LSM9DS1_ADDRESS_M, LSM9DS1_CTRL_REG3_M, 0x03);
103
  writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG1_G, 0x00);
104
  writeRegister(LSM9DS1_ADDRESS, LSM9DS1_CTRL_REG6_XL, 0x00);
105
 
106
}
107
 
108
int LSM9DS1Class::readAcceleration(float& x, float& y, float& z)
109
{
110
  int16_t data[3];
111
 
112
  if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_XL, (uint8_t*)data, sizeof(data))) {
113
    x = NAN;
114
    y = NAN;
115
    z = NAN;
116
 
117
    return 0;
118
  }
119
 
120
  x = data[0] * 4.0 / 32768.0;
121
  y = data[1] * 4.0 / 32768.0;
122
  z = data[2] * 4.0 / 32768.0;
123
 
124
  return 1;
125
}
126
 
127
int LSM9DS1Class::accelerationAvailable()
128
{
129
  if (continuousMode) {
130
    // Read FIFO_SRC. If any of the rightmost 8 bits have a value, there is data.
131
    if (readRegister(LSM9DS1_ADDRESS, 0x2F) & 63) {
132
      return 1;
133
    }
134
  } else {
135
    if (readRegister(LSM9DS1_ADDRESS, LSM9DS1_STATUS_REG) & 0x01) {
136
      return 1;
137
    }
138
  }
139
 
140
  return 0;
141
}
142
 
143
float LSM9DS1Class::accelerationSampleRate()
144
{
145
  return 119.0F;
146
}
147
 
148
int LSM9DS1Class::readGyroscope(float& x, float& y, float& z)
149
{
150
  int16_t data[3];
151
 
152
  if (!readRegisters(LSM9DS1_ADDRESS, LSM9DS1_OUT_X_G, (uint8_t*)data, sizeof(data))) {
153
    x = NAN;
154
    y = NAN;
155
    z = NAN;
156
 
157
    return 0;
158
  }
159
 
160
  x = data[0] * 2000.0 / 32768.0;
161
  y = data[1] * 2000.0 / 32768.0;
162
  z = data[2] * 2000.0 / 32768.0;
163
 
164
  return 1;
165
}
166
 
167
int LSM9DS1Class::gyroscopeAvailable()
168
{
169
  if (readRegister(LSM9DS1_ADDRESS, LSM9DS1_STATUS_REG) & 0x02) {
170
    return 1;
171
  }
172
 
173
  return 0;
174
}
175
 
176
float LSM9DS1Class::gyroscopeSampleRate()
177
{
178
  return 119.0F;
179
}
180
 
181
int LSM9DS1Class::readMagneticField(float& x, float& y, float& z)
182
{
183
  int16_t data[3];
184
 
185
  if (!readRegisters(LSM9DS1_ADDRESS_M, LSM9DS1_OUT_X_L_M, (uint8_t*)data, sizeof(data))) {
186
    x = NAN;
187
    y = NAN;
188
    z = NAN;
189
 
190
    return 0;
191
  }
192
 
193
  x = data[0] * 4.0 * 100.0 / 32768.0;
194
  y = data[1] * 4.0 * 100.0 / 32768.0;
195
  z = data[2] * 4.0 * 100.0 / 32768.0;
196
 
197
  return 1;
198
}
199
 
200
int LSM9DS1Class::magneticFieldAvailable()
201
{
202
  if (readRegister(LSM9DS1_ADDRESS_M, LSM9DS1_STATUS_REG_M) & 0x08) {
203
    return 1;
204
  }
205
 
206
  return 0;
207
}
208
 
209
float LSM9DS1Class::magneticFieldSampleRate()
210
{
211
  return 20.0;
212
}
213
 
214
int LSM9DS1Class::readRegister(uint8_t slaveAddress, uint8_t address)
215
{
216
  uint8_t c;
217
  HAL_StatusTypeDef st =  HAL_I2C_Mem_Read(_i2c, slaveAddress<<1, address, 1, &c, 1, 10000);
218
 
219
   return c;
220
}
221
 
222
int LSM9DS1Class::readRegisters(uint8_t slaveAddress, uint8_t address, uint8_t* data, size_t length)
223
{
224
  HAL_StatusTypeDef st =  HAL_I2C_Mem_Read(_i2c, slaveAddress<<1, address, 1, data, length, 10000);
225
  return st == HAL_OK ? 1 : 0;
226
}
227
 
228
int LSM9DS1Class::writeRegister(uint8_t slaveAddress, uint8_t address, uint8_t value)
229
{
230
  uint8_t c= value;
231
  HAL_StatusTypeDef st = HAL_I2C_Mem_Write (_i2c, slaveAddress << 1, address, 1,
232
                                            &c, 1, 10000);
233
 
234
  return st == HAL_OK ? 1 : 0;
235
}
236