|
|
|
@ -33,221 +33,108 @@
@@ -33,221 +33,108 @@
|
|
|
|
|
|
|
|
|
|
#include "bmi160.hpp" |
|
|
|
|
|
|
|
|
|
/** driver 'main' command */ |
|
|
|
|
extern "C" { __EXPORT int bmi160_main(int argc, char *argv[]); } |
|
|
|
|
#include <px4_platform_common/getopt.h> |
|
|
|
|
#include <px4_platform_common/module.h> |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Local functions in support of the shell command. |
|
|
|
|
*/ |
|
|
|
|
namespace bmi160 |
|
|
|
|
{ |
|
|
|
|
|
|
|
|
|
BMI160 *g_dev_int; // on internal bus
|
|
|
|
|
BMI160 *g_dev_ext; // on external bus
|
|
|
|
|
|
|
|
|
|
void start(bool, enum Rotation); |
|
|
|
|
void stop(bool); |
|
|
|
|
void info(bool); |
|
|
|
|
void regdump(bool); |
|
|
|
|
void testerror(bool); |
|
|
|
|
void usage(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Start the driver. |
|
|
|
|
* |
|
|
|
|
* This function only returns if the driver is up and running |
|
|
|
|
* or failed to detect the sensor. |
|
|
|
|
*/ |
|
|
|
|
void |
|
|
|
|
start(bool external_bus, enum Rotation rotation) |
|
|
|
|
BMI160::print_usage() |
|
|
|
|
{ |
|
|
|
|
BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int; |
|
|
|
|
|
|
|
|
|
if (*g_dev_ptr != nullptr) |
|
|
|
|
/* if already started, the still command succeeded */ |
|
|
|
|
{ |
|
|
|
|
errx(0, "already started"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* create the driver */ |
|
|
|
|
if (external_bus) { |
|
|
|
|
#if defined(PX4_SPI_BUS_EXT) && defined(PX4_SPIDEV_EXT_BMI) |
|
|
|
|
*g_dev_ptr = new BMI160(PX4_SPI_BUS_EXT, PX4_SPIDEV_EXT_BMI, rotation); |
|
|
|
|
#else |
|
|
|
|
errx(0, "External SPI not available"); |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
#if defined(PX4_SPIDEV_BMI) |
|
|
|
|
*g_dev_ptr = new BMI160(PX4_SPI_BUS_SENSORS, PX4_SPIDEV_BMI, rotation); |
|
|
|
|
#else |
|
|
|
|
errx(0, "No Internal SPI CS"); |
|
|
|
|
#endif |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (*g_dev_ptr == nullptr) { |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (OK != (*g_dev_ptr)->init()) { |
|
|
|
|
goto fail; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
fail: |
|
|
|
|
|
|
|
|
|
if (*g_dev_ptr != nullptr) { |
|
|
|
|
delete (*g_dev_ptr); |
|
|
|
|
*g_dev_ptr = nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
errx(1, "driver start failed"); |
|
|
|
|
PRINT_MODULE_USAGE_NAME("bmi160", "driver"); |
|
|
|
|
PRINT_MODULE_USAGE_SUBCATEGORY("imu"); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND("start"); |
|
|
|
|
PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(false, true); |
|
|
|
|
PRINT_MODULE_USAGE_PARAM_INT('R', 0, 0, 35, "Rotation", true); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND("reset"); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND("regdump"); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND("testerror"); |
|
|
|
|
PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
stop(bool external_bus) |
|
|
|
|
I2CSPIDriverBase *BMI160::instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, |
|
|
|
|
int runtime_instance) |
|
|
|
|
{ |
|
|
|
|
BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int; |
|
|
|
|
|
|
|
|
|
if (*g_dev_ptr != nullptr) { |
|
|
|
|
delete *g_dev_ptr; |
|
|
|
|
*g_dev_ptr = nullptr; |
|
|
|
|
BMI160 *instance = new BMI160(iterator.configuredBusOption(), iterator.bus(), iterator.devid(), cli.rotation, |
|
|
|
|
cli.bus_frequency, cli.spi_mode); |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
/* warn, but not an error */ |
|
|
|
|
warnx("already stopped."); |
|
|
|
|
if (!instance) { |
|
|
|
|
PX4_ERR("alloc failed"); |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Print a little info about the driver. |
|
|
|
|
*/ |
|
|
|
|
void |
|
|
|
|
info(bool external_bus) |
|
|
|
|
{ |
|
|
|
|
BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int; |
|
|
|
|
|
|
|
|
|
if (*g_dev_ptr == nullptr) { |
|
|
|
|
errx(1, "driver not running"); |
|
|
|
|
if (OK != instance->init()) { |
|
|
|
|
delete instance; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printf("state @ %p\n", *g_dev_ptr); |
|
|
|
|
(*g_dev_ptr)->print_info(); |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
return instance; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Dump the register information |
|
|
|
|
*/ |
|
|
|
|
void |
|
|
|
|
regdump(bool external_bus) |
|
|
|
|
BMI160::custom_method(const BusCLIArguments &cli) |
|
|
|
|
{ |
|
|
|
|
BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int; |
|
|
|
|
|
|
|
|
|
if (*g_dev_ptr == nullptr) { |
|
|
|
|
errx(1, "driver not running"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
printf("regdump @ %p\n", *g_dev_ptr); |
|
|
|
|
(*g_dev_ptr)->print_registers(); |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
switch (cli.custom1) { |
|
|
|
|
case 0: reset(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* deliberately produce an error to test recovery |
|
|
|
|
*/ |
|
|
|
|
void |
|
|
|
|
testerror(bool external_bus) |
|
|
|
|
{ |
|
|
|
|
BMI160 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int; |
|
|
|
|
case 1: print_registers(); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
if (*g_dev_ptr == nullptr) { |
|
|
|
|
errx(1, "driver not running"); |
|
|
|
|
case 2: test_error(); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
(*g_dev_ptr)->test_error(); |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
usage() |
|
|
|
|
{ |
|
|
|
|
warnx("missing command: try 'start', 'info', 'stop', 'regdump', 'testerror'"); |
|
|
|
|
warnx("options:"); |
|
|
|
|
warnx(" -X (external bus)"); |
|
|
|
|
warnx(" -R rotation"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
int |
|
|
|
|
bmi160_main(int argc, char *argv[]) |
|
|
|
|
extern "C" int bmi160_main(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
int myoptind = 1; |
|
|
|
|
int ch; |
|
|
|
|
const char *myoptarg = nullptr; |
|
|
|
|
bool external_bus = false; |
|
|
|
|
enum Rotation rotation = ROTATION_NONE; |
|
|
|
|
using ThisDriver = BMI160; |
|
|
|
|
BusCLIArguments cli{false, true}; |
|
|
|
|
cli.default_spi_frequency = BMI160_BUS_SPEED; |
|
|
|
|
|
|
|
|
|
while ((ch = px4_getopt(argc, argv, "XR:", &myoptind, &myoptarg)) != EOF) { |
|
|
|
|
while ((ch = cli.getopt(argc, argv, "R:")) != EOF) { |
|
|
|
|
switch (ch) { |
|
|
|
|
case 'X': |
|
|
|
|
external_bus = true; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'R': |
|
|
|
|
rotation = (enum Rotation)atoi(myoptarg); |
|
|
|
|
cli.rotation = (enum Rotation)atoi(cli.optarg()); |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
bmi160::usage(); |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (myoptind >= argc) { |
|
|
|
|
bmi160::usage(); |
|
|
|
|
const char *verb = cli.optarg(); |
|
|
|
|
|
|
|
|
|
if (!verb) { |
|
|
|
|
ThisDriver::print_usage(); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char *verb = argv[myoptind]; |
|
|
|
|
BusInstanceIterator iterator(MODULE_NAME, cli, DRV_IMU_DEVTYPE_BMI160); |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Start/load the driver. |
|
|
|
|
*/ |
|
|
|
|
if (!strcmp(verb, "start")) { |
|
|
|
|
bmi160::start(external_bus, rotation); |
|
|
|
|
return ThisDriver::module_start(cli, iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!strcmp(verb, "stop")) { |
|
|
|
|
bmi160::stop(external_bus); |
|
|
|
|
return ThisDriver::module_stop(iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!strcmp(verb, "status")) { |
|
|
|
|
return ThisDriver::module_status(iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Print driver information. |
|
|
|
|
*/ |
|
|
|
|
if (!strcmp(verb, "info")) { |
|
|
|
|
bmi160::info(external_bus); |
|
|
|
|
if (!strcmp(verb, "reset")) { |
|
|
|
|
cli.custom1 = 0; |
|
|
|
|
return ThisDriver::module_custom_method(cli, iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Print register information. |
|
|
|
|
*/ |
|
|
|
|
if (!strcmp(verb, "regdump")) { |
|
|
|
|
bmi160::regdump(external_bus); |
|
|
|
|
cli.custom1 = 1; |
|
|
|
|
return ThisDriver::module_custom_method(cli, iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!strcmp(verb, "testerror")) { |
|
|
|
|
bmi160::testerror(external_bus); |
|
|
|
|
cli.custom1 = 2; |
|
|
|
|
return ThisDriver::module_custom_method(cli, iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
bmi160::usage(); |
|
|
|
|
ThisDriver::print_usage(); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|