Contiki 3.x
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-CC26XX Invensense MPU9250 motion processing unit
37  */
38 /*---------------------------------------------------------------------------*/
39 #include "contiki-conf.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 
500  enable_sensor(elements & MPU_9250_SENSOR_TYPE_ALL);
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_pin_write(BOARD_MPU_POWER, 1);
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_rom_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_rom_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_pin_clear(BOARD_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_pin_clear(BOARD_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 /** @} */
#define BOARD_IOID_MPU_INT
MPU IOID mappings.
Definition: board.h:189
Header file for the real-time timer module.
Header file with macros which rename TI CC26xxware functions.
static void sensor_sleep(void)
Place the MPU in low power mode.
static int configure(int type, int enable)
Configuration function for the MPU9250 sensor.
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:135
static int status(int type)
Returns the status of the sensor.
static bool acc_set_range(uint8_t new_range)
Set the range of the accelerometer.
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
static uint8_t int_status(void)
Check whether a data or wake on motion interrupt has occurred.
static float gyro_convert(int16_t raw_data)
Convert gyro raw reading to a value in deg/sec.
static void sensor_wakeup(void)
Exit low power mode.
#define NULL
The null pointer.
static bool acc_read(uint16_t *data)
Read data from the accelerometer - X, Y, Z - 3 words.
Header file for the Sensortag-CC26xx Common sensor utilities.
static bool gyro_read(uint16_t *data)
Read data from the gyroscope - X, Y, Z - 3 words.
Header file for the Sensortag-CC26xx I2C Driver.
bool sensor_common_read_reg(uint8_t addr, uint8_t *buf, uint8_t len)
Reads a sensor's register over I2C.
Definition: sensor-common.c:48
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition: ctimer.c:99
bool sensor_common_write_reg(uint8_t addr, uint8_t *buf, uint8_t len)
Write to a sensor's register over I2C.
Definition: sensor-common.c:54
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition: ctimer.c:149
#define I2C0_BASE
Peripheral I2C0 base address.
Definition: MKL25Z4.h:2200
static float acc_convert(int16_t raw_data)
Convert accelerometer raw reading to a value in G.
static void enable_sensor(uint16_t axes)
Enable the MPU.
static int value(int type)
Returns a reading from the sensor.
Header file for the Sensortag-CC26XX Invensense MPU9250 motion processing unit.
static void select_axes(void)
Select gyro and accelerometer axes.