Contiki-NG
mpu-9250-sensor.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /*---------------------------------------------------------------------------*/
31 /**
32  * \addtogroup sensortag-cc26xx-mpu
33  * @{
34  *
35  * \file
36  * Driver for the Sensortag Invensense MPU9250 motion processing unit
37  */
38 /*---------------------------------------------------------------------------*/
39 #include "contiki.h"
40 #include "lib/sensors.h"
41 #include "mpu-9250-sensor.h"
42 #include "sys/rtimer.h"
43 #include "sensor-common.h"
44 #include "board-i2c.h"
45 
46 #include "ti-lib.h"
47 
48 #include <stdint.h>
49 #include <string.h>
50 #include <stdio.h>
51 #include <math.h>
52 /*---------------------------------------------------------------------------*/
53 #define DEBUG 0
54 #if DEBUG
55 #define PRINTF(...) printf(__VA_ARGS__)
56 #else
57 #define PRINTF(...)
58 #endif
59 /*---------------------------------------------------------------------------*/
60 /* Sensor I2C address */
61 #define SENSOR_I2C_ADDRESS 0x68
62 #define SENSOR_MAG_I2_ADDRESS 0x0C
63 /*---------------------------------------------------------------------------*/
64 /* Registers */
65 #define SELF_TEST_X_GYRO 0x00 /* R/W */
66 #define SELF_TEST_Y_GYRO 0x01 /* R/W */
67 #define SELF_TEST_Z_GYRO 0x02 /* R/W */
68 #define SELF_TEST_X_ACCEL 0x0D /* R/W */
69 #define SELF_TEST_Z_ACCEL 0x0E /* R/W */
70 #define SELF_TEST_Y_ACCEL 0x0F /* R/W */
71 /*---------------------------------------------------------------------------*/
72 #define XG_OFFSET_H 0x13 /* R/W */
73 #define XG_OFFSET_L 0x14 /* R/W */
74 #define YG_OFFSET_H 0x15 /* R/W */
75 #define YG_OFFSET_L 0x16 /* R/W */
76 #define ZG_OFFSET_H 0x17 /* R/W */
77 #define ZG_OFFSET_L 0x18 /* R/W */
78 /*---------------------------------------------------------------------------*/
79 #define SMPLRT_DIV 0x19 /* R/W */
80 #define CONFIG 0x1A /* R/W */
81 #define GYRO_CONFIG 0x1B /* R/W */
82 #define ACCEL_CONFIG 0x1C /* R/W */
83 #define ACCEL_CONFIG_2 0x1D /* R/W */
84 #define LP_ACCEL_ODR 0x1E /* R/W */
85 #define WOM_THR 0x1F /* R/W */
86 #define FIFO_EN 0x23 /* R/W */
87 /*---------------------------------------------------------------------------*/
88 /*
89  * Registers 0x24 - 0x36 are not applicable to the SensorTag HW configuration
90  * (IC2 Master)
91  */
92 #define INT_PIN_CFG 0x37 /* R/W */
93 #define INT_ENABLE 0x38 /* R/W */
94 #define INT_STATUS 0x3A /* R */
95 #define ACCEL_XOUT_H 0x3B /* R */
96 #define ACCEL_XOUT_L 0x3C /* R */
97 #define ACCEL_YOUT_H 0x3D /* R */
98 #define ACCEL_YOUT_L 0x3E /* R */
99 #define ACCEL_ZOUT_H 0x3F /* R */
100 #define ACCEL_ZOUT_L 0x40 /* R */
101 #define TEMP_OUT_H 0x41 /* R */
102 #define TEMP_OUT_L 0x42 /* R */
103 #define GYRO_XOUT_H 0x43 /* R */
104 #define GYRO_XOUT_L 0x44 /* R */
105 #define GYRO_YOUT_H 0x45 /* R */
106 #define GYRO_YOUT_L 0x46 /* R */
107 #define GYRO_ZOUT_H 0x47 /* R */
108 #define GYRO_ZOUT_L 0x48 /* R */
109 /*---------------------------------------------------------------------------*/
110 /*
111  * Registers 0x49 - 0x60 are not applicable to the SensorTag HW configuration
112  * (external sensor data)
113  *
114  * Registers 0x63 - 0x67 are not applicable to the SensorTag HW configuration
115  * (I2C master)
116  */
117 #define SIGNAL_PATH_RESET 0x68 /* R/W */
118 #define ACCEL_INTEL_CTRL 0x69 /* R/W */
119 #define USER_CTRL 0x6A /* R/W */
120 #define PWR_MGMT_1 0x6B /* R/W */
121 #define PWR_MGMT_2 0x6C /* R/W */
122 #define FIFO_COUNT_H 0x72 /* R/W */
123 #define FIFO_COUNT_L 0x73 /* R/W */
124 #define FIFO_R_W 0x74 /* R/W */
125 #define WHO_AM_I 0x75 /* R/W */
126 /*---------------------------------------------------------------------------*/
127 /* Masks is mpuConfig valiable */
128 #define ACC_CONFIG_MASK 0x38
129 #define GYRO_CONFIG_MASK 0x07
130 /*---------------------------------------------------------------------------*/
131 /* Values PWR_MGMT_1 */
132 #define MPU_SLEEP 0x4F /* Sleep + stop all clocks */
133 #define MPU_WAKE_UP 0x09 /* Disable temp. + intern osc */
134 /*---------------------------------------------------------------------------*/
135 /* Values PWR_MGMT_2 */
136 #define ALL_AXES 0x3F
137 #define GYRO_AXES 0x07
138 #define ACC_AXES 0x38
139 /*---------------------------------------------------------------------------*/
140 /* Data sizes */
141 #define DATA_SIZE 6
142 /*---------------------------------------------------------------------------*/
143 /* Output data rates */
144 #define INV_LPA_0_3125HZ 0
145 #define INV_LPA_0_625HZ 1
146 #define INV_LPA_1_25HZ 2
147 #define INV_LPA_2_5HZ 3
148 #define INV_LPA_5HZ 4
149 #define INV_LPA_10HZ 5
150 #define INV_LPA_20HZ 6
151 #define INV_LPA_40HZ 7
152 #define INV_LPA_80HZ 8
153 #define INV_LPA_160HZ 9
154 #define INV_LPA_320HZ 10
155 #define INV_LPA_640HZ 11
156 #define INV_LPA_STOPPED 255
157 /*---------------------------------------------------------------------------*/
158 /* Bit values */
159 #define BIT_ANY_RD_CLR 0x10
160 #define BIT_RAW_RDY_EN 0x01
161 #define BIT_WOM_EN 0x40
162 #define BIT_LPA_CYCLE 0x20
163 #define BIT_STBY_XA 0x20
164 #define BIT_STBY_YA 0x10
165 #define BIT_STBY_ZA 0x08
166 #define BIT_STBY_XG 0x04
167 #define BIT_STBY_YG 0x02
168 #define BIT_STBY_ZG 0x01
169 #define BIT_STBY_XYZA (BIT_STBY_XA | BIT_STBY_YA | BIT_STBY_ZA)
170 #define BIT_STBY_XYZG (BIT_STBY_XG | BIT_STBY_YG | BIT_STBY_ZG)
171 /*---------------------------------------------------------------------------*/
172 /* User control register */
173 #define BIT_ACTL 0x80
174 #define BIT_LATCH_EN 0x20
175 /*---------------------------------------------------------------------------*/
176 /* INT Pin / Bypass Enable Configuration */
177 #define BIT_AUX_IF_EN 0x20 /* I2C_MST_EN */
178 #define BIT_BYPASS_EN 0x02
179 /*---------------------------------------------------------------------------*/
180 #define ACC_RANGE_INVALID -1
181 
182 #define ACC_RANGE_2G 0
183 #define ACC_RANGE_4G 1
184 #define ACC_RANGE_8G 2
185 #define ACC_RANGE_16G 3
186 
187 #define MPU_AX_GYR_X 2
188 #define MPU_AX_GYR_Y 1
189 #define MPU_AX_GYR_Z 0
190 #define MPU_AX_GYR 0x07
191 
192 #define MPU_AX_ACC_X 5
193 #define MPU_AX_ACC_Y 4
194 #define MPU_AX_ACC_Z 3
195 #define MPU_AX_ACC 0x38
196 
197 #define MPU_AX_MAG 6
198 /*---------------------------------------------------------------------------*/
199 #define MPU_DATA_READY 0x01
200 #define MPU_MOVEMENT 0x40
201 /*---------------------------------------------------------------------------*/
202 /* Sensor selection/deselection */
203 #define SENSOR_SELECT() board_i2c_select(BOARD_I2C_INTERFACE_1, SENSOR_I2C_ADDRESS)
204 #define SENSOR_DESELECT() board_i2c_deselect()
205 /*---------------------------------------------------------------------------*/
206 /* Delay */
207 #define delay_ms(i) (ti_lib_cpu_delay(8000 * (i)))
208 /*---------------------------------------------------------------------------*/
209 static uint8_t mpu_config;
210 static uint8_t acc_range;
211 static uint8_t acc_range_reg;
212 static uint8_t val;
213 static uint8_t interrupt_status;
214 /*---------------------------------------------------------------------------*/
215 #define SENSOR_STATE_DISABLED 0
216 #define SENSOR_STATE_BOOTING 1
217 #define SENSOR_STATE_ENABLED 2
218 
219 static int state = SENSOR_STATE_DISABLED;
220 static int elements = MPU_9250_SENSOR_TYPE_NONE;
221 /*---------------------------------------------------------------------------*/
222 /* 3 16-byte words for all sensor readings */
223 #define SENSOR_DATA_BUF_SIZE 3
224 
225 static uint16_t sensor_value[SENSOR_DATA_BUF_SIZE];
226 /*---------------------------------------------------------------------------*/
227 /*
228  * Wait SENSOR_BOOT_DELAY ticks for the sensor to boot and
229  * SENSOR_STARTUP_DELAY for readings to be ready
230  * Gyro is a little slower than Acc
231  */
232 #define SENSOR_BOOT_DELAY 8
233 #define SENSOR_STARTUP_DELAY 5
234 
235 static struct ctimer startup_timer;
236 /*---------------------------------------------------------------------------*/
237 /* Wait for the MPU to have data ready */
238 rtimer_clock_t t0;
239 
240 /*
241  * Wait timeout in rtimer ticks. This is just a random low number, since the
242  * first time we read the sensor status, it should be ready to return data
243  */
244 #define READING_WAIT_TIMEOUT 10
245 /*---------------------------------------------------------------------------*/
246 /**
247  * \brief Place the MPU in low power mode
248  */
249 static void
251 {
252  SENSOR_SELECT();
253 
254  val = ALL_AXES;
255  sensor_common_write_reg(PWR_MGMT_2, &val, 1);
256 
257  val = MPU_SLEEP;
258  sensor_common_write_reg(PWR_MGMT_1, &val, 1);
259  SENSOR_DESELECT();
260 }
261 /*---------------------------------------------------------------------------*/
262 /**
263  * \brief Exit low power mode
264  */
265 static void
267 {
268  SENSOR_SELECT();
269  val = MPU_WAKE_UP;
270  sensor_common_write_reg(PWR_MGMT_1, &val, 1);
271 
272  /* All axis initially disabled */
273  val = ALL_AXES;
274  sensor_common_write_reg(PWR_MGMT_2, &val, 1);
275  mpu_config = 0;
276 
277  /* Restore the range */
278  sensor_common_write_reg(ACCEL_CONFIG, &acc_range_reg, 1);
279 
280  /* Clear interrupts */
281  sensor_common_read_reg(INT_STATUS, &val, 1);
282  SENSOR_DESELECT();
283 }
284 /*---------------------------------------------------------------------------*/
285 /**
286  * \brief Select gyro and accelerometer axes
287  */
288 static void
290 {
291  val = ~mpu_config;
292  SENSOR_SELECT();
293  sensor_common_write_reg(PWR_MGMT_2, &val, 1);
294  SENSOR_DESELECT();
295 }
296 /*---------------------------------------------------------------------------*/
297 static void
298 convert_to_le(uint8_t *data, uint8_t len)
299 {
300  int i;
301  for(i = 0; i < len; i += 2) {
302  uint8_t tmp;
303  tmp = data[i];
304  data[i] = data[i + 1];
305  data[i + 1] = tmp;
306  }
307 }
308 /*---------------------------------------------------------------------------*/
309 /**
310  * \brief Set the range of the accelerometer
311  * \param new_range: ACC_RANGE_2G, ACC_RANGE_4G, ACC_RANGE_8G, ACC_RANGE_16G
312  * \return true if the write to the sensor succeeded
313  */
314 static bool
315 acc_set_range(uint8_t new_range)
316 {
317  bool success;
318 
319  if(new_range == acc_range) {
320  return true;
321  }
322 
323  success = false;
324 
325  acc_range_reg = (new_range << 3);
326 
327  /* Apply the range */
328  SENSOR_SELECT();
329  success = sensor_common_write_reg(ACCEL_CONFIG, &acc_range_reg, 1);
330  SENSOR_DESELECT();
331 
332  if(success) {
333  acc_range = new_range;
334  }
335 
336  return success;
337 }
338 /*---------------------------------------------------------------------------*/
339 /**
340  * \brief Check whether a data or wake on motion interrupt has occurred
341  * \return Return the interrupt status
342  *
343  * This driver does not use interrupts, however this function allows us to
344  * determine whether a new sensor reading is available
345  */
346 static uint8_t
348 {
349  SENSOR_SELECT();
350  sensor_common_read_reg(INT_STATUS, &interrupt_status, 1);
351  SENSOR_DESELECT();
352 
353  return interrupt_status;
354 }
355 /*---------------------------------------------------------------------------*/
356 /**
357  * \brief Enable the MPU
358  * \param axes: Gyro bitmap [0..2], X = 1, Y = 2, Z = 4. 0 = gyro off
359  * Acc bitmap [3..5], X = 8, Y = 16, Z = 32. 0 = accelerometer off
360  */
361 static void
362 enable_sensor(uint16_t axes)
363 {
364  if(mpu_config == 0 && axes != 0) {
365  /* Wake up the sensor if it was off */
366  sensor_wakeup();
367  }
368 
369  mpu_config = axes;
370 
371  if(mpu_config != 0) {
372  /* Enable gyro + accelerometer readout */
373  select_axes();
374  delay_ms(10);
375  } else if(mpu_config == 0) {
376  sensor_sleep();
377  }
378 }
379 /*---------------------------------------------------------------------------*/
380 /**
381  * \brief Read data from the accelerometer - X, Y, Z - 3 words
382  * \return True if a valid reading could be taken, false otherwise
383  */
384 static bool
385 acc_read(uint16_t *data)
386 {
387  bool success;
388 
389  if(interrupt_status & BIT_RAW_RDY_EN) {
390  /* Burst read of all accelerometer values */
391  SENSOR_SELECT();
392  success = sensor_common_read_reg(ACCEL_XOUT_H, (uint8_t *)data, DATA_SIZE);
393  SENSOR_DESELECT();
394 
395  if(success) {
396  convert_to_le((uint8_t *)data, DATA_SIZE);
397  } else {
398  sensor_common_set_error_data((uint8_t *)data, DATA_SIZE);
399  }
400  } else {
401  /* Data not ready */
402  success = false;
403  }
404 
405  return success;
406 }
407 /*---------------------------------------------------------------------------*/
408 /**
409  * \brief Read data from the gyroscope - X, Y, Z - 3 words
410  * \return True if a valid reading could be taken, false otherwise
411  */
412 static bool
413 gyro_read(uint16_t *data)
414 {
415  bool success;
416 
417  if(interrupt_status & BIT_RAW_RDY_EN) {
418  /* Select this sensor */
419  SENSOR_SELECT();
420 
421  /* Burst read of all gyroscope values */
422  success = sensor_common_read_reg(GYRO_XOUT_H, (uint8_t *)data, DATA_SIZE);
423 
424  if(success) {
425  convert_to_le((uint8_t *)data, DATA_SIZE);
426  } else {
427  sensor_common_set_error_data((uint8_t *)data, DATA_SIZE);
428  }
429 
430  SENSOR_DESELECT();
431  } else {
432  success = false;
433  }
434 
435  return success;
436 }
437 /*---------------------------------------------------------------------------*/
438 /**
439  * \brief Convert accelerometer raw reading to a value in G
440  * \param raw_data The raw accelerometer reading
441  * \return The converted value
442  */
443 static float
444 acc_convert(int16_t raw_data)
445 {
446  float v = 0;
447 
448  switch(acc_range) {
449  case ACC_RANGE_2G:
450  /* Calculate acceleration, unit G, range -2, +2 */
451  v = (raw_data * 1.0) / (32768 / 2);
452  break;
453  case ACC_RANGE_4G:
454  /* Calculate acceleration, unit G, range -4, +4 */
455  v = (raw_data * 1.0) / (32768 / 4);
456  break;
457  case ACC_RANGE_8G:
458  /* Calculate acceleration, unit G, range -8, +8 */
459  v = (raw_data * 1.0) / (32768 / 8);
460  break;
461  case ACC_RANGE_16G:
462  /* Calculate acceleration, unit G, range -16, +16 */
463  v = (raw_data * 1.0) / (32768 / 16);
464  break;
465  default:
466  v = 0;
467  break;
468  }
469 
470  return v;
471 }
472 /*---------------------------------------------------------------------------*/
473 /**
474  * \brief Convert gyro raw reading to a value in deg/sec
475  * \param raw_data The raw accelerometer reading
476  * \return The converted value
477  */
478 static float
479 gyro_convert(int16_t raw_data)
480 {
481  /* calculate rotation, unit deg/s, range -250, +250 */
482  return (raw_data * 1.0) / (65536 / 500);
483 }
484 /*---------------------------------------------------------------------------*/
485 static void
486 notify_ready(void *not_used)
487 {
488  state = SENSOR_STATE_ENABLED;
489  sensors_changed(&mpu_9250_sensor);
490 }
491 /*---------------------------------------------------------------------------*/
492 static void
493 initialise(void *not_used)
494 {
495  /* Configure the accelerometer range */
496  if((elements & MPU_9250_SENSOR_TYPE_ACC) != 0) {
497  acc_set_range(MPU_9250_SENSOR_ACC_RANGE);
498  }
499 
501 
502  ctimer_set(&startup_timer, SENSOR_STARTUP_DELAY, notify_ready, NULL);
503 }
504 /*---------------------------------------------------------------------------*/
505 static void
506 power_up(void)
507 {
508  ti_lib_gpio_set_dio(BOARD_IOID_MPU_POWER);
509  state = SENSOR_STATE_BOOTING;
510 
511  ctimer_set(&startup_timer, SENSOR_BOOT_DELAY, initialise, NULL);
512 }
513 /*---------------------------------------------------------------------------*/
514 /**
515  * \brief Returns a reading from the sensor
516  * \param type MPU_9250_SENSOR_TYPE_ACC_[XYZ] or MPU_9250_SENSOR_TYPE_GYRO_[XYZ]
517  * \return centi-G (ACC) or centi-Deg/Sec (Gyro)
518  */
519 static int
520 value(int type)
521 {
522  int rv;
523  float converted_val = 0;
524 
525  if(state == SENSOR_STATE_DISABLED) {
526  PRINTF("MPU: Sensor Disabled\n");
527  return CC26XX_SENSOR_READING_ERROR;
528  }
529 
530  memset(sensor_value, 0, sizeof(sensor_value));
531 
532  if((type & MPU_9250_SENSOR_TYPE_ACC) != 0) {
533  t0 = RTIMER_NOW();
534 
535  while(!int_status() &&
536  (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + READING_WAIT_TIMEOUT)));
537 
538  rv = acc_read(sensor_value);
539 
540  if(rv == 0) {
541  return CC26XX_SENSOR_READING_ERROR;
542  }
543 
544  PRINTF("MPU: ACC = 0x%04x 0x%04x 0x%04x = ",
545  sensor_value[0], sensor_value[1], sensor_value[2]);
546 
547  /* Convert */
548  if(type == MPU_9250_SENSOR_TYPE_ACC_X) {
549  converted_val = acc_convert(sensor_value[0]);
550  } else if(type == MPU_9250_SENSOR_TYPE_ACC_Y) {
551  converted_val = acc_convert(sensor_value[1]);
552  } else if(type == MPU_9250_SENSOR_TYPE_ACC_Z) {
553  converted_val = acc_convert(sensor_value[2]);
554  }
555  rv = (int)(converted_val * 100);
556  } else if((type & MPU_9250_SENSOR_TYPE_GYRO) != 0) {
557  t0 = RTIMER_NOW();
558 
559  while(!int_status() &&
560  (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + READING_WAIT_TIMEOUT)));
561 
562  rv = gyro_read(sensor_value);
563 
564  if(rv == 0) {
565  return CC26XX_SENSOR_READING_ERROR;
566  }
567 
568  PRINTF("MPU: Gyro = 0x%04x 0x%04x 0x%04x = ",
569  sensor_value[0], sensor_value[1], sensor_value[2]);
570 
571  if(type == MPU_9250_SENSOR_TYPE_GYRO_X) {
572  converted_val = gyro_convert(sensor_value[0]);
573  } else if(type == MPU_9250_SENSOR_TYPE_GYRO_Y) {
574  converted_val = gyro_convert(sensor_value[1]);
575  } else if(type == MPU_9250_SENSOR_TYPE_GYRO_Z) {
576  converted_val = gyro_convert(sensor_value[2]);
577  }
578  rv = (int)(converted_val * 100);
579  } else {
580  PRINTF("MPU: Invalid type\n");
581  rv = CC26XX_SENSOR_READING_ERROR;
582  }
583 
584  PRINTF("%ld\n", (long int)(converted_val * 100));
585 
586  return rv;
587 }
588 /*---------------------------------------------------------------------------*/
589 /**
590  * \brief Configuration function for the MPU9250 sensor.
591  *
592  * \param type Activate, enable or disable the sensor. See below
593  * \param enable
594  *
595  * When type == SENSORS_HW_INIT we turn on the hardware
596  * When type == SENSORS_ACTIVE and enable==1 we enable the sensor
597  * When type == SENSORS_ACTIVE and enable==0 we disable the sensor
598  */
599 static int
600 configure(int type, int enable)
601 {
602  switch(type) {
603  case SENSORS_HW_INIT:
604  ti_lib_ioc_pin_type_gpio_input(BOARD_IOID_MPU_INT);
605  ti_lib_ioc_io_port_pull_set(BOARD_IOID_MPU_INT, IOC_IOPULL_DOWN);
606  ti_lib_ioc_io_hyst_set(BOARD_IOID_MPU_INT, IOC_HYST_ENABLE);
607 
608  ti_lib_ioc_pin_type_gpio_output(BOARD_IOID_MPU_POWER);
609  ti_lib_ioc_io_drv_strength_set(BOARD_IOID_MPU_POWER, IOC_CURRENT_4MA,
610  IOC_STRENGTH_MAX);
611  ti_lib_gpio_clear_dio(BOARD_IOID_MPU_POWER);
612  elements = MPU_9250_SENSOR_TYPE_NONE;
613  break;
614  case SENSORS_ACTIVE:
615  if(((enable & MPU_9250_SENSOR_TYPE_ACC) != 0) ||
616  ((enable & MPU_9250_SENSOR_TYPE_GYRO) != 0)) {
617  PRINTF("MPU: Enabling\n");
618  elements = enable & MPU_9250_SENSOR_TYPE_ALL;
619 
620  power_up();
621 
622  state = SENSOR_STATE_BOOTING;
623  } else {
624  PRINTF("MPU: Disabling\n");
625  if(HWREG(GPIO_BASE + GPIO_O_DOUT31_0) & BOARD_MPU_POWER) {
626  /* Then check our state */
627  elements = MPU_9250_SENSOR_TYPE_NONE;
628  ctimer_stop(&startup_timer);
629  sensor_sleep();
630  while(ti_lib_i2c_master_busy(I2C0_BASE));
631  state = SENSOR_STATE_DISABLED;
632  ti_lib_gpio_clear_dio(BOARD_IOID_MPU_POWER);
633  }
634  }
635  break;
636  default:
637  break;
638  }
639  return state;
640 }
641 /*---------------------------------------------------------------------------*/
642 /**
643  * \brief Returns the status of the sensor
644  * \param type SENSORS_ACTIVE or SENSORS_READY
645  * \return 1 if the sensor is enabled
646  */
647 static int
648 status(int type)
649 {
650  switch(type) {
651  case SENSORS_ACTIVE:
652  case SENSORS_READY:
653  return state;
654  break;
655  default:
656  break;
657  }
658  return SENSOR_STATE_DISABLED;
659 }
660 /*---------------------------------------------------------------------------*/
661 SENSORS_SENSOR(mpu_9250_sensor, "MPU9250", value, configure, status);
662 /*---------------------------------------------------------------------------*/
663 /** @} */
static float acc_convert(int16_t raw_data)
Convert accelerometer raw reading to a value in G.
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition: ctimer.c:149
static void select_axes(void)
Select gyro and accelerometer axes.
static void sensor_wakeup(void)
Exit low power mode.
Header file with macros which rename TI CC26xxware functions.
static int status(int type)
Returns the status of the sensor.
Header file for the Sensortag I2C Driver.
Header file for the Sensortag Invensense MPU9250 motion processing unit.
static void sensor_sleep(void)
Place the MPU in low power mode.
void sensor_common_set_error_data(uint8_t *buf, uint8_t len)
Fill a result buffer with dummy error data.
Definition: sensor-common.c:71
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:160
static uint8_t int_status(void)
Check whether a data or wake on motion interrupt has occurred.
bool sensor_common_read_reg(uint8_t addr, uint8_t *buf, uint8_t len)
Reads a sensor&#39;s register over I2C.
Definition: sensor-common.c:48
#define BOARD_IOID_MPU_INT
MPU IOID mappings.
Definition: board.h:170
static float gyro_convert(int16_t raw_data)
Convert gyro raw reading to a value in deg/sec.
Header file for the Sensortag Common sensor utilities.
static void enable_sensor(uint16_t axes)
Enable the MPU.
Header file for the real-time timer module.
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition: ctimer.c:99
static int value(int type)
Returns a reading from the sensor.
bool sensor_common_write_reg(uint8_t addr, uint8_t *buf, uint8_t len)
Write to a sensor&#39;s register over I2C.
Definition: sensor-common.c:54
static int configure(int type, int enable)
Configuration function for the MPU9250 sensor.
static void notify_ready(void *unused)
Callback when sensor is ready to read data from.
static bool gyro_read(uint16_t *data)
Read data from the gyroscope - X, Y, Z - 3 words.
static bool acc_set_range(uint8_t new_range)
Set the range of the accelerometer.
static bool acc_read(uint16_t *data)
Read data from the accelerometer - X, Y, Z - 3 words.