forked from Archive/PX4-Autopilot
ll40ls: support either internal or external I2C bus
This commit is contained in:
parent
99bfbb6dc3
commit
c6ada17f68
|
@ -74,7 +74,8 @@
|
||||||
/* Configuration Constants */
|
/* Configuration Constants */
|
||||||
#define LL40LS_BUS PX4_I2C_BUS_EXPANSION
|
#define LL40LS_BUS PX4_I2C_BUS_EXPANSION
|
||||||
#define LL40LS_BASEADDR 0x42 /* 7-bit address */
|
#define LL40LS_BASEADDR 0x42 /* 7-bit address */
|
||||||
#define LL40LS_DEVICE_PATH "/dev/ll40ls"
|
#define LL40LS_DEVICE_PATH_INT "/dev/ll40ls_int"
|
||||||
|
#define LL40LS_DEVICE_PATH_EXT "/dev/ll40ls_ext"
|
||||||
|
|
||||||
/* LL40LS Registers addresses */
|
/* LL40LS Registers addresses */
|
||||||
|
|
||||||
|
@ -101,7 +102,7 @@ static const int ERROR = -1;
|
||||||
class LL40LS : public device::I2C
|
class LL40LS : public device::I2C
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
LL40LS(int bus = LL40LS_BUS, int address = LL40LS_BASEADDR);
|
LL40LS(int bus, const char *path, int address = LL40LS_BASEADDR);
|
||||||
virtual ~LL40LS();
|
virtual ~LL40LS();
|
||||||
|
|
||||||
virtual int init();
|
virtual int init();
|
||||||
|
@ -134,6 +135,9 @@ private:
|
||||||
perf_counter_t _buffer_overflows;
|
perf_counter_t _buffer_overflows;
|
||||||
uint16_t _last_distance;
|
uint16_t _last_distance;
|
||||||
|
|
||||||
|
/**< the bus the device is connected to */
|
||||||
|
int _bus;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test whether the device supported by the driver is present at a
|
* Test whether the device supported by the driver is present at a
|
||||||
* specific address.
|
* specific address.
|
||||||
|
@ -189,8 +193,8 @@ private:
|
||||||
*/
|
*/
|
||||||
extern "C" __EXPORT int ll40ls_main(int argc, char *argv[]);
|
extern "C" __EXPORT int ll40ls_main(int argc, char *argv[]);
|
||||||
|
|
||||||
LL40LS::LL40LS(int bus, int address) :
|
LL40LS::LL40LS(int bus, const char *path, int address) :
|
||||||
I2C("LL40LS", LL40LS_DEVICE_PATH, bus, address, 100000),
|
I2C("LL40LS", path, bus, address, 100000),
|
||||||
_min_distance(LL40LS_MIN_DISTANCE),
|
_min_distance(LL40LS_MIN_DISTANCE),
|
||||||
_max_distance(LL40LS_MAX_DISTANCE),
|
_max_distance(LL40LS_MAX_DISTANCE),
|
||||||
_reports(nullptr),
|
_reports(nullptr),
|
||||||
|
@ -202,7 +206,8 @@ LL40LS::LL40LS(int bus, int address) :
|
||||||
_sample_perf(perf_alloc(PC_ELAPSED, "ll40ls_read")),
|
_sample_perf(perf_alloc(PC_ELAPSED, "ll40ls_read")),
|
||||||
_comms_errors(perf_alloc(PC_COUNT, "ll40ls_comms_errors")),
|
_comms_errors(perf_alloc(PC_COUNT, "ll40ls_comms_errors")),
|
||||||
_buffer_overflows(perf_alloc(PC_COUNT, "ll40ls_buffer_overflows")),
|
_buffer_overflows(perf_alloc(PC_COUNT, "ll40ls_buffer_overflows")),
|
||||||
_last_distance(0)
|
_last_distance(0),
|
||||||
|
_bus(bus)
|
||||||
{
|
{
|
||||||
// up the retries since the device misses the first measure attempts
|
// up the retries since the device misses the first measure attempts
|
||||||
I2C::_retries = 3;
|
I2C::_retries = 3;
|
||||||
|
@ -668,55 +673,89 @@ namespace ll40ls
|
||||||
#endif
|
#endif
|
||||||
const int ERROR = -1;
|
const int ERROR = -1;
|
||||||
|
|
||||||
LL40LS *g_dev;
|
LL40LS *g_dev_int;
|
||||||
|
LL40LS *g_dev_ext;
|
||||||
|
|
||||||
void start();
|
void start(int bus);
|
||||||
void stop();
|
void stop(int bus);
|
||||||
void test();
|
void test(int bus);
|
||||||
void reset();
|
void reset(int bus);
|
||||||
void info();
|
void info(int bus);
|
||||||
|
void usage();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start the driver.
|
* Start the driver.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
start()
|
start(int bus)
|
||||||
{
|
{
|
||||||
int fd;
|
/* create the driver, attempt expansion bus first */
|
||||||
|
if (bus == -1 || bus == PX4_I2C_BUS_EXPANSION) {
|
||||||
if (g_dev != nullptr) {
|
if (g_dev_ext != nullptr)
|
||||||
errx(1, "already started");
|
errx(0, "already started external");
|
||||||
|
g_dev_ext = new LL40LS(PX4_I2C_BUS_EXPANSION, LL40LS_DEVICE_PATH_EXT);
|
||||||
|
if (g_dev_ext != nullptr && OK != g_dev_ext->init()) {
|
||||||
|
delete g_dev_ext;
|
||||||
|
g_dev_ext = nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create the driver */
|
#ifdef PX4_I2C_BUS_ONBOARD
|
||||||
g_dev = new LL40LS(LL40LS_BUS);
|
/* if this failed, attempt onboard sensor */
|
||||||
|
if (bus == -1 || bus == PX4_I2C_BUS_ONBOARD) {
|
||||||
|
if (g_dev_int != nullptr)
|
||||||
|
errx(0, "already started internal");
|
||||||
|
g_dev_int = new LL40LS(PX4_I2C_BUS_ONBOARD, LL40LS_DEVICE_PATH_INT);
|
||||||
|
if (g_dev_int != nullptr && OK != g_dev_int->init()) {
|
||||||
|
/* tear down the failing onboard instance */
|
||||||
|
delete g_dev_int;
|
||||||
|
g_dev_int = nullptr;
|
||||||
|
|
||||||
if (g_dev == nullptr) {
|
if (bus == PX4_I2C_BUS_ONBOARD) {
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (OK != g_dev->init()) {
|
if (g_dev_int == nullptr && bus == PX4_I2C_BUS_ONBOARD) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* set the poll rate to default, starts automatic data collection */
|
/* set the poll rate to default, starts automatic data collection */
|
||||||
fd = open(LL40LS_DEVICE_PATH, O_RDONLY);
|
if (g_dev_int != nullptr) {
|
||||||
|
int fd = open(LL40LS_DEVICE_PATH_INT, O_RDONLY);
|
||||||
|
if (fd == -1) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
int ret = ioctl(fd, SENSORIOCSPOLLRATE, SENSOR_POLLRATE_DEFAULT);
|
||||||
|
close(fd);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fd < 0) {
|
if (g_dev_ext != nullptr) {
|
||||||
goto fail;
|
int fd = open(LL40LS_DEVICE_PATH_EXT, O_RDONLY);
|
||||||
}
|
if (fd == -1) {
|
||||||
|
goto fail;
|
||||||
if (ioctl(fd, SENSORIOCSPOLLRATE, SENSOR_POLLRATE_DEFAULT) < 0) {
|
}
|
||||||
goto fail;
|
int ret = ioctl(fd, SENSORIOCSPOLLRATE, SENSOR_POLLRATE_DEFAULT);
|
||||||
}
|
close(fd);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
exit(0);
|
exit(0);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
if (g_dev_int != nullptr && (bus == -1 || bus == PX4_I2C_BUS_ONBOARD)) {
|
||||||
if (g_dev != nullptr) {
|
delete g_dev_int;
|
||||||
delete g_dev;
|
g_dev_int = nullptr;
|
||||||
g_dev = nullptr;
|
}
|
||||||
|
if (g_dev_ext != nullptr && (bus == -1 || bus == PX4_I2C_BUS_EXPANSION)) {
|
||||||
|
delete g_dev_ext;
|
||||||
|
g_dev_ext = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
errx(1, "driver start failed");
|
errx(1, "driver start failed");
|
||||||
|
@ -725,11 +764,12 @@ fail:
|
||||||
/**
|
/**
|
||||||
* Stop the driver
|
* Stop the driver
|
||||||
*/
|
*/
|
||||||
void stop()
|
void stop(int bus)
|
||||||
{
|
{
|
||||||
if (g_dev != nullptr) {
|
LL40LS **g_dev = (bus == PX4_I2C_BUS_ONBOARD?&g_dev_int:&g_dev_ext);
|
||||||
delete g_dev;
|
if (*g_dev != nullptr) {
|
||||||
g_dev = nullptr;
|
delete *g_dev;
|
||||||
|
*g_dev = nullptr;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
errx(1, "driver not running");
|
errx(1, "driver not running");
|
||||||
|
@ -744,16 +784,17 @@ void stop()
|
||||||
* and automatic modes.
|
* and automatic modes.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
test()
|
test(int bus)
|
||||||
{
|
{
|
||||||
struct range_finder_report report;
|
struct range_finder_report report;
|
||||||
ssize_t sz;
|
ssize_t sz;
|
||||||
int ret;
|
int ret;
|
||||||
|
const char *path = (bus==PX4_I2C_BUS_ONBOARD?LL40LS_DEVICE_PATH_INT:LL40LS_DEVICE_PATH_EXT);
|
||||||
|
|
||||||
int fd = open(LL40LS_DEVICE_PATH, O_RDONLY);
|
int fd = open(path, O_RDONLY);
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
err(1, "%s open failed (try 'll40ls start' if the driver is not running", LL40LS_DEVICE_PATH);
|
err(1, "%s open failed (try 'll40ls start' if the driver is not running", path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do a simple demand read */
|
/* do a simple demand read */
|
||||||
|
@ -809,9 +850,10 @@ test()
|
||||||
* Reset the driver.
|
* Reset the driver.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
reset()
|
reset(int bus)
|
||||||
{
|
{
|
||||||
int fd = open(LL40LS_DEVICE_PATH, O_RDONLY);
|
const char *path = (bus==PX4_I2C_BUS_ONBOARD?LL40LS_DEVICE_PATH_INT:LL40LS_DEVICE_PATH_EXT);
|
||||||
|
int fd = open(path, O_RDONLY);
|
||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
err(1, "failed ");
|
err(1, "failed ");
|
||||||
|
@ -832,8 +874,9 @@ reset()
|
||||||
* Print a little info about the driver.
|
* Print a little info about the driver.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
info()
|
info(int bus)
|
||||||
{
|
{
|
||||||
|
LL40LS *g_dev = (bus == PX4_I2C_BUS_ONBOARD?g_dev_int:g_dev_ext);
|
||||||
if (g_dev == nullptr) {
|
if (g_dev == nullptr) {
|
||||||
errx(1, "driver not running");
|
errx(1, "driver not running");
|
||||||
}
|
}
|
||||||
|
@ -844,44 +887,76 @@ info()
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
usage()
|
||||||
|
{
|
||||||
|
warnx("missing command: try 'start', 'stop', 'info', 'test', 'reset', 'info'");
|
||||||
|
warnx("options:");
|
||||||
|
warnx(" -X only external bus");
|
||||||
|
#ifdef PX4_I2C_BUS_ONBOARD
|
||||||
|
warnx(" -I only internal bus");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int
|
int
|
||||||
ll40ls_main(int argc, char *argv[])
|
ll40ls_main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
int ch;
|
||||||
|
int bus = -1;
|
||||||
|
|
||||||
|
while ((ch = getopt(argc, argv, "XI")) != EOF) {
|
||||||
|
switch (ch) {
|
||||||
|
#ifdef PX4_I2C_BUS_ONBOARD
|
||||||
|
case 'I':
|
||||||
|
bus = PX4_I2C_BUS_ONBOARD;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 'X':
|
||||||
|
bus = PX4_I2C_BUS_EXPANSION;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ll40ls::usage();
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *verb = argv[optind];
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start/load the driver.
|
* Start/load the driver.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(argv[1], "start")) {
|
if (!strcmp(verb, "start")) {
|
||||||
ll40ls::start();
|
ll40ls::start(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stop the driver
|
* Stop the driver
|
||||||
*/
|
*/
|
||||||
if (!strcmp(argv[1], "stop")) {
|
if (!strcmp(verb, "stop")) {
|
||||||
ll40ls::stop();
|
ll40ls::stop(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Test the driver/device.
|
* Test the driver/device.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(argv[1], "test")) {
|
if (!strcmp(verb, "test")) {
|
||||||
ll40ls::test();
|
ll40ls::test(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reset the driver.
|
* Reset the driver.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(argv[1], "reset")) {
|
if (!strcmp(verb, "reset")) {
|
||||||
ll40ls::reset();
|
ll40ls::reset(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print driver information.
|
* Print driver information.
|
||||||
*/
|
*/
|
||||||
if (!strcmp(argv[1], "info") || !strcmp(argv[1], "status")) {
|
if (!strcmp(verb, "info") || !strcmp(verb, "status")) {
|
||||||
ll40ls::info();
|
ll40ls::info(bus);
|
||||||
}
|
}
|
||||||
|
|
||||||
errx(1, "unrecognized command, try 'start', 'test', 'reset' or 'info'");
|
errx(1, "unrecognized command, try 'start', 'test', 'reset' or 'info'");
|
||||||
|
|
Loading…
Reference in New Issue