mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-07-04 07:20:35 +08:00
refactor ak09916: use driver base class
This commit is contained in:
@@ -42,101 +42,17 @@
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <lib/conversion/rotation.h>
|
||||
#include <px4_platform_common/getopt.h>
|
||||
#include <px4_platform_common/module.h>
|
||||
|
||||
#include "ak09916.hpp"
|
||||
|
||||
|
||||
extern "C" { __EXPORT int ak09916_main(int argc, char *argv[]); }
|
||||
extern "C" __EXPORT int ak09916_main(int argc, char *argv[]);
|
||||
|
||||
|
||||
namespace ak09916
|
||||
{
|
||||
|
||||
AK09916 *g_dev_ext;
|
||||
AK09916 *g_dev_int;
|
||||
|
||||
void start(bool, enum Rotation);
|
||||
void info(bool);
|
||||
void usage();
|
||||
|
||||
void start(bool external_bus, enum Rotation rotation)
|
||||
{
|
||||
AK09916 **g_dev_ptr = (external_bus ? &g_dev_ext : &g_dev_int);
|
||||
const char *path = (external_bus ? AK09916_DEVICE_PATH_MAG_EXT : AK09916_DEVICE_PATH_MAG);
|
||||
|
||||
if (*g_dev_ptr != nullptr) {
|
||||
PX4_ERR("already started");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (external_bus) {
|
||||
#if defined(PX4_I2C_BUS_EXPANSION)
|
||||
*g_dev_ptr = new AK09916(PX4_I2C_BUS_EXPANSION, path, rotation);
|
||||
#else
|
||||
PX4_ERR("External I2C not available");
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
} else {
|
||||
PX4_ERR("Internal I2C not available");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if (*g_dev_ptr == nullptr || (OK != (*g_dev_ptr)->init())) {
|
||||
PX4_ERR("driver start failed");
|
||||
delete (*g_dev_ptr);
|
||||
*g_dev_ptr = nullptr;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
stop(bool external_bus)
|
||||
{
|
||||
AK09916 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int;
|
||||
|
||||
if (*g_dev_ptr == nullptr) {
|
||||
PX4_ERR("driver not running");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
(*g_dev_ptr)->stop();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
info(bool external_bus)
|
||||
{
|
||||
AK09916 **g_dev_ptr = external_bus ? &g_dev_ext : &g_dev_int;
|
||||
|
||||
if (*g_dev_ptr == nullptr) {
|
||||
PX4_ERR("driver not running");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("state @ %p\n", *g_dev_ptr);
|
||||
(*g_dev_ptr)->print_info();
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
usage()
|
||||
{
|
||||
PX4_INFO("missing command: try 'start', 'info', stop'");
|
||||
PX4_INFO("options:");
|
||||
PX4_INFO(" -X (external bus)");
|
||||
PX4_INFO(" -R (rotation)");
|
||||
}
|
||||
|
||||
} // namespace ak09916
|
||||
|
||||
AK09916::AK09916(int bus, const char *path, enum Rotation rotation) :
|
||||
I2C("AK09916", path, bus, AK09916_I2C_ADDR, 400000),
|
||||
ScheduledWorkItem(MODULE_NAME, px4::device_bus_to_wq(get_device_id())),
|
||||
AK09916::AK09916(I2CSPIBusOption bus_option, const int bus, int bus_frequency, enum Rotation rotation) :
|
||||
I2C("AK09916", nullptr, bus, AK09916_I2C_ADDR, bus_frequency),
|
||||
I2CSPIDriver(MODULE_NAME, px4::device_bus_to_wq(get_device_id()), bus_option, bus),
|
||||
_px4_mag(get_device_id(), ORB_PRIO_MAX, rotation),
|
||||
_mag_reads(perf_alloc(PC_COUNT, "ak09916_mag_reads")),
|
||||
_mag_errors(perf_alloc(PC_COUNT, "ak09916_mag_errors")),
|
||||
@@ -161,7 +77,7 @@ AK09916::init()
|
||||
int ret = I2C::init();
|
||||
|
||||
if (ret != OK) {
|
||||
PX4_WARN("AK09916 mag init failed");
|
||||
DEVICE_DEBUG("AK09916 mag init failed (%i)", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -229,8 +145,9 @@ AK09916::measure()
|
||||
}
|
||||
|
||||
void
|
||||
AK09916::print_info()
|
||||
AK09916::print_status()
|
||||
{
|
||||
I2CSPIDriverBase::print_status();
|
||||
perf_print_counter(_mag_reads);
|
||||
perf_print_counter(_mag_errors);
|
||||
perf_print_counter(_mag_overruns);
|
||||
@@ -308,78 +225,82 @@ AK09916::setup()
|
||||
void
|
||||
AK09916::start()
|
||||
{
|
||||
_cycle_interval = AK09916_CONVERSION_INTERVAL_us;
|
||||
|
||||
ScheduleNow();
|
||||
}
|
||||
|
||||
void
|
||||
AK09916::stop()
|
||||
AK09916::RunImpl()
|
||||
{
|
||||
// Ensure no new items are queued while we cancel this one.
|
||||
_cycle_interval = 0;
|
||||
try_measure();
|
||||
ScheduleDelayed(_cycle_interval);
|
||||
}
|
||||
|
||||
ScheduleClear();
|
||||
I2CSPIDriverBase *
|
||||
AK09916::instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, int runtime_instance)
|
||||
{
|
||||
AK09916 *interface = new AK09916(iterator.configuredBusOption(), iterator.bus(), cli.bus_frequency, cli.rotation);
|
||||
|
||||
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_DEBUG("no device on bus %i (devid 0x%x)", iterator.bus(), iterator.devid());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return interface;
|
||||
}
|
||||
|
||||
void
|
||||
AK09916::Run()
|
||||
AK09916::print_usage()
|
||||
{
|
||||
if (_cycle_interval == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try_measure();
|
||||
|
||||
if (_cycle_interval > 0) {
|
||||
ScheduleDelayed(_cycle_interval);
|
||||
}
|
||||
PRINT_MODULE_USAGE_NAME("ak09916", "driver");
|
||||
PRINT_MODULE_USAGE_SUBCATEGORY("magnetometer");
|
||||
PRINT_MODULE_USAGE_COMMAND("start");
|
||||
PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false);
|
||||
PRINT_MODULE_USAGE_PARAM_INT('R', 0, 0, 35, "Rotation", true);
|
||||
PRINT_MODULE_USAGE_DEFAULT_COMMANDS();
|
||||
}
|
||||
|
||||
int
|
||||
ak09916_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 = AK09916;
|
||||
BusCLIArguments cli{true, false};
|
||||
|
||||
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:
|
||||
ak09916::usage();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (myoptind >= argc) {
|
||||
ak09916::usage();
|
||||
const char *verb = cli.optarg();
|
||||
|
||||
if (!verb) {
|
||||
ThisDriver::print_usage();
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *verb = argv[myoptind];
|
||||
BusInstanceIterator iterator(MODULE_NAME, cli, DRV_MAG_DEVTYPE_AK09916);
|
||||
|
||||
if (!strcmp(verb, "start")) {
|
||||
ak09916::start(external_bus, rotation);
|
||||
return ThisDriver::module_start(cli, iterator);
|
||||
}
|
||||
|
||||
if (!strcmp(verb, "stop")) {
|
||||
ak09916::stop(external_bus);
|
||||
return ThisDriver::module_stop(iterator);
|
||||
}
|
||||
|
||||
if (!strcmp(verb, "info")) {
|
||||
ak09916::info(external_bus);
|
||||
if (!strcmp(verb, "status")) {
|
||||
return ThisDriver::module_status(iterator);
|
||||
}
|
||||
|
||||
ak09916::usage();
|
||||
return -1;
|
||||
ThisDriver::print_usage();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -39,12 +39,9 @@
|
||||
#include <systemlib/conversions.h>
|
||||
#include <drivers/drv_hrt.h>
|
||||
#include <drivers/device/i2c.h>
|
||||
#include <px4_platform_common/px4_work_queue/ScheduledWorkItem.hpp>
|
||||
#include <px4_platform_common/i2c_spi_buses.h>
|
||||
#include <lib/drivers/magnetometer/PX4Magnetometer.hpp>
|
||||
|
||||
static constexpr auto AK09916_DEVICE_PATH_MAG = "/dev/ak09916_i2c_int";
|
||||
static constexpr auto AK09916_DEVICE_PATH_MAG_EXT = "/dev/ak09916_i2c_ext";
|
||||
|
||||
// in 16-bit sampling mode the mag resolution is 1.5 milli Gauss per bit.
|
||||
static constexpr float AK09916_MAG_RANGE_GA = 1.5e-3f;
|
||||
|
||||
@@ -80,23 +77,27 @@ struct ak09916_regs {
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
class AK09916 : public device::I2C, px4::ScheduledWorkItem
|
||||
class AK09916 : public device::I2C, public I2CSPIDriver<AK09916>
|
||||
{
|
||||
public:
|
||||
AK09916(int bus, const char *path, enum Rotation rotation);
|
||||
~AK09916();
|
||||
AK09916(I2CSPIBusOption bus_option, const int bus, int bus_frequency, enum Rotation rotation);
|
||||
virtual ~AK09916();
|
||||
|
||||
virtual int init() override;
|
||||
static I2CSPIDriverBase *instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator,
|
||||
int runtime_instance);
|
||||
static void print_usage();
|
||||
|
||||
int init() override;
|
||||
void start();
|
||||
void stop();
|
||||
void print_info();
|
||||
int probe();
|
||||
void print_status() override;
|
||||
int probe() override;
|
||||
|
||||
void RunImpl();
|
||||
|
||||
protected:
|
||||
int setup();
|
||||
int setup_master_i2c();
|
||||
bool check_id();
|
||||
void Run();
|
||||
void try_measure();
|
||||
bool is_ready();
|
||||
void measure();
|
||||
@@ -110,7 +111,7 @@ private:
|
||||
|
||||
PX4Magnetometer _px4_mag;
|
||||
|
||||
uint32_t _cycle_interval{0};
|
||||
static constexpr uint32_t _cycle_interval{AK09916_CONVERSION_INTERVAL_us};
|
||||
|
||||
perf_counter_t _mag_reads;
|
||||
perf_counter_t _mag_errors;
|
||||
|
||||
Reference in New Issue
Block a user