From d81fedfcfac67bf3f59be6804cc856bbd9ed0796 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Wed, 26 Feb 2020 18:17:10 +0100 Subject: [PATCH] refactor lps22hb: use driver base class --- boards/av/x-v1/init/rc.board_sensors | 2 +- src/drivers/barometer/lps22hb/LPS22HB.cpp | 21 +- src/drivers/barometer/lps22hb/LPS22HB.hpp | 40 +-- src/drivers/barometer/lps22hb/LPS22HB_I2C.cpp | 12 +- src/drivers/barometer/lps22hb/LPS22HB_SPI.cpp | 15 +- .../barometer/lps22hb/lps22hb_main.cpp | 274 +++--------------- 6 files changed, 77 insertions(+), 287 deletions(-) diff --git a/boards/av/x-v1/init/rc.board_sensors b/boards/av/x-v1/init/rc.board_sensors index 68dd9377c7..f3cf068b7b 100644 --- a/boards/av/x-v1/init/rc.board_sensors +++ b/boards/av/x-v1/init/rc.board_sensors @@ -7,7 +7,7 @@ adc start adis16477 -R 8 start -lps22hb -S start +lps22hb -s start lsm303agr -R 4 start diff --git a/src/drivers/barometer/lps22hb/LPS22HB.cpp b/src/drivers/barometer/lps22hb/LPS22HB.cpp index ac980f058e..e425634c82 100644 --- a/src/drivers/barometer/lps22hb/LPS22HB.cpp +++ b/src/drivers/barometer/lps22hb/LPS22HB.cpp @@ -42,9 +42,9 @@ /* Max measurement rate is 25Hz */ #define LPS22HB_CONVERSION_INTERVAL (1000000 / 25) /* microseconds */ -LPS22HB::LPS22HB(device::Device *interface, const char *path) : - CDev(path), - ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(interface->get_device_id())), +LPS22HB::LPS22HB(I2CSPIBusOption bus_option, int bus, device::Device *interface) : + CDev(nullptr), + I2CSPIDriver(MODULE_NAME, px4::device_bus_to_wq(interface->get_device_id()), bus_option, bus), _interface(interface), _sample_perf(perf_alloc(PC_ELAPSED, "lps22hb_read")), _comms_errors(perf_alloc(PC_COUNT, "lps22hb_comms_errors")) @@ -55,9 +55,6 @@ LPS22HB::LPS22HB(device::Device *interface, const char *path) : LPS22HB::~LPS22HB() { - /* make sure we are truly inactive */ - stop(); - if (_class_instance != -1) { unregister_class_devname(BARO_BASE_DEVICE_PATH, _class_instance); } @@ -88,7 +85,6 @@ LPS22HB::init() ret = OK; - PX4_INFO("starting"); _measure_interval = LPS22HB_CONVERSION_INTERVAL; start(); @@ -174,12 +170,6 @@ LPS22HB::start() ScheduleNow(); } -void -LPS22HB::stop() -{ - ScheduleClear(); -} - int LPS22HB::reset() { @@ -191,7 +181,7 @@ LPS22HB::reset() } void -LPS22HB::Run() +LPS22HB::RunImpl() { /* collection phase? */ if (_collect_phase) { @@ -324,8 +314,9 @@ LPS22HB::read_reg(uint8_t reg, uint8_t &val) } void -LPS22HB::print_info() +LPS22HB::print_status() { + I2CSPIDriverBase::print_status(); perf_print_counter(_sample_perf); perf_print_counter(_comms_errors); diff --git a/src/drivers/barometer/lps22hb/LPS22HB.hpp b/src/drivers/barometer/lps22hb/LPS22HB.hpp index fa87d29859..8d0d6fc5bc 100644 --- a/src/drivers/barometer/lps22hb/LPS22HB.hpp +++ b/src/drivers/barometer/lps22hb/LPS22HB.hpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -77,24 +78,26 @@ static constexpr uint8_t TEMP_OUT_L = 0x2B; static constexpr uint8_t TEMP_OUT_H = 0x2C; /* interface factories */ -extern device::Device *LPS22HB_SPI_interface(int bus); -extern device::Device *LPS22HB_I2C_interface(int bus); -typedef device::Device *(*LPS22HB_constructor)(int); +extern device::Device *LPS22HB_SPI_interface(int bus, uint32_t devid, int bus_frequency, spi_mode_e spi_mode); +extern device::Device *LPS22HB_I2C_interface(int bus, int bus_frequency); -class LPS22HB : public cdev::CDev, public px4::ScheduledWorkItem +class LPS22HB : public cdev::CDev, public I2CSPIDriver { public: - LPS22HB(device::Device *interface, const char *path); + LPS22HB(I2CSPIBusOption bus_option, int bus, device::Device *interface); virtual ~LPS22HB(); + static I2CSPIDriverBase *instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, + int runtime_instance); + static void print_usage(); + virtual int init(); virtual int ioctl(struct file *filp, int cmd, unsigned long arg); - /** - * Diagnostics - print some basic information about the driver. - */ - void print_info(); + void print_status(); + + void RunImpl(); protected: device::Device *_interface; @@ -122,30 +125,11 @@ private: */ void start(); - /** - * Stop the automatic measurement state machine. - */ - void stop(); - /** * Reset the device */ int reset(); - /** - * 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 Run() override; /** * Write a register. diff --git a/src/drivers/barometer/lps22hb/LPS22HB_I2C.cpp b/src/drivers/barometer/lps22hb/LPS22HB_I2C.cpp index 83794cbde5..dd643c5ebc 100644 --- a/src/drivers/barometer/lps22hb/LPS22HB_I2C.cpp +++ b/src/drivers/barometer/lps22hb/LPS22HB_I2C.cpp @@ -41,12 +41,12 @@ #define LPS22HB_ADDRESS 0x5D -device::Device *LPS22HB_I2C_interface(int bus); +device::Device *LPS22HB_I2C_interface(int bus, int bus_frequency); class LPS22HB_I2C : public device::I2C { public: - LPS22HB_I2C(int bus); + LPS22HB_I2C(int bus, int bus_frequency); virtual ~LPS22HB_I2C() = default; virtual int read(unsigned address, void *data, unsigned count); @@ -58,13 +58,13 @@ protected: }; device::Device * -LPS22HB_I2C_interface(int bus) +LPS22HB_I2C_interface(int bus, int bus_frequency) { - return new LPS22HB_I2C(bus); + return new LPS22HB_I2C(bus, bus_frequency); } -LPS22HB_I2C::LPS22HB_I2C(int bus) : - I2C("LPS22HB_I2C", nullptr, bus, LPS22HB_ADDRESS, 400000) +LPS22HB_I2C::LPS22HB_I2C(int bus, int bus_frequency) : + I2C("LPS22HB_I2C", nullptr, bus, LPS22HB_ADDRESS, bus_frequency) { } diff --git a/src/drivers/barometer/lps22hb/LPS22HB_SPI.cpp b/src/drivers/barometer/lps22hb/LPS22HB_SPI.cpp index 76f1bbeac3..5999a696c6 100644 --- a/src/drivers/barometer/lps22hb/LPS22HB_SPI.cpp +++ b/src/drivers/barometer/lps22hb/LPS22HB_SPI.cpp @@ -39,18 +39,16 @@ #include "LPS22HB.hpp" -#ifdef PX4_SPIDEV_LPS22HB - /* SPI protocol address bits */ #define DIR_READ (1<<7) #define DIR_WRITE (0<<7) -device::Device *LPS22HB_SPI_interface(int bus); +device::Device *LPS22HB_SPI_interface(int bus, uint32_t devid, int bus_frequency, spi_mode_e spi_mode); class LPS22HB_SPI : public device::SPI { public: - LPS22HB_SPI(int bus, uint32_t device); + LPS22HB_SPI(int bus, uint32_t device, int bus_frequency, spi_mode_e spi_mode); virtual ~LPS22HB_SPI() = default; virtual int init(); @@ -60,12 +58,13 @@ public: }; device::Device * -LPS22HB_SPI_interface(int bus) +LPS22HB_SPI_interface(int bus, uint32_t devid, int bus_frequency, spi_mode_e spi_mode) { - return new LPS22HB_SPI(bus, PX4_SPIDEV_LPS22HB); + return new LPS22HB_SPI(bus, devid, bus_frequency, spi_mode); } -LPS22HB_SPI::LPS22HB_SPI(int bus, uint32_t device) : SPI("LPS22HB_SPI", nullptr, bus, device, SPIDEV_MODE3, 10000000) +LPS22HB_SPI::LPS22HB_SPI(int bus, uint32_t device, int bus_frequency, spi_mode_e spi_mode) + : SPI("LPS22HB_SPI", nullptr, bus, device, spi_mode, bus_frequency) { _device_id.devid_s.devtype = DRV_BARO_DEVTYPE_LPS22HB; } @@ -126,5 +125,3 @@ LPS22HB_SPI::read(unsigned address, void *data, unsigned count) memcpy(data, &buf[1], count); return ret; } - -#endif /* PX4_SPIDEV_LPS22HB */ diff --git a/src/drivers/barometer/lps22hb/lps22hb_main.cpp b/src/drivers/barometer/lps22hb/lps22hb_main.cpp index 294345640c..a23b48506c 100644 --- a/src/drivers/barometer/lps22hb/lps22hb_main.cpp +++ b/src/drivers/barometer/lps22hb/lps22hb_main.cpp @@ -32,268 +32,86 @@ ****************************************************************************/ #include "LPS22HB.hpp" +#include extern "C" __EXPORT int lps22hb_main(int argc, char *argv[]); -enum LPS22HB_BUS { - LPS22HB_BUS_ALL = 0, - LPS22HB_BUS_I2C_INTERNAL, - LPS22HB_BUS_I2C_EXTERNAL, - LPS22HB_BUS_SPI -}; -/** - * Local functions in support of the shell command. - */ -namespace lps22hb +void +LPS22HB::print_usage() { + PRINT_MODULE_USAGE_NAME("lps22hb", "driver"); + PRINT_MODULE_USAGE_SUBCATEGORY("baro"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, true); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} -struct lps22hb_bus_option { - enum LPS22HB_BUS busid; - const char *devpath; - LPS22HB_constructor interface_constructor; - uint8_t busnum; - LPS22HB *dev; -} bus_options[] = { - { LPS22HB_BUS_I2C_EXTERNAL, "/dev/lps22hb_ext", &LPS22HB_I2C_interface, PX4_I2C_BUS_EXPANSION, NULL }, -#ifdef PX4_I2C_BUS_EXPANSION1 - { LPS22HB_BUS_I2C_EXTERNAL, "/dev/lps22hb_ext1", &LPS22HB_I2C_interface, PX4_I2C_BUS_EXPANSION1, NULL }, -#endif -#ifdef PX4_I2C_BUS_EXPANSION2 - { LPS22HB_BUS_I2C_EXTERNAL, "/dev/lps22hb_ext2", &LPS22HB_I2C_interface, PX4_I2C_BUS_EXPANSION2, NULL }, -#endif -#ifdef PX4_I2C_BUS_ONBOARD - { LPS22HB_BUS_I2C_INTERNAL, "/dev/lps22hb_int", &LPS22HB_I2C_interface, PX4_I2C_BUS_ONBOARD, NULL }, -#endif -#ifdef PX4_SPIDEV_LPS22HB - { LPS22HB_BUS_SPI, "/dev/lps22hb_spi", &LPS22HB_SPI_interface, PX4_SPI_BUS_SENSOR4, NULL }, -#endif -}; -#define NUM_BUS_OPTIONS (sizeof(bus_options)/sizeof(bus_options[0])) - -int start(enum LPS22HB_BUS busid); -bool start_bus(struct lps22hb_bus_option &bus); -struct lps22hb_bus_option &find_bus(enum LPS22HB_BUS busid); -int reset(enum LPS22HB_BUS busid); -int info(); -void usage(); - -/** - * start driver for a specific bus option - */ -bool -start_bus(struct lps22hb_bus_option &bus) +I2CSPIDriverBase *LPS22HB::instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, + int runtime_instance) { - PX4_INFO("starting %s", bus.devpath); + device::Device *interface = nullptr; - if (bus.dev != nullptr) { - PX4_WARN("bus option already started"); - return false; + if (iterator.busType() == BOARD_I2C_BUS) { + interface = LPS22HB_I2C_interface(iterator.bus(), cli.bus_frequency); + + } else if (iterator.busType() == BOARD_SPI_BUS) { + interface = LPS22HB_SPI_interface(iterator.bus(), iterator.devid(), cli.bus_frequency, cli.spi_mode); } - device::Device *interface = bus.interface_constructor(bus.busnum); + if (interface == nullptr) { + PX4_ERR("failed creating interface for bus %i (devid 0x%x)", iterator.bus(), iterator.devid()); + return nullptr; + } if (interface->init() != OK) { delete interface; - PX4_WARN("no device on bus %u", (unsigned)bus.busid); - return false; + PX4_DEBUG("no device on bus %i (devid 0x%x)", iterator.bus(), iterator.devid()); + return nullptr; } - bus.dev = new LPS22HB(interface, bus.devpath); + LPS22HB *dev = new LPS22HB(iterator.configuredBusOption(), iterator.bus(), interface); - if (bus.dev != nullptr && OK != bus.dev->init()) { - PX4_WARN("init failed"); - delete bus.dev; - bus.dev = nullptr; - return false; + if (dev == nullptr) { + delete interface; + return nullptr; } - int fd = px4_open(bus.devpath, O_RDONLY); - - /* set the poll rate to default, starts automatic data collection */ - if (fd == -1) { - PX4_ERR("can't open baro device"); - return false; + if (OK != dev->init()) { + delete dev; + return nullptr; } - if (px4_ioctl(fd, SENSORIOCSPOLLRATE, SENSOR_POLLRATE_DEFAULT) < 0) { - px4_close(fd); - PX4_ERR("failed setting default poll rate"); - return false; - } - - px4_close(fd); - - return true; + return dev; } - -/** - * Start the driver. - * - * This function call only returns once the driver - * is either successfully up and running or failed to start. - */ -int -start(enum LPS22HB_BUS busid) +extern "C" int lps22hb_main(int argc, char *argv[]) { - bool started = false; + using ThisDriver = LPS22HB; + BusCLIArguments cli{true, true}; + cli.default_spi_frequency = 10 * 1000 * 1000; - for (unsigned i = 0; i < NUM_BUS_OPTIONS; i++) { - if (busid == LPS22HB_BUS_ALL && bus_options[i].dev != NULL) { - // this device is already started - continue; - } + const char *verb = cli.parseDefaultArguments(argc, argv); - if (busid != LPS22HB_BUS_ALL && bus_options[i].busid != busid) { - // not the one that is asked for - continue; - } - - started |= start_bus(bus_options[i]); - } - - if (!started) { - return PX4_ERROR; - } - - return PX4_OK; -} - -/** - * find a bus structure for a busid - */ -struct lps22hb_bus_option &find_bus(enum LPS22HB_BUS busid) -{ - for (unsigned i = 0; i < NUM_BUS_OPTIONS; i++) { - if ((busid == LPS22HB_BUS_ALL || - busid == bus_options[i].busid) && bus_options[i].dev != NULL) { - return bus_options[i]; - } - } - - errx(1, "bus %u not started", (unsigned)busid); -} - -/** - * Reset the driver. - */ -int -reset(enum LPS22HB_BUS busid) -{ - struct lps22hb_bus_option &bus = find_bus(busid); - const char *path = bus.devpath; - - int fd = open(path, O_RDONLY); - - if (fd < 0) { - PX4_ERR("failed"); - return PX4_ERROR; - } - - if (px4_ioctl(fd, SENSORIOCRESET, 0) < 0) { - PX4_ERR("driver reset failed"); - return PX4_ERROR; - } - - if (px4_ioctl(fd, SENSORIOCSPOLLRATE, SENSOR_POLLRATE_DEFAULT) < 0) { - PX4_ERR("driver poll restart failed"); - return PX4_ERROR; - } - - return 0; -} - -/** - * Print a little info about the driver. - */ -int -info() -{ - for (uint8_t i = 0; i < NUM_BUS_OPTIONS; i++) { - struct lps22hb_bus_option &bus = bus_options[i]; - - if (bus.dev != nullptr) { - warnx("%s", bus.devpath); - bus.dev->print_info(); - } - } - - return 0; -} - -void -usage() -{ - PX4_INFO("missing command: try 'start', 'info', 'reset'"); - PX4_INFO("options:"); - PX4_INFO(" -X (external I2C bus)"); - PX4_INFO(" -I (internal I2C bus)"); - PX4_INFO(" -S (external SPI bus)"); -} - -} // namespace - -int -lps22hb_main(int argc, char *argv[]) -{ - int myoptind = 1; - int ch; - const char *myoptarg = nullptr; - - enum LPS22HB_BUS busid = LPS22HB_BUS_ALL; - - while ((ch = px4_getopt(argc, argv, "IXS", &myoptind, &myoptarg)) != EOF) { - switch (ch) { -#if (PX4_I2C_BUS_ONBOARD) - - case 'I': - busid = LPS22HB_BUS_I2C_INTERNAL; - break; -#endif /* PX4_I2C_BUS_ONBOARD */ - - case 'X': - busid = LPS22HB_BUS_I2C_EXTERNAL; - break; - - case 'S': - busid = LPS22HB_BUS_SPI; - break; - - default: - lps22hb::usage(); - return 0; - } - } - - if (myoptind >= argc) { - lps22hb::usage(); + if (!verb) { + ThisDriver::print_usage(); return -1; } - const char *verb = argv[myoptind]; + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_BARO_DEVTYPE_LPS22HB); - /* - * Start/load the driver. - */ if (!strcmp(verb, "start")) { - return lps22hb::start(busid); + return ThisDriver::module_start(cli, iterator); } - /* - * Reset the driver. - */ - if (!strcmp(verb, "reset")) { - return lps22hb::reset(busid); + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); } - /* - * Print driver information. - */ - if (!strcmp(verb, "info")) { - return lps22hb::info(); + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); } - PX4_WARN("unrecognised command, try 'start', 'reset' or 'info'"); - return 0; + ThisDriver::print_usage(); + return -1; }