mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-06-01 02:55:07 +08:00
Made the MPU6000 driver a highbread using both hrt for SPI or workqueue for I2C
This commit is contained in:
committed by
Lorenz Meier
parent
5f342c3b5f
commit
e8ae0fe13c
@@ -7,6 +7,10 @@ if adc start
|
|||||||
then
|
then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if ms5611 -T 5607 -I start
|
||||||
|
then
|
||||||
|
fi
|
||||||
|
|
||||||
# External I2C bus
|
# External I2C bus
|
||||||
if hmc5883 -C -T -X start
|
if hmc5883 -C -T -X start
|
||||||
then
|
then
|
||||||
@@ -21,8 +25,8 @@ if hmc5883 -C -T -S -R 2 start
|
|||||||
then
|
then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Internal SPI bus ICM-20608-G is rotated 90 deg yaw
|
# Internal I2C bus Rotation TBD
|
||||||
if mpu6000 -R 2 -T 20608 start
|
if mpu6000 -I -T 6000 start
|
||||||
then
|
then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ set(config_module_list
|
|||||||
drivers/boards/tap-v1
|
drivers/boards/tap-v1
|
||||||
drivers/rgbled_pwm
|
drivers/rgbled_pwm
|
||||||
drivers/tap_esc
|
drivers/tap_esc
|
||||||
#drivers/mpu6500
|
drivers/mpu6000
|
||||||
drivers/ms5611
|
drivers/ms5611
|
||||||
drivers/hmc5883
|
drivers/hmc5883
|
||||||
drivers/gps
|
drivers/gps
|
||||||
|
|||||||
@@ -114,8 +114,7 @@ __BEGIN_DECLS
|
|||||||
* Note that these are unshifted addresses (not includinf R/W).
|
* Note that these are unshifted addresses (not includinf R/W).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* todo:
|
/*
|
||||||
* Cannot tell from the schematic if there is one or 2 MPU6050
|
|
||||||
* The slave address of the MPU-60X0 is b110100X which is 7 bits long.
|
* The slave address of the MPU-60X0 is b110100X which is 7 bits long.
|
||||||
* The LSB bit of the 7 bit address is determined by the logic level
|
* The LSB bit of the 7 bit address is determined by the logic level
|
||||||
* on pin AD0. This allows two MPU-60X0s to be connected to the same I2C bus.
|
* on pin AD0. This allows two MPU-60X0s to be connected to the same I2C bus.
|
||||||
@@ -123,8 +122,7 @@ __BEGIN_DECLS
|
|||||||
* should be b1101000 (pin AD0 is logic low) and the address of the other
|
* should be b1101000 (pin AD0 is logic low) and the address of the other
|
||||||
* should be b1101001 (pin AD0 is logic high).
|
* should be b1101001 (pin AD0 is logic high).
|
||||||
*/
|
*/
|
||||||
#define PX4_I2C_ON_BOARD_MPU6050_ADDRS {0x68,0x69}
|
#define PX4_I2C_MPU6050_ADDR 0x68
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ADC channels
|
* ADC channels
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
px4_add_module(
|
px4_add_module(
|
||||||
MODULE drivers__mpu6000
|
MODULE drivers__mpu6000
|
||||||
MAIN mpu6000
|
MAIN mpu6000
|
||||||
STACK_MAIN 1300
|
STACK_MAIN 1400
|
||||||
COMPILE_FLAGS
|
COMPILE_FLAGS
|
||||||
-Weffc++
|
-Weffc++
|
||||||
-Os
|
-Os
|
||||||
|
|||||||
+166
-15
@@ -34,10 +34,25 @@
|
|||||||
/**
|
/**
|
||||||
* @file mpu6000.cpp
|
* @file mpu6000.cpp
|
||||||
*
|
*
|
||||||
* Driver for the Invensense MPU6000 connected via SPI.
|
* Driver for the Invensense MPU6000, MPU6050 and the ICM2608 connected via
|
||||||
|
* SPI or I2C.
|
||||||
|
*
|
||||||
|
* When the device is on the SPI bus the hrt is used to provide thread of
|
||||||
|
* execution to the driver.
|
||||||
|
*
|
||||||
|
* When the device is on the I2C bus a work queue is used provide thread of
|
||||||
|
* execution to the driver.
|
||||||
|
*
|
||||||
|
* The I2C code is only included in the build if USE_I2C is defined by the
|
||||||
|
* existance of any of PX4_I2C_MPU6050_ADDR, PX4_I2C_MPU6000_ADDR or
|
||||||
|
* PX4_I2C_ICM_20608_G_ADDR in the board_config.h file.
|
||||||
|
*
|
||||||
|
* The command line option -T 6000|20608 (default 6000) selects between
|
||||||
|
* MPU60x0 or the ICM20608G;
|
||||||
*
|
*
|
||||||
* @author Andrew Tridgell
|
* @author Andrew Tridgell
|
||||||
* @author Pat Hickey
|
* @author Pat Hickey
|
||||||
|
* @author David Sidrane
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <px4_config.h>
|
#include <px4_config.h>
|
||||||
@@ -63,6 +78,7 @@
|
|||||||
#include <systemlib/px4_macros.h>
|
#include <systemlib/px4_macros.h>
|
||||||
|
|
||||||
#include <nuttx/arch.h>
|
#include <nuttx/arch.h>
|
||||||
|
#include <nuttx/wqueue.h>
|
||||||
#include <nuttx/clock.h>
|
#include <nuttx/clock.h>
|
||||||
|
|
||||||
#include <board_config.h>
|
#include <board_config.h>
|
||||||
@@ -85,6 +101,9 @@
|
|||||||
worst case timing jitter due to other timers
|
worst case timing jitter due to other timers
|
||||||
*/
|
*/
|
||||||
#define MPU6000_TIMER_REDUCTION 200
|
#define MPU6000_TIMER_REDUCTION 200
|
||||||
|
#define MPU6000_CONVERSION_INTERVAL 10000 //todo:This is set long for the moment
|
||||||
|
// As the bus is running at 100KHX and the
|
||||||
|
// Transaction time is 2.163Ms
|
||||||
|
|
||||||
enum MPU6000_BUS {
|
enum MPU6000_BUS {
|
||||||
MPU6000_BUS_ALL = 0,
|
MPU6000_BUS_ALL = 0,
|
||||||
@@ -140,6 +159,16 @@ private:
|
|||||||
MPU6000_gyro *_gyro;
|
MPU6000_gyro *_gyro;
|
||||||
uint8_t _product; /** product code */
|
uint8_t _product; /** product code */
|
||||||
|
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
/*
|
||||||
|
* SPI bus based device use hrt
|
||||||
|
* I2C bus needs to use work queue
|
||||||
|
*/
|
||||||
|
bool _use_hrt;
|
||||||
|
work_s _work;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
struct hrt_call _call;
|
struct hrt_call _call;
|
||||||
unsigned _call_interval;
|
unsigned _call_interval;
|
||||||
|
|
||||||
@@ -229,6 +258,39 @@ private:
|
|||||||
*/
|
*/
|
||||||
bool is_mpu_device() { return _device_type == 6000;}
|
bool is_mpu_device() { return _device_type == 6000;}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
/**
|
||||||
|
* When the I2C interfase is cho
|
||||||
|
* Perform a poll cycle; collect from the previous measurement
|
||||||
|
* and start a new one.
|
||||||
|
*
|
||||||
|
* This is the heart of the measurement state machine. This function
|
||||||
|
* alternately starts a measurement, or collects the data from the
|
||||||
|
* previous measurement.
|
||||||
|
*
|
||||||
|
* When the interval between measurements is greater than the minimum
|
||||||
|
* measurement interval, a gap is inserted between collection
|
||||||
|
* and measurement to provide the most recent measurement possible
|
||||||
|
* at the next interval.
|
||||||
|
*/
|
||||||
|
void cycle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static trampoline from the workq context; because we don't have a
|
||||||
|
* generic workq wrapper yet.
|
||||||
|
*
|
||||||
|
* @param arg Instance pointer for the driver that is polling.
|
||||||
|
*/
|
||||||
|
static void cycle_trampoline(void *arg);
|
||||||
|
|
||||||
|
bool is_i2c(void) { return !_use_hrt; }
|
||||||
|
|
||||||
|
void use_i2c(bool on_true) { _use_hrt = !on_true; }
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Static trampoline from the hrt_call context; because we don't have a
|
* Static trampoline from the hrt_call context; because we don't have a
|
||||||
* generic hrt wrapper yet.
|
* generic hrt wrapper yet.
|
||||||
@@ -243,7 +305,7 @@ private:
|
|||||||
/**
|
/**
|
||||||
* Fetch measurements from the sensor and update the report buffers.
|
* Fetch measurements from the sensor and update the report buffers.
|
||||||
*/
|
*/
|
||||||
void measure();
|
int measure();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a register from the MPU6000
|
* Read a register from the MPU6000
|
||||||
@@ -406,6 +468,10 @@ MPU6000::MPU6000(device::Device *interface, const char *path_accel, const char *
|
|||||||
_device_type(device_type),
|
_device_type(device_type),
|
||||||
_gyro(new MPU6000_gyro(this, path_gyro)),
|
_gyro(new MPU6000_gyro(this, path_gyro)),
|
||||||
_product(0),
|
_product(0),
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
_use_hrt(false),
|
||||||
|
_work{},
|
||||||
|
#endif
|
||||||
_call {},
|
_call {},
|
||||||
_call_interval(0),
|
_call_interval(0),
|
||||||
_accel_reports(nullptr),
|
_accel_reports(nullptr),
|
||||||
@@ -446,6 +512,10 @@ MPU6000::MPU6000(device::Device *interface, const char *path_accel, const char *
|
|||||||
_last_accel{},
|
_last_accel{},
|
||||||
_got_duplicate(false)
|
_got_duplicate(false)
|
||||||
{
|
{
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
// work_cancel in stop_cycle called from the dtor will explode if we don't do this...
|
||||||
|
memset(&_work, 0, sizeof(_work));
|
||||||
|
#endif
|
||||||
// disable debug() calls
|
// disable debug() calls
|
||||||
_debug_enabled = false;
|
_debug_enabled = false;
|
||||||
|
|
||||||
@@ -509,7 +579,14 @@ MPU6000::~MPU6000()
|
|||||||
int
|
int
|
||||||
MPU6000::init()
|
MPU6000::init()
|
||||||
{
|
{
|
||||||
/* probe again to get our settings */
|
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
unsigned dummy;
|
||||||
|
use_i2c(_interface->ioctl(MPUIOCGIS_I2C, dummy));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* probe again to get our settings that are based on the device type */
|
||||||
|
|
||||||
int ret = probe();
|
int ret = probe();
|
||||||
|
|
||||||
@@ -531,6 +608,7 @@ MPU6000::init()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = -ENOMEM;
|
||||||
/* allocate basic report buffers */
|
/* allocate basic report buffers */
|
||||||
_accel_reports = new ringbuffer::RingBuffer(2, sizeof(accel_report));
|
_accel_reports = new ringbuffer::RingBuffer(2, sizeof(accel_report));
|
||||||
|
|
||||||
@@ -544,6 +622,8 @@ MPU6000::init()
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = -EIO;
|
||||||
|
|
||||||
if (reset() != OK) {
|
if (reset() != OK) {
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -626,8 +706,15 @@ int MPU6000::reset()
|
|||||||
write_checked_reg(MPUREG_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ);
|
write_checked_reg(MPUREG_PWR_MGMT_1, MPU_CLK_SEL_PLLGYROZ);
|
||||||
up_udelay(1000);
|
up_udelay(1000);
|
||||||
|
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
|
||||||
|
if (!is_i2c())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
// Disable I2C bus (recommended on datasheet)
|
// Disable I2C bus (recommended on datasheet)
|
||||||
write_checked_reg(MPUREG_USER_CTRL, BIT_I2C_IF_DIS);
|
write_checked_reg(MPUREG_USER_CTRL, BIT_I2C_IF_DIS);
|
||||||
|
}
|
||||||
|
|
||||||
px4_leave_critical_section(state);
|
px4_leave_critical_section(state);
|
||||||
|
|
||||||
if (read_reg(MPUREG_PWR_MGMT_1) == MPU_CLK_SEL_PLLGYROZ) {
|
if (read_reg(MPUREG_PWR_MGMT_1) == MPU_CLK_SEL_PLLGYROZ) {
|
||||||
@@ -1218,7 +1305,13 @@ MPU6000::ioctl(struct file *filp, int cmd, unsigned long arg)
|
|||||||
them. This prevents aliasing due to a beat between the
|
them. This prevents aliasing due to a beat between the
|
||||||
stm32 clock and the mpu6000 clock
|
stm32 clock and the mpu6000 clock
|
||||||
*/
|
*/
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
|
||||||
|
if (!is_i2c())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
_call.period = _call_interval - MPU6000_TIMER_REDUCTION;
|
_call.period = _call_interval - MPU6000_TIMER_REDUCTION;
|
||||||
|
}
|
||||||
|
|
||||||
/* if we need to start the poll state machine, do it */
|
/* if we need to start the poll state machine, do it */
|
||||||
if (want_start) {
|
if (want_start) {
|
||||||
@@ -1521,18 +1614,40 @@ MPU6000::start()
|
|||||||
_accel_reports->flush();
|
_accel_reports->flush();
|
||||||
_gyro_reports->flush();
|
_gyro_reports->flush();
|
||||||
|
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
|
||||||
|
if (_use_hrt) {
|
||||||
|
#endif
|
||||||
/* start polling at the specified rate */
|
/* start polling at the specified rate */
|
||||||
hrt_call_every(&_call,
|
hrt_call_every(&_call,
|
||||||
1000,
|
1000,
|
||||||
_call_interval - MPU6000_TIMER_REDUCTION,
|
_call_interval - MPU6000_TIMER_REDUCTION,
|
||||||
(hrt_callout)&MPU6000::measure_trampoline, this);
|
(hrt_callout)&MPU6000::measure_trampoline, this);
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* schedule a cycle to start things */
|
||||||
|
work_queue(HPWORK, &_work, (worker_t)&MPU6000::cycle_trampoline, this, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MPU6000::stop()
|
MPU6000::stop()
|
||||||
{
|
{
|
||||||
hrt_cancel(&_call);
|
#if defined(USE_I2C)
|
||||||
|
|
||||||
|
if (_use_hrt) {
|
||||||
|
#endif
|
||||||
|
hrt_cancel(&_call);
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
work_cancel(HPWORK, &_work);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
/* reset internal states */
|
/* reset internal states */
|
||||||
memset(_last_accel, 0, sizeof(_last_accel));
|
memset(_last_accel, 0, sizeof(_last_accel));
|
||||||
|
|
||||||
@@ -1541,6 +1656,43 @@ MPU6000::stop()
|
|||||||
_gyro_reports->flush();
|
_gyro_reports->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(USE_I2C)
|
||||||
|
void
|
||||||
|
MPU6000::cycle_trampoline(void *arg)
|
||||||
|
{
|
||||||
|
MPU6000 *dev = (MPU6000 *)arg;
|
||||||
|
|
||||||
|
dev->cycle();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MPU6000::cycle()
|
||||||
|
{
|
||||||
|
|
||||||
|
int ret = measure();
|
||||||
|
|
||||||
|
if (ret != OK) {
|
||||||
|
/* issue a reset command to the sensor */
|
||||||
|
reset();
|
||||||
|
start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_call_interval != 0) {
|
||||||
|
work_queue(HPWORK,
|
||||||
|
&_work,
|
||||||
|
(worker_t)&MPU6000::cycle_trampoline,
|
||||||
|
this,
|
||||||
|
USEC2TICK(MPU6000_CONVERSION_INTERVAL));
|
||||||
|
//todo:This is set long for the moment
|
||||||
|
// As the bus is running at 100KHX and the
|
||||||
|
// Transaction time is 2.163Ms
|
||||||
|
// It should be USEC2TICK(_call_interval - MPU6000_TIMER_REDUCTION));
|
||||||
|
// When I get the bus running at 400Khz
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
MPU6000::measure_trampoline(void *arg)
|
MPU6000::measure_trampoline(void *arg)
|
||||||
{
|
{
|
||||||
@@ -1549,7 +1701,6 @@ MPU6000::measure_trampoline(void *arg)
|
|||||||
/* make another measurement */
|
/* make another measurement */
|
||||||
dev->measure();
|
dev->measure();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MPU6000::check_registers(void)
|
MPU6000::check_registers(void)
|
||||||
{
|
{
|
||||||
@@ -1611,17 +1762,17 @@ MPU6000::check_registers(void)
|
|||||||
_checked_next = (_checked_next + 1) % MPU6000_NUM_CHECKED_REGISTERS;
|
_checked_next = (_checked_next + 1) % MPU6000_NUM_CHECKED_REGISTERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
MPU6000::measure()
|
MPU6000::measure()
|
||||||
{
|
{
|
||||||
if (_in_factory_test) {
|
if (_in_factory_test) {
|
||||||
// don't publish any data while in factory test mode
|
// don't publish any data while in factory test mode
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hrt_absolute_time() < _reset_wait) {
|
if (hrt_absolute_time() < _reset_wait) {
|
||||||
// we're waiting for a reset to complete
|
// we're waiting for a reset to complete
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MPUReport mpu_report;
|
struct MPUReport mpu_report;
|
||||||
@@ -1648,7 +1799,7 @@ MPU6000::measure()
|
|||||||
if (sizeof(mpu_report) != _interface->read(MPU6000_SET_SPEED(MPUREG_INT_STATUS, MPU6000_HIGH_BUS_SPEED),
|
if (sizeof(mpu_report) != _interface->read(MPU6000_SET_SPEED(MPUREG_INT_STATUS, MPU6000_HIGH_BUS_SPEED),
|
||||||
(uint8_t *)&mpu_report,
|
(uint8_t *)&mpu_report,
|
||||||
sizeof(mpu_report))) {
|
sizeof(mpu_report))) {
|
||||||
return;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_registers();
|
check_registers();
|
||||||
@@ -1666,7 +1817,7 @@ MPU6000::measure()
|
|||||||
perf_end(_sample_perf);
|
perf_end(_sample_perf);
|
||||||
perf_count(_duplicates);
|
perf_count(_duplicates);
|
||||||
_got_duplicate = true;
|
_got_duplicate = true;
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(&_last_accel[0], &mpu_report.accel_x[0], 6);
|
memcpy(&_last_accel[0], &mpu_report.accel_x[0], 6);
|
||||||
@@ -1700,7 +1851,7 @@ MPU6000::measure()
|
|||||||
// costs 20ms with interrupts disabled. That means if
|
// costs 20ms with interrupts disabled. That means if
|
||||||
// the mpu6k does go bad it would cause a FMU failure,
|
// the mpu6k does go bad it would cause a FMU failure,
|
||||||
// regardless of whether another sensor is available,
|
// regardless of whether another sensor is available,
|
||||||
return;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
perf_count(_good_transfers);
|
perf_count(_good_transfers);
|
||||||
@@ -1710,7 +1861,7 @@ MPU6000::measure()
|
|||||||
// the sensor again. We still increment
|
// the sensor again. We still increment
|
||||||
// _good_transfers, but don't return any data yet
|
// _good_transfers, but don't return any data yet
|
||||||
_register_wait--;
|
_register_wait--;
|
||||||
return;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1865,6 +2016,7 @@ MPU6000::measure()
|
|||||||
|
|
||||||
/* stop measuring */
|
/* stop measuring */
|
||||||
perf_end(_sample_perf);
|
perf_end(_sample_perf);
|
||||||
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -2054,6 +2206,7 @@ start_bus(struct mpu6000_bus_option &bus, enum Rotation rotation, int range, int
|
|||||||
|
|
||||||
device::Device *interface = bus.interface_constructor(bus.busnum, device_type, external);
|
device::Device *interface = bus.interface_constructor(bus.busnum, device_type, external);
|
||||||
|
|
||||||
|
|
||||||
if (interface == nullptr) {
|
if (interface == nullptr) {
|
||||||
warnx("no device on bus %u", (unsigned)bus.busid);
|
warnx("no device on bus %u", (unsigned)bus.busid);
|
||||||
return false;
|
return false;
|
||||||
@@ -2136,9 +2289,7 @@ start(enum MPU6000_BUS busid, enum Rotation rotation, int range, int device_type
|
|||||||
started |= start_bus(bus_options[i], rotation, range, device_type, external);
|
started |= start_bus(bus_options[i], rotation, range, device_type, external);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!started) {
|
exit(started ? 0 : 1);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -174,6 +174,8 @@
|
|||||||
#define EXTERNAL_BUS 0
|
#define EXTERNAL_BUS 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MPUIOCGIS_I2C (unsigned)(DEVIOCGDEVICEID+100)
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
/**
|
/**
|
||||||
* Report conversation within the MPU6000, including command byte and
|
* Report conversation within the MPU6000, including command byte and
|
||||||
|
|||||||
@@ -121,6 +121,9 @@ MPU6000_I2C::ioctl(unsigned operation, unsigned &arg)
|
|||||||
case DEVIOCGDEVICEID:
|
case DEVIOCGDEVICEID:
|
||||||
return CDev::ioctl(nullptr, operation, arg);
|
return CDev::ioctl(nullptr, operation, arg);
|
||||||
|
|
||||||
|
case MPUIOCGIS_I2C:
|
||||||
|
return 1;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -181,6 +181,9 @@ MPU6000_SPI::ioctl(unsigned operation, unsigned &arg)
|
|||||||
case DEVIOCGDEVICEID:
|
case DEVIOCGDEVICEID:
|
||||||
return CDev::ioctl(nullptr, operation, arg);
|
return CDev::ioctl(nullptr, operation, arg);
|
||||||
|
|
||||||
|
case MPUIOCGIS_I2C:
|
||||||
|
return 0;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user