ECE 4760 Final Project
 All Files Functions Variables Enumerations Enumerator Macros
imu.c
Go to the documentation of this file.
1 /*
2 from https://github.com/sparkfun/LSM9DS0_Breakout/blob/master/Libraries/Arduino/SFE_LSM9DS0/SFE_LSM9DS0.cpp
3 This code is beerware; if you see me (or any other SparkFun employee) at the
4 local, and you've found our code helpful, please buy us a round!
5 Distributed as-is; no warranty is given.
6 ******************************************************************************/
7 #include <avr/io.h>
8 #include "i2cmaster.h"
9 #include "imu.h"
10 
11 
12 #define ga (LSM9DS0_G)
13 #define xma (LSM9DS0_XM)
14 
15 
16 #define g_rb(x) (imu_rb(ga,x))
17 #define g_rbs(x,y,z) (imu_rbs(ga,x,y,z))
18 #define g_wb(x,y) (imu_wb(ga,x,y))
19 #define xm_rb(x) (imu_rb(xma,x))
20 #define xm_rbs(x,y,z) (imu_rbs(xma,x,y,z))
21 #define xm_wb(x,y) (imu_wb(xma,x,y))
22 #define multiple(x) (x | 0x80)
23 
24 int16_t readTemp()
25 {
26  uint8_t temp[2]; // We'll read two bytes from the temperature sensor into temp
27  xm_rbs(OUT_TEMP_L_XM, temp, 2); // Read 2 bytes, beginning at OUT_TEMP_L_M
28  return (((int16_t) temp[1] << 12) | temp[0] << 4 ) >> 4; // Temperature is a 12-bit signed integer
29 }
30 
31 
32 uint16_t init_imu(enum gyro_scale gScl, enum accel_scale aScl,enum mag_scale mScl,
33  enum gyro_odr gODR,enum accel_odr aODR,enum mag_odr mODR)
34 {
35 
36  i2c_init();
37  // Store the given scales in class variables. These scale variables
38  // are used throughout to calculate the actual g's, DPS,and Gs's.
39  gScale = gScl;
40  aScale = aScl;
41  mScale = mScl;
42 
43  // Once we have the scale values, we can calculate the resolution
44  // of each sensor. That's what these functions are for. One for each sensor
45  calcgRes(); // Calculate DPS / ADC tick, stored in gRes variable
46  calcmRes(); // Calculate Gs / ADC tick, stored in mRes variable
47  calcaRes(); // Calculate g / ADC tick, stored in aRes variable
48  uint8_t gTest = g_rb(WHO_AM_I_G); // Read the gyro WHO_AM_I
49  uint8_t xmTest = xm_rb(WHO_AM_I_XM); // Read the accel/mag WHO_AM_I
50 
51  if (gTest != 0xD4 || xmTest != 0x49)
52  {
53  while(1);
54  }
55 
56  // Gyro initialization stuff:
57  initGyro(); // This will "turn on" the gyro. Setting up interrupts, etc.
58  setGyroODR(gODR); // Set the gyro output data rate and bandwidth.
59  setGyroScale(gScale); // Set the gyro range
60 
61  // Accelerometer initialization stuff:
62  initAccel(); // "Turn on" all axes of the accel. Set up interrupts, etc.
63  setAccelODR(aODR); // Set the accel data rate.
64  setAccelScale(aScale); // Set the accel range.
65 
66  // Magnetometer initialization stuff:
67  initMag(); // "Turn on" all axes of the mag. Set up interrupts, etc.
68  setMagODR(mODR); // Set the magnetometer output data rate.
69  setMagScale(mScale); // Set the magnetometer's range.
70 
71  // Once everything is initialized, return the WHO_AM_I registers we read:
72  return 0;// (xmTest << 8) | gTest;
73 }
74 
75 void initGyro()
76 {
77  /* CTRL_REG1_G sets output data rate, bandwidth, power-down and enables
78  Bits[7:0]: DR1 DR0 BW1 BW0 PD Zen Xen Yen
79  DR[1:0] - Output data rate selection
80  00=95Hz, 01=190Hz, 10=380Hz, 11=760Hz
81  BW[1:0] - Bandwidth selection (sets cutoff frequency)
82  Value depends on ODR. See datasheet table 21.
83  PD - Power down enable (0=power down mode, 1=normal or sleep mode)
84  Zen, Xen, Yen - Axis enable (o=disabled, 1=enabled) */
85  g_wb(CTRL_REG1_G, 0x0F); // Normal mode, enable all axes
86 
87  /* CTRL_REG2_G sets up the HPF
88  Bits[7:0]: 0 0 HPM1 HPM0 HPCF3 HPCF2 HPCF1 HPCF0
89  HPM[1:0] - High pass filter mode selection
90  00=normal (reset reading HP_RESET_FILTER, 01=ref signal for filtering,
91  10=normal, 11=autoreset on interrupt
92  HPCF[3:0] - High pass filter cutoff frequency
93  Value depends on data rate. See datasheet table 26.
94  */
95  g_wb(CTRL_REG2_G, 0x00); // Normal mode, high cutoff frequency
96 
97  /* CTRL_REG3_G sets up interrupt and DRDY_G pins
98  Bits[7:0]: I1_IINT1 I1_BOOT H_LACTIVE PP_OD I2_DRDY I2_WTM I2_ORUN I2_EMPTY
99  I1_INT1 - Interrupt enable on INT_G pin (0=disable, 1=enable)
100  I1_BOOT - Boot status available on INT_G (0=disable, 1=enable)
101  H_LACTIVE - Interrupt active configuration on INT_G (0:high, 1:low)
102  PP_OD - Push-pull/open-drain (0=push-pull, 1=open-drain)
103  I2_DRDY - Data ready on DRDY_G (0=disable, 1=enable)
104  I2_WTM - FIFO watermark interrupt on DRDY_G (0=disable 1=enable)
105  I2_ORUN - FIFO overrun interrupt on DRDY_G (0=disable 1=enable)
106  I2_EMPTY - FIFO empty interrupt on DRDY_G (0=disable 1=enable) */
107  // Int1 enabled (pp, active low), data read on DRDY_G:
108  g_wb(CTRL_REG3_G, 0x88);
109 
110  /* CTRL_REG4_G sets the scale, update mode
111  Bits[7:0] - BDU BLE FS1 FS0 - ST1 ST0 SIM
112  BDU - Block data update (0=continuous, 1=output not updated until read
113  BLE - Big/little endian (0=data LSB @ lower address, 1=LSB @ higher add)
114  FS[1:0] - Full-scale selection
115  00=245dps, 01=500dps, 10=2000dps, 11=2000dps
116  ST[1:0] - Self-test enable
117  00=disabled, 01=st 0 (x+, y-, z-), 10=undefined, 11=st 1 (x-, y+, z+)
118  SIM - SPI serial interface mode select
119  0=4 wire, 1=3 wire */
120  g_wb(CTRL_REG4_G, 0x00); // Set scale to 245 dps
121 
122  /* CTRL_REG5_G sets up the FIFO, HPF, and INT1
123  Bits[7:0] - BOOT FIFO_EN - HPen INT1_Sel1 INT1_Sel0 Out_Sel1 Out_Sel0
124  BOOT - Reboot memory content (0=normal, 1=reboot)
125  FIFO_EN - FIFO enable (0=disable, 1=enable)
126  HPen - HPF enable (0=disable, 1=enable)
127  INT1_Sel[1:0] - Int 1 selection configuration
128  Out_Sel[1:0] - Out selection configuration */
129  g_wb(CTRL_REG5_G, 0x00);
130 
131 
132 }
133 void assert(char v) {
134  if (!v) {
135  while(1);
136  }
137 
138 }
139 void initAccel()
140 {
141  xm_wb(CTRL_REG0_XM, 0x00);
142  xm_wb(CTRL_REG1_XM,0x57); // 100Hz data rate, x/y/z all enabled
143  xm_wb(CTRL_REG2_XM, 0x00); // Set scale to 2g
144  xm_wb(CTRL_REG3_XM, 0x04);
145 
146  assert(xm_rb(CTRL_REG0_XM)== 0x00);
147  assert(xm_rb(CTRL_REG1_XM)==0x57); // 100Hz data rate)== x/y/z all enabled
148  assert(xm_rb(CTRL_REG2_XM)== 0x00); // Set scale to 2g
149  assert(xm_rb(CTRL_REG3_XM)== 0x04);
150 }
151 
152 void initMag()
153 {
154  /* CTRL_REG5_XM enables temp sensor, sets mag resolution and data rate
155  Bits (7-0): TEMP_EN M_RES1 M_RES0 M_ODR2 M_ODR1 M_ODR0 LIR2 LIR1
156  TEMP_EN - Enable temperature sensor (0=disabled, 1=enabled)
157  M_RES[1:0] - Magnetometer resolution select (0=low, 3=high)
158  M_ODR[2:0] - Magnetometer data rate select
159  000=3.125Hz, 001=6.25Hz, 010=12.5Hz, 011=25Hz, 100=50Hz, 101=100Hz
160  LIR2 - Latch interrupt request on INT2_SRC (cleared by reading INT2_SRC)
161  0=interrupt request not latched, 1=interrupt request latched
162  LIR1 - Latch interrupt request on INT1_SRC (cleared by readging INT1_SRC)
163  0=irq not latched, 1=irq latched */
164  xm_wb(CTRL_REG5_XM, 0x94); // Mag data rate - 100 Hz, enable temperature sensor
165 
166  /* CTRL_REG6_XM sets the magnetometer full-scale
167  Bits (7-0): 0 MFS1 MFS0 0 0 0 0 0
168  MFS[1:0] - Magnetic full-scale selection
169 00:+/-2Gauss, 01:+/-4Gs, 10:+/-8Gs, 11:+/-12Gs */
170  xm_wb(CTRL_REG6_XM, 0x00); // Mag scale to +/- 2GS
171 
172  /* CTRL_REG7_XM sets magnetic sensor mode, low power mode, and filters
173  AHPM1 AHPM0 AFDS 0 0 MLP MD1 MD0
174  AHPM[1:0] - HPF mode selection
175  00=normal (resets reference registers), 01=reference signal for filtering,
176  10=normal, 11=autoreset on interrupt event
177  AFDS - Filtered acceleration data selection
178  0=internal filter bypassed, 1=data from internal filter sent to FIFO
179  MLP - Magnetic data low-power mode
180  0=data rate is set by M_ODR bits in CTRL_REG5
181  1=data rate is set to 3.125Hz
182  MD[1:0] - Magnetic sensor mode selection (default 10)
183  00=continuous-conversion, 01=single-conversion, 10 and 11=power-down */
184  xm_wb(CTRL_REG7_XM, 0x00); // Continuous conversion mode
185 
186  /* CTRL_REG4_XM is used to set interrupt generators on INT2_XM
187  Bits (7-0): P2_TAP P2_INT1 P2_INT2 P2_INTM P2_DRDYA P2_DRDYM P2_Overrun P2_WTM
188  */
189  xm_wb(CTRL_REG4_XM, 0x04); // Magnetometer data ready on INT2_XM (0x08)
190 
191  /* INT_CTRL_REG_M to set push-pull/open drain, and active-low/high
192  Bits[7:0] - XMIEN YMIEN ZMIEN PP_OD IEA IEL 4D MIEN
193  XMIEN, YMIEN, ZMIEN - Enable interrupt recognition on axis for mag data
194  PP_OD - Push-pull/open-drain interrupt configuration (0=push-pull, 1=od)
195  IEA - Interrupt polarity for accel and magneto
196  0=active-low, 1=active-high
197  IEL - Latch interrupt request for accel and magneto
198  0=irq not latched, 1=irq latched
199  4D - 4D enable. 4D detection is enabled when 6D bit in INT_GEN1_REG is set
200  MIEN - Enable interrupt generation for magnetic data
201  0=disable, 1=enable) */
202  xm_wb(INT_CTRL_REG_M, 0x09); // Enable interrupts for mag, active-low, push-pull
203 }
204 
205 void readAccel(int16_t * ax, int16_t * ay, int16_t * az)
206 {
207  uint8_t temp[6]; // We'll read six bytes from the accelerometer into temp
208  xm_rbs(OUT_X_L_A, temp, 6); // Read 6 bytes, beginning at OUT_X_L_A
209  *ax = (temp[1] << 8) | temp[0]; // Store x-axis values into ax
210  *ay = (temp[3] << 8) | temp[2]; // Store y-axis values into ay
211  *az = (temp[5] << 8) | temp[4]; // Store z-axis values into az
212 }
213 
214 void readMag(int16_t * mx, int16_t * my, int16_t * mz)
215 {
216  uint8_t temp[6]; // We'll read six bytes from the mag into temp
217  xm_rbs(OUT_X_L_M, temp, 6); // Read 6 bytes, beginning at OUT_X_L_M
218  *mx = (temp[1] << 8) | temp[0]; // Store x-axis values into mx
219  *my = (temp[3] << 8) | temp[2]; // Store y-axis values into my
220  *mz = (temp[5] << 8) | temp[4]; // Store z-axis values into mz
221 }
222 
223 void readGyro(int16_t * gx, int16_t * gy, int16_t * gz)
224 {
225  uint8_t temp[6]; // We'll read six bytes from the gyro into temp
226  g_rbs(OUT_X_L_G, temp, 6); // Read 6 bytes, beginning at OUT_X_L_G
227  *gx = (temp[1] << 8) | temp[0]; // Store x-axis values into gx
228  *gy = (temp[3] << 8) | temp[2]; // Store y-axis values into gy
229  *gz = (temp[5] << 8) | temp[4]; // Store z-axis values into gz
230 }
231 
232 
233 void read_gyro(float * x, float * y, float * z) {
234  int16_t xd, yd, zd;
235  readGyro(&xd,&yd,&zd);
236  *x = calcGyro(xd);
237  *y = calcGyro(yd);
238  *z = calcGyro(zd);
239 }
240 
241 void read_accel(float * x, float * y, float * z) {
242  int16_t xd, yd, zd;
243  readAccel(&xd,&yd,&zd);
244  *x = calcAccel(xd);
245  *y = calcAccel(yd);
246  *z = calcAccel(zd);
247 }
248 
249 void read_mag(float * x, float * y, float * z) {
250  int16_t xd, yd, zd;
251  readMag(&xd,&yd,&zd);
252  *x = calcMag(xd);
253  *y = calcMag(yd);
254  *z = calcMag(zd);
255 }
256 
257 
258 
259 float calcGyro(int16_t gyro)
260 {
261  // Return the gyro raw reading times our pre-calculated DPS / (ADC tick):
262  return gRes * gyro;
263 }
264 
265 float calcAccel(int16_t accel)
266 {
267  // Return the accel raw reading times our pre-calculated g's / (ADC tick):
268  return aRes * accel;
269 }
270 
271 float calcMag(int16_t mag)
272 {
273  // Return the mag raw reading times our pre-calculated Gs / (ADC tick):
274  return mRes * mag;
275 }
276 
277 void setGyroScale(enum gyro_scale gScl)
278 {
279  // We need to preserve the other bytes in CTRL_REG4_G. So, first read it:
280  uint8_t temp = g_rb(CTRL_REG4_G);
281  // Then mask out the gyro scale bits:
282  temp &= 0xFF^(0x3 << 4);
283  // Then shift in our new scale bits:
284  temp |= gScl << 4;
285  // And write the new register value back into CTRL_REG4_G:
286  g_wb(CTRL_REG4_G, temp);
287 
288  // We've updated the sensor, but we also need to update our class variables
289  // First update gScale:
290  gScale = gScl;
291  // Then calculate a new gRes, which relies on gScale being set correctly:
292  calcgRes();
293 }
294 
295 void setAccelScale(enum accel_scale aScl)
296 {
297  //printf("new scale = %d\n",aScl);
298  // We need to preserve the other bytes in CTRL_REG2_XM. So, first read it:
299  uint8_t temp = xm_rb(CTRL_REG2_XM);
300  // Then mask out the accel scale bits:
301  temp &= 0xFF^(0x3 << 3);
302  // Then shift in our new scale bits:
303  temp |= aScl << 3;
304  // And write the new register value back into CTRL_REG2_XM:
305  xm_wb(CTRL_REG2_XM, temp);
306 
307  // We've updated the sensor, but we also need to update our class variables
308  // First update aScale:
309  aScale = aScl;
310  // Then calculate a new aRes, which relies on aScale being set correctly:
311  calcaRes();
312 }
313 
314 void setMagScale(enum mag_scale mScl)
315 {
316  // We need to preserve the other bytes in CTRL_REG6_XM. So, first read it:
317  uint8_t temp = xm_rb(CTRL_REG6_XM);
318  // Then mask out the mag scale bits:
319  temp &= 0xFF^(0x3 << 5);
320  // Then shift in our new scale bits:
321  temp |= mScl << 5;
322  // And write the new register value back into CTRL_REG6_XM:
323  xm_wb(CTRL_REG6_XM, temp);
324 
325  // We've updated the sensor, but we also need to update our class variables
326  // First update mScale:
327  mScale = mScl;
328  // Then calculate a new mRes, which relies on mScale being set correctly:
329  calcmRes();
330 }
331 
332 void setGyroODR(enum gyro_odr gRate)
333 {
334  // We need to preserve the other bytes in CTRL_REG1_G. So, first read it:
335  uint8_t temp = g_rb(CTRL_REG1_G);
336  // Then mask out the gyro ODR bits:
337  temp &= 0xFF^(0xF << 4);
338  // Then shift in our new ODR bits:
339  temp |= (gRate << 4);
340  // And write the new register value back into CTRL_REG1_G:
341  g_wb(CTRL_REG1_G, temp);
342 }
343 void setAccelODR(enum accel_odr aRate)
344 {
345  // We need to preserve the other bytes in CTRL_REG1_XM. So, first read it:
346  uint8_t temp = xm_rb(CTRL_REG1_XM);
347  // Then mask out the accel ODR bits:
348  temp &= 0xFF^(0xF << 4);
349  // Then shift in our new ODR bits:
350  temp |= (aRate << 4);
351  // And write the new register value back into CTRL_REG1_XM:
352  xm_wb(CTRL_REG1_XM, temp);
353 }
354 void setAccelABW(enum accel_abw abwRate)
355 {
356  // We need to preserve the other bytes in CTRL_REG2_XM. So, first read it:
357  uint8_t temp = xm_rb(CTRL_REG2_XM);
358  // Then mask out the accel ABW bits:
359  temp &= 0xFF^(0x3 << 7);
360  // Then shift in our new ODR bits:
361  temp |= (abwRate << 7);
362  // And write the new register value back into CTRL_REG2_XM:
363  xm_wb(CTRL_REG2_XM, temp);
364 }
365 
366 void setMagODR(enum mag_odr mRate)
367 {
368  // We need to preserve the other bytes in CTRL_REG5_XM. So, first read it:
369  uint8_t temp = xm_rb(CTRL_REG5_XM);
370  // Then mask out the mag ODR bits:
371  temp &= 0xFF^(0x7 << 2);
372  // Then shift in our new ODR bits:
373  temp |= (mRate << 2);
374  // And write the new register value back into CTRL_REG5_XM:
375  xm_wb(CTRL_REG5_XM, temp);
376 }
377 
378 void calcgRes()
379 {
380  // Possible gyro scales (and their register bit settings) are:
381  // 245 DPS (00), 500 DPS (01), 2000 DPS (10). Here's a bit of an algorithm
382  // to calculate DPS/(ADC tick) based on that 2-bit value:
383  switch (gScale)
384  {
385  case G_SCALE_245DPS:
386  gRes = 245.0 / 32768.0;
387  break;
388  case G_SCALE_500DPS:
389  gRes = 500.0 / 32768.0;
390  break;
391  case G_SCALE_2000DPS:
392  gRes = 2000.0 / 32768.0;
393  break;
394  }
395 }
396 
397 void calcaRes()
398 {
399  // Possible accelerometer scales (and their register bit settings) are:
400  // 2 g (000), 4g (001), 6g (010) 8g (011), 16g (100). Here's a bit of an
401  // algorithm to calculate g/(ADC tick) based on that 3-bit value:
402  aRes = aScale == A_SCALE_16G ? 16.0 / 32768.0 :
403  (((float) aScale + 1.0) * 2.0) / 32768.0;
404 }
405 
406 void calcmRes()
407 {
408  // Possible magnetometer scales (and their register bit settings) are:
409  // 2 Gs (00), 4 Gs (01), 8 Gs (10) 12 Gs (11). Here's a bit of an algorithm
410  // to calculate Gs/(ADC tick) based on that 2-bit value:
411  mRes = mScale == M_SCALE_2GS ? 2.0 / 32768.0 :
412  (float) (mScale << 2) / 32768.0;
413 }
414 
415 
416 void imu_wb(uint8_t address, uint8_t subAddress, uint8_t data)
417 {
418  if (address == (0x1D<<1)) {
419  }
420  i2c_start((address)+I2C_WRITE);
421  i2c_write(subAddress);
422  i2c_write(data);
423  i2c_stop();
424 }
425 
426 uint8_t imu_rb(uint8_t address, uint8_t subAddress)
427 {
428  uint8_t data; // `data` will store the register data
429  i2c_start((address)+I2C_WRITE);
430  i2c_write(subAddress); // Put slave register address in Tx buffer
431  i2c_rep_start((address)+I2C_READ);
432  data = i2c_readNak(); // Fill Rx buffer with result
433  i2c_stop();
434  return data; // Return data read from slave register
435 }
436 
437 void imu_rbs(uint8_t address, uint8_t subAddress, uint8_t * dest, uint8_t count)
438 {
439 
440  if (address == (0x1D<<1)&& subAddress == OUT_X_L_A) {
441  }
442  i2c_start((address)+I2C_WRITE);
443 
444  i2c_write(multiple(subAddress));
445 
446  i2c_rep_start((address)+I2C_READ); // Restart the signal
447  uint8_t i = 0;
448 
449  for (i = 0; i < count; i++) {
450  if(i == (count-1)) {
451  dest[i] = i2c_readNak();
452  } else {
453  dest[i] = i2c_readAck();
454  }
455  }
456  i2c_stop();
457 
458 }
float gRes
Definition: imu.h:311
unsigned char i2c_rep_start(unsigned char addr)
Issues a repeated start condition and sends address and transfer direction.
Definition: twimaster.c:128
void setGyroODR(enum gyro_odr gRate)
set the data capture rate of the gyroscope see the enum gyro_odr to see what values this can take...
Definition: imu.c:332
accel_odr
Definition: imu.h:151
Definition: imu.h:17
float calcAccel(int16_t accel)
Definition: imu.c:265
void i2c_stop(void)
Terminates the data transfer and releases the I2C bus.
Definition: twimaster.c:138
#define xm_rbs(x, y, z)
Definition: imu.c:20
gyro_odr
Definition: imu.h:132
unsigned char i2c_readNak(void)
read one byte from the I2C device, read is followed by a stop condition
Definition: twimaster.c:195
void readAccel(int16_t *ax, int16_t *ay, int16_t *az)
Definition: imu.c:205
void readGyro(int16_t *gx, int16_t *gy, int16_t *gz)
Definition: imu.c:223
void setMagScale(enum mag_scale mScl)
see the setGyroScale function
Definition: imu.c:314
void setMagODR(enum mag_odr mRate)
see the setGyroODR function
Definition: imu.c:366
Definition: imu.h:25
unsigned char i2c_start(unsigned char addr)
Issues a start condition and sends address and transfer direction.
Definition: twimaster.c:41
void readMag(int16_t *mx, int16_t *my, int16_t *mz)
Definition: imu.c:214
void initMag()
Definition: imu.c:152
void setGyroScale(enum gyro_scale gScl)
set the scale of the gyroscope see enum gyro_Scale to see what values this can take.
Definition: imu.c:277
float mRes
Definition: imu.h:312
float calcGyro(int16_t gyro)
takes a raw gyro reading and returns the actual value
Definition: imu.c:259
enum gyro_scale gScale
Definition: imu.h:188
void i2c_init(void)
initialize the I2C master interace. Need to be called only once
Definition: twimaster.c:27
void imu_wb(uint8_t address, uint8_t subAddress, uint8_t data)
Writes a byte to the register at the address specified by subAddress.
Definition: imu.c:416
int16_t readTemp()
Returns the temperature in Celcius. Will be 25 degrees, which is the optimal temparture for the gyros...
Definition: imu.c:24
mag_scale
Definition: imu.h:124
void initAccel()
initilize the accelometer, this must be called before using any accelometer fucntions ...
Definition: imu.c:139
mag_odr
Definition: imu.h:177
void setAccelODR(enum accel_odr aRate)
see setGyroODR function
Definition: imu.c:343
void setAccelScale(enum accel_scale aScl)
see the setGyroScle function
Definition: imu.c:295
enum accel_scale aScale
Definition: imu.h:189
enum mag_scale mScale
Definition: imu.h:190
uint8_t imu_rb(uint8_t address, uint8_t subAddress)
Read one byte from the device.
Definition: imu.c:426
#define xm_rb(x)
Definition: imu.c:19
#define xm_wb(x, y)
Definition: imu.c:21
void calcmRes()
sets the mRes variable to the correct resolution of the magenmeter readings
Definition: imu.c:406
Definition: imu.h:52
unsigned char i2c_write(unsigned char data)
Send one byte to I2C device.
Definition: twimaster.c:156
gyro_scale
Definition: imu.h:108
#define multiple(x)
Definition: imu.c:22
unsigned char i2c_readAck(void)
read one byte from the I2C device, request more data from device
Definition: twimaster.c:180
accel_scale
Definition: imu.h:115
void assert(char v)
Definition: imu.c:133
#define g_rbs(x, y, z)
Definition: imu.c:17
#define g_wb(x, y)
Definition: imu.c:18
#define I2C_WRITE
Definition: i2cmaster.h:94
void read_mag(float *x, float *y, float *z)
Reads the magnemeter and calculates the real value from the raw reading.
Definition: imu.c:249
void calcaRes()
sets the aRes variable to the correct resolution of the accelometer readings
Definition: imu.c:397
void initGyro()
initialize the gyroscope, must be done before reading from the gyroscope
Definition: imu.c:75
void calcgRes()
sets the gRes variable to the correct resolution of the gyroscope readings
Definition: imu.c:378
uint16_t init_imu(enum gyro_scale gScl, enum accel_scale aScl, enum mag_scale mScl, enum gyro_odr gODR, enum accel_odr aODR, enum mag_odr mODR)
Initilizes the IMU and enables all 9 axes and set the respective scales and data rates.
Definition: imu.c:32
Definition: imu.h:81
void read_gyro(float *x, float *y, float *z)
Reads the gyroscope and calculates the real value from the raw reading.
Definition: imu.c:233
#define g_rb(x)
Definition: imu.c:16
#define I2C_READ
Definition: i2cmaster.h:91
float aRes
Definition: imu.h:310
accel_abw
Definition: imu.h:167
float calcMag(int16_t mag)
Definition: imu.c:271
void setAccelABW(enum accel_abw abwRate)
Definition: imu.c:354
void imu_rbs(uint8_t address, uint8_t subAddress, uint8_t *dest, uint8_t count)
read multiple bytes from the imu
Definition: imu.c:437
void read_accel(float *x, float *y, float *z)
Reads the accelometer and calculates the real value from the raw reading.
Definition: imu.c:241