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/*---------------------------------------------------------------------------*/
209static uint8_t mpu_config;
210static uint8_t acc_range;
211static uint8_t acc_range_reg;
212static uint8_t val;
213static uint8_t interrupt_status;
214/*---------------------------------------------------------------------------*/
215#define SENSOR_STATE_DISABLED 0
216#define SENSOR_STATE_BOOTING 1
217#define SENSOR_STATE_ENABLED 2
218
219static int state = SENSOR_STATE_DISABLED;
220static 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
225static 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
235static struct ctimer startup_timer;
236/*---------------------------------------------------------------------------*/
237/* Wait for the MPU to have data ready */
238rtimer_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 */
249static 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 */
265static 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 */
288static void
290{
291 val = ~mpu_config;
292 SENSOR_SELECT();
293 sensor_common_write_reg(PWR_MGMT_2, &val, 1);
294 SENSOR_DESELECT();
295}
296/*---------------------------------------------------------------------------*/
297static void
298convert_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 */
314static bool
315acc_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 */
346static 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 */
361static void
362enable_sensor(uint16_t axes)
363{
364 if(mpu_config == 0 && axes != 0) {
365 /* Wake up the sensor if it was off */
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 */
384static bool
385acc_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 */
412static bool
413gyro_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 */
443static float
444acc_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 */
478static float
479gyro_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/*---------------------------------------------------------------------------*/
485static void
486notify_ready(void *not_used)
487{
488 state = SENSOR_STATE_ENABLED;
489 sensors_changed(&mpu_9250_sensor);
490}
491/*---------------------------------------------------------------------------*/
492static void
493initialise(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/*---------------------------------------------------------------------------*/
505static void
506power_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 */
519static int
520value(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 */
599static int
600configure(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 */
647static int
648status(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/*---------------------------------------------------------------------------*/
661SENSORS_SENSOR(mpu_9250_sensor, "MPU9250", value, configure, status);
662/*---------------------------------------------------------------------------*/
663/** @} */
Header file for the Sensortag I2C Driver.
void ctimer_stop(struct ctimer *c)
Stop a pending callback timer.
Definition: ctimer.c:149
void ctimer_set(struct ctimer *c, clock_time_t t, void(*f)(void *), void *ptr)
Set a callback timer.
Definition: ctimer.c:99
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:185
#define BOARD_IOID_MPU_INT
MPU IOID mappings.
Definition: board.h:170
static void select_axes(void)
Select gyro and accelerometer axes.
static int value(int type)
Returns a reading from the sensor.
static bool acc_set_range(uint8_t new_range)
Set the range of the accelerometer.
static void sensor_sleep(void)
Place the MPU in low power mode.
static int status(int type)
Returns the status of the sensor.
static uint8_t int_status(void)
Check whether a data or wake on motion interrupt has occurred.
static void enable_sensor(uint16_t axes)
Enable the MPU.
static float acc_convert(int16_t raw_data)
Convert accelerometer raw reading to a value in G.
static void sensor_wakeup(void)
Exit low power mode.
static float gyro_convert(int16_t raw_data)
Convert gyro raw reading to a value in deg/sec.
static bool gyro_read(uint16_t *data)
Read data from the gyroscope - X, Y, Z - 3 words.
static bool acc_read(uint16_t *data)
Read data from the accelerometer - X, Y, Z - 3 words.
static int configure(int type, int enable)
Configuration function for the MPU9250 sensor.
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
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
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
static void notify_ready(void *unused)
Callback when sensor is ready to read data from.
@ MPU_9250_SENSOR_TYPE_GYRO_Z
0b000100 = 0x04
@ MPU_9250_SENSOR_TYPE_ACC_X
0b001000 = 0x08
@ MPU_9250_SENSOR_TYPE_ACC_Y
0b010000 = 0x10
@ MPU_9250_SENSOR_TYPE_ACC
0b111000 = 0x38
@ MPU_9250_SENSOR_TYPE_ACC_Z
0b100000 = 0x20
@ MPU_9250_SENSOR_TYPE_NONE
0b000000 = 0x00
@ MPU_9250_SENSOR_TYPE_ALL
0b111111 = 0x3F
@ MPU_9250_SENSOR_TYPE_GYRO_Y
0b000010 = 0x02
@ MPU_9250_SENSOR_TYPE_GYRO_X
0b000001 = 0x01
@ MPU_9250_SENSOR_TYPE_GYRO
0b000111 = 0x07
Header file for the real-time timer module.
Header file for the Sensortag Common sensor utilities.
Header file with macros which rename TI CC26xxware functions.