GlobLib
HAL and API libraries for MCUs and hardware.
lsm9ds1.c
Go to the documentation of this file.
1 
17 #include "lsm9ds1.h"
18 
19 //From SPI library
20 
21 extern uint16_t SPI_read(uint8_t,uint16_t,uint32_t,uint8_t,uint16_t);
22 extern void SPI_repeatRead(uint8_t,uint16_t,uint32_t,uint8_t,uint16_t,uint16_t*,uint16_t);
23 extern void SPI_write(uint8_t,uint16_t,uint32_t,uint8_t,uint16_t,uint16_t);
24 
25 //From Core library
26 extern void delayms(uint32_t);
27 
28 void lsm9ds1_magSetup(LSM9DS1 *target);
29 void lsm9ds1_gyrSetup(LSM9DS1 *target);
30 void lsm9ds1_accSetup(LSM9DS1 *target);
31 
32 void LSM9DS1_setup(LSM9DS1 *target,uint8_t spiPort,uint16_t gx_port,
33  uint32_t gx_pin,uint16_t m_port, uint32_t m_pin, uint8_t cs_pol){
34 
35  //The chip needs a delay for setup, provide it here
36  delayms(10);
37 
38  target->port = spiPort;
39  target->gx_pin = gx_pin;
40  target->gx_port = gx_port;
41  target->m_pin = m_pin;
42  target->m_port = m_port;
43  target->cs_pol = cs_pol;
44 
45  lsm9ds1_gyrSetup(target);
46  lsm9ds1_accSetup(target);
47  lsm9ds1_magSetup(target);
48 
49  return;
50 }
51 
52 void lsm9ds1_accSetup(LSM9DS1 *target){
53 
54  //Set maximum data rate,
55  SPI_write(target->port,target->gx_port,
56  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG6_XL,
57  0xC0);
58 
60 
61 }
62 
63 void lsm9ds1_gyrSetup(LSM9DS1 *target){
64 
65  //Set maximum data rate and highest low pass filter spec.
66  SPI_write(target->port,target->gx_port,
67  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG1_G,
68  0xC3);
69 
71 
72  //Output data comes after high and low pass filters
73  SPI_write(target->port,target->gx_port,
74  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG2_G,
75  0x02);
76 
77  //High pass filter enable, cutoff = 1Hz (this also depends on the output data rate)
78  SPI_write(target->port,target->gx_port,
79  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG3_G,
80  0x46);
81 
82 }
83 
84 void lsm9ds1_magSetup(LSM9DS1 *target){
85 
86  //Set ultra-high performace, temperature compensation, self test, fast and maximum output data rate
87  SPI_write(target->port,target->m_port,
88  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG1_M,
89  0xFF);
90 
91  //Set default scale
93 
94  //Set continuous conversion
95  SPI_write(target->port,target->m_port,
96  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG3_M,
97  0x00);
98 
99  //Set Z axis ultra high performane and little endian data formate
100  SPI_write(target->port,target->m_port,
101  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG4_M,
102  0x0C);
103  return;
104 }
105 
107 
108  uint8_t regValue;
109  regValue = SPI_read(target->port,target->m_port,
110  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG2_M | 0x80);
111 
112  //Clear existing value
113  regValue &= ~0x60;
114 
115  switch(scale){
116 
117  case LSM9DS1_MAG_4:
118 
119  SPI_write(target->port,target->m_port,
120  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG2_M,
121  regValue);
122  break;
123 
124  case LSM9DS1_MAG_8:
125 
126  SPI_write(target->port,target->m_port,
127  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG2_M,
128  (regValue | 0x20));
129  break;
130 
131  case LSM9DS1_MAG_12:
132 
133  SPI_write(target->port,target->m_port,
134  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG2_M,
135  (regValue | 0x40));
136  break;
137 
138  case LSM9DS1_MAG_16:
139 
140  SPI_write(target->port,target->m_port,
141  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG2_M,
142  (regValue | 0x60));
143  break;
144 
145  default:
146  //Do nothing
147  break;
148  }
149 
150 }
151 
152 
154 
155  uint8_t regValue;
156  regValue = SPI_read(target->port,target->gx_port,
157  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG6_XL | 0x80);
158 
159  //Clear existing value
160  regValue &= ~0x18;
161 
162  switch(scale){
163 
164  case LSM9DS1_ACC_2:
165 
166  SPI_write(target->port,target->gx_port,
167  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG6_XL,
168  regValue);
169  break;
170 
171  case LSM9DS1_ACC_4:
172 
173  SPI_write(target->port,target->gx_port,
174  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG6_XL,
175  (regValue | 0x10));
176  break;
177 
178  case LSM9DS1_ACC_8:
179 
180  SPI_write(target->port,target->gx_port,
181  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG6_XL,
182  (regValue | 0x18));
183  break;
184 
185  case LSM9DS1_ACC_16:
186 
187  SPI_write(target->port,target->gx_port,
188  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG6_XL,
189  (regValue | 0x08));
190  break;
191 
192  default:
193  //Do nothing
194  break;
195  }
196 }
197 
199 
200  uint8_t regValue;
201  regValue = SPI_read(target->port,target->gx_port,
202  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG1_G | 0x80);
203 
204  //Clear existing value
205  regValue &= ~0x18;
206 
207  switch(scale){
208 
209  case LSM9DS1_GYR_245:
210 
211  SPI_write(target->port,target->gx_port,
212  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG1_G,
213  regValue);
214  break;
215 
216  case LSM9DS1_GYR_500:
217 
218  SPI_write(target->port,target->gx_port,
219  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG1_G,
220  (regValue |= 0x08));
221  break;
222 
223  case LSM9DS1_GYR_2000:
224 
225  SPI_write(target->port,target->gx_port,
226  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG1_G,
227  (regValue |= 0x18));
228  break;
229  default:
230  //Do nothing
231  break;
232  }
233 }
234 
235 uint8_t LSM9DS1_getMagScale(LSM9DS1 *target){
236 
237  uint8_t regValue;
238  regValue = SPI_read(target->port,target->m_port,
239  target->m_pin,target->cs_pol,LSM9DS1_CTRL_REG2_M | 0x80);
240 
241  switch(regValue & 0x60){
242 
243  case 0:
244 
245  return LSM9DS1_MAG_4;
246  break;
247 
248  case 0x20:
249 
250  return LSM9DS1_MAG_8;
251  break;
252 
253  case 0x40:
254 
255  return LSM9DS1_MAG_12;
256  break;
257 
258  case 0x60:
259 
260  return LSM9DS1_MAG_16;
261  break;
262  default:
263  break;
264  }
265 
266  return 0;
267 
268 }
269 
270 uint8_t LSM9DS1_getAccScale(LSM9DS1 *target){
271 
272  uint8_t regValue;
273  regValue = SPI_read(target->port,target->gx_port,
274  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG6_XL | 0x80);
275 
276  switch(regValue & 0x18){
277 
278  case 0:
279 
280  return LSM9DS1_ACC_2;
281  break;
282 
283  case 0x08:
284 
285  return LSM9DS1_ACC_16;
286  break;
287 
288  case 0x10:
289 
290  return LSM9DS1_ACC_4;
291  break;
292 
293  case 0x18:
294 
295  return LSM9DS1_ACC_8;
296  break;
297  default:
298  break;
299  }
300 
301  return 0;
302 }
303 
304 uint16_t LSM9DS1_getGyrScale(LSM9DS1 *target){
305 
306  uint8_t regValue;
307  regValue = SPI_read(target->port,target->gx_port,
308  target->gx_pin,target->cs_pol,LSM9DS1_CTRL_REG1_G | 0x80);
309 
310  switch(regValue & 0x18){
311 
312  case 0:
313 
314  return LSM9DS1_GYR_245;
315  break;
316 
317  case 0x08:
318 
319  return LSM9DS1_GYR_500;
320  break;
321 
322  case 0x18:
323 
324  return LSM9DS1_GYR_2000;
325  break;
326  default:
327  break;
328  }
329 
330  return 0;
331 }
332 
333 uint8_t LSM9DS1_magReady(LSM9DS1 *target){
334 
335  uint8_t regValue;
336  regValue = SPI_read(target->port,target->m_port,
337  target->m_pin,target->cs_pol,LSM9DS1_STATUS_REG_M | 0x80);
338 
339  return (regValue & 0x08);
340 }
341 
342 void LSM9DS1_getMag(LSM9DS1 *target,int16_t *data){
343 
344  uint16_t newData[6];
345 
346  //Continuous read of magneto requries first two bits set
347  SPI_repeatRead(target->port,target->m_port,
348  target->m_pin,target->cs_pol,LSM9DS1_OUT_X_L_M | 0xC0,newData,6);
349 
350  data[0] = (newData[1] << 8) | newData[0];
351  data[1] = (newData[3] << 8) | newData[2];
352  data[2] = (newData[5] << 8) | newData[4];
353 }
354 
355 uint8_t LSM9DS1_gyrReady(LSM9DS1 *target){
356 
357  uint8_t regValue;
358  regValue = SPI_read(target->port,target->gx_port,
359  target->gx_pin,target->cs_pol,LSM9DS1_STATUS_REG_0 | 0x80);
360 
361  return (regValue & 0x02);
362 }
363 
364 void LSM9DS1_getGyr(LSM9DS1 *target,int16_t *data){
365 
366  uint16_t newData[6];
367 
368  SPI_repeatRead(target->port,target->gx_port,
369  target->gx_pin,target->cs_pol,LSM9DS1_OUT_X_L_G | 0x80,newData,6);
370 
371  data[0] = (newData[1] << 8) | newData[0];
372  data[1] = (newData[3] << 8) | newData[2];
373  data[2] = (newData[5] << 8) | newData[4];
374  return;
375 }
376 
377 uint8_t LSM9DS1_accReady(LSM9DS1 *target){
378 
379  uint8_t regValue;
380  regValue = SPI_read(target->port,target->gx_port,
381  target->gx_pin,target->cs_pol,LSM9DS1_STATUS_REG_0 | 0x80);
382 
383  return (regValue & 0x01);
384 }
385 
386 void LSM9DS1_getAcc(LSM9DS1 *target,int16_t *data){
387 
388  uint16_t newData[6];
389 
390  SPI_repeatRead(target->port,target->gx_port,
391  target->gx_pin,target->cs_pol,LSM9DS1_OUT_X_L_XL | 0x80,newData,6);
392 
393  data[0] = (newData[1] << 8) | newData[0];
394  data[1] = (newData[3] << 8) | newData[2];
395  data[2] = (newData[5] << 8) | newData[4];
396  return;
397 }
398 
399 uint8_t LSM9DS1_tempReady(LSM9DS1 *target){
400 
401  uint8_t regValue;
402  regValue = SPI_read(target->port,target->gx_port,
403  target->gx_pin,target->cs_pol,LSM9DS1_STATUS_REG_0 | 0x80);
404 
405  return (regValue & 0x04);
406 }
407 
408 float LSM9DS1_getTemp(LSM9DS1 *target){
409 
410  uint16_t newData[2];
411 
412  SPI_repeatRead(target->port,target->gx_port,
413  target->gx_pin,target->cs_pol,LSM9DS1_OUT_TEMP_L | 0x80,newData,2);
414 
415  //Temperature sensitivity 16 bit / Degree, bias = 25 degrees
416  return (((int16_t)((newData[1] << 8) | newData[0])/16.0f) + 25);
417 
418 }
419 
420 uint8_t LSM9DS1_gxWAI(LSM9DS1 *target){
421 
422  return SPI_read(target->port,target->gx_port,
423  target->gx_pin,target->cs_pol,LSM9DS1_WHO_AM_I_M | 0x80);
424 }
425 
426 uint8_t LSM9DS1_mWAI(LSM9DS1 *target){
427 
428  return SPI_read(target->port,target->m_port,
429  target->m_pin,target->cs_pol,LSM9DS1_WHO_AM_I_XG | 0x80);
430 }
431 
432 void LSM9DS1_writeByte(LSM9DS1 *target, uint8_t component, uint8_t address, uint8_t data){
433 
434  if(component == LSM9DS1_M){
435 
436  SPI_write(target->port,target->m_port,
437  target->m_pin,target->cs_pol,address,data);
438  }
439  else{
440 
441  SPI_write(target->port,target->gx_port,
442  target->gx_pin,target->cs_pol,address,data);
443  }
444 }
445 
446 uint16_t LSM9DS1_readByte(LSM9DS1 *target, uint8_t component, uint8_t address){
447 
448  if(component == LSM9DS1_M){
449 
450  return SPI_read(target->port,target->m_port,
451  target->m_pin,target->cs_pol,address | 0x80);
452  }
453  else{
454 
455  return SPI_read(target->port,target->gx_port,
456  target->gx_pin,target->cs_pol,address | 0x80);
457  }
458 }
uint16_t LSM9DS1_getGyrScale(LSM9DS1 *target)
Get the scale of the gyroscope.
Definition: lsm9ds1.c:304
void LSM9DS1_getMag(LSM9DS1 *target, int16_t *data)
Get the latest magnometer readings.
Definition: lsm9ds1.c:342
void LSM9DS1_setAccScale(LSM9DS1 *target, lsm9ds1_accScale scale)
Set the scale of the accelerometer.
Definition: lsm9ds1.c:153
uint32_t m_pin
The pin used for mag SPI chip select.
Definition: lsm9ds1.h:155
lsm9ds1_gyrScale
Available gyroscope ranges.
Definition: lsm9ds1.h:187
uint16_t LSM9DS1_readByte(LSM9DS1 *target, uint8_t component, uint8_t address)
Read a single byte from the device&#39;s register.
Definition: lsm9ds1.c:446
void LSM9DS1_writeByte(LSM9DS1 *target, uint8_t component, uint8_t address, uint8_t data)
Write a single byte to the device&#39;s register.
Definition: lsm9ds1.c:432
float LSM9DS1_getTemp(LSM9DS1 *target)
Get the latest accelerometer readings.
Definition: lsm9ds1.c:408
uint8_t LSM9DS1_gxWAI(LSM9DS1 *target)
Read the value for the gyro/accel who am I register.
Definition: lsm9ds1.c:420
+-2000 degrees / second range
Definition: lsm9ds1.h:191
uint16_t m_port
The port used for mag SPI chip select.
Definition: lsm9ds1.h:156
uint8_t port
The port the device is connected to.
Definition: lsm9ds1.h:152
Data structure containing variables specific to individual slave devices.
Definition: lsm9ds1.h:150
lsm9ds1_accScale
Available accelerometer ranges.
Definition: lsm9ds1.h:175
+-2G range
Definition: lsm9ds1.h:177
uint8_t LSM9DS1_getMagScale(LSM9DS1 *target)
Get the scale of the magnetometer.
Definition: lsm9ds1.c:235
uint8_t LSM9DS1_tempReady(LSM9DS1 *target)
Check if the temperature module has new data available.
Definition: lsm9ds1.c:399
lsm9ds1_magScale
Available magnetometer ranges.
Definition: lsm9ds1.h:163
+-4G range
Definition: lsm9ds1.h:178
uint8_t LSM9DS1_mWAI(LSM9DS1 *target)
Read the value for the magnetometer who am I register.
Definition: lsm9ds1.c:426
+-16 Gauss range
Definition: lsm9ds1.h:168
uint8_t LSM9DS1_gyrReady(LSM9DS1 *target)
Check if the gyroscope has new data available.
Definition: lsm9ds1.c:355
void LSM9DS1_setGyrScale(LSM9DS1 *target, lsm9ds1_gyrScale scale)
Set the scale of the gyroscope.
Definition: lsm9ds1.c:198
+-8 Gauss range
Definition: lsm9ds1.h:166
+-16G range
Definition: lsm9ds1.h:180
+-500 degrees / second range
Definition: lsm9ds1.h:190
#define LSM9DS1_DEFAULT_GYR_SCALE
Default mag range set by LSM9DS1_setup()
Definition: lsm9ds1.h:61
uint8_t cs_pol
The polary of the SPI chip select line.
Definition: lsm9ds1.h:157
uint8_t LSM9DS1_getAccScale(LSM9DS1 *target)
Get the scale of the accelerometer.
Definition: lsm9ds1.c:270
+-245 degrees / second range
Definition: lsm9ds1.h:189
void LSM9DS1_setup(LSM9DS1 *target, uint8_t spiPort, uint16_t gx_port, uint32_t gx_pin, uint16_t m_port, uint32_t m_pin, uint8_t cs_pol)
Initalizes the slave device and populates data structure variable.
Definition: lsm9ds1.c:32
#define LSM9DS1_DEFAULT_MAG_SCALE
Default mag range set by LSM9DS1_setup()
Definition: lsm9ds1.h:60
void LSM9DS1_getAcc(LSM9DS1 *target, int16_t *data)
Get the latest accelerometer readings.
Definition: lsm9ds1.c:386
uint16_t gx_port
The port used for gyro/accel SPI chip select.
Definition: lsm9ds1.h:154
void LSM9DS1_getGyr(LSM9DS1 *target, int16_t *data)
Get the latest gyroscope readings.
Definition: lsm9ds1.c:364
+-12 Gauss range
Definition: lsm9ds1.h:167
Header file for STMicroelectronics LSM9DS1 9DOF IMU.
#define LSM9DS1_DEFAULT_ACC_SCALE
Default mag range set by LSM9DS1_setup()
Definition: lsm9ds1.h:62
uint8_t LSM9DS1_accReady(LSM9DS1 *target)
Check if the accelerometer has new data available.
Definition: lsm9ds1.c:377
uint32_t gx_pin
The pin used for gyro/accel SPI chip select.
Definition: lsm9ds1.h:153
+-4 Gauss range
Definition: lsm9ds1.h:165
uint8_t LSM9DS1_magReady(LSM9DS1 *target)
Check if the magnetometer has new data available.
Definition: lsm9ds1.c:333
#define LSM9DS1_M
Used by read/write functions to select mag.
Definition: lsm9ds1.h:65
+-8G range
Definition: lsm9ds1.h:179
void LSM9DS1_setMagScale(LSM9DS1 *target, lsm9ds1_magScale scale)
Set the scale of the magnetometer.
Definition: lsm9ds1.c:106