|
|
|
@ -36,188 +36,84 @@
@@ -36,188 +36,84 @@
|
|
|
|
|
|
|
|
|
|
#include "voxlpm.hpp" |
|
|
|
|
|
|
|
|
|
enum VOXLPM_BUS { |
|
|
|
|
VOXLPM_BUS_I2C_EXTERNAL, |
|
|
|
|
VOXLPM_BUS_I2C_EXTERNAL1, |
|
|
|
|
VOXLPM_BUS_I2C_EXTERNAL2 |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Local functions in support of the shell command. |
|
|
|
|
*/ |
|
|
|
|
namespace voxlpm |
|
|
|
|
I2CSPIDriverBase *VOXLPM::instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, |
|
|
|
|
int runtime_instance) |
|
|
|
|
{ |
|
|
|
|
struct voxlpm_chan { |
|
|
|
|
const char *devpath; |
|
|
|
|
uint32_t device; |
|
|
|
|
VOXLPM *dev; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
struct voxlpm_bus_option { |
|
|
|
|
enum VOXLPM_BUS busid; |
|
|
|
|
uint8_t busnum; |
|
|
|
|
bool external; |
|
|
|
|
struct voxlpm_chan vbat; |
|
|
|
|
struct voxlpm_chan vpwr; |
|
|
|
|
} bus_options[] = { |
|
|
|
|
#if defined(PX4_I2C_BUS_EXPANSION) |
|
|
|
|
{ |
|
|
|
|
VOXLPM_BUS_I2C_EXTERNAL, PX4_I2C_BUS_EXPANSION, true, |
|
|
|
|
{"/dev/voxlpm_vbat", VOXLPM_LTC2946_ADDR_VBATT, NULL }, |
|
|
|
|
{"/dev/voxlpm_p5vd", VOXLPM_LTC2946_ADDR_P5VD, NULL} |
|
|
|
|
}, |
|
|
|
|
#endif |
|
|
|
|
#if defined(PX4_I2C_BUS_EXPANSION1) |
|
|
|
|
{ |
|
|
|
|
VOXLPM_BUS_I2C_EXTERNAL1, PX4_I2C_BUS_EXPANSION1, true, |
|
|
|
|
{"/dev/voxlpm_vbat", VOXLPM_LTC2946_ADDR_VBATT, NULL }, |
|
|
|
|
{"/dev/voxlpm_p5vd", VOXLPM_LTC2946_ADDR_P5VD, NULL} |
|
|
|
|
}, |
|
|
|
|
#endif |
|
|
|
|
#if defined(PX4_I2C_BUS_EXPANSION2) |
|
|
|
|
{ |
|
|
|
|
VOXLPM_BUS_I2C_EXTERNAL2, PX4_I2C_BUS_EXPANSION2, true, |
|
|
|
|
{"/dev/voxlpm_vbat", VOXLPM_LTC2946_ADDR_VBATT, NULL }, |
|
|
|
|
{"/dev/voxlpm_p5vd", VOXLPM_LTC2946_ADDR_P5VD, NULL} |
|
|
|
|
}, |
|
|
|
|
#endif |
|
|
|
|
}; |
|
|
|
|
#define NUM_BUS_OPTIONS (sizeof(bus_options)/sizeof(bus_options[0])) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Start the driver. |
|
|
|
|
*/ |
|
|
|
|
bool |
|
|
|
|
start_bus(struct voxlpm_bus_option &bus) |
|
|
|
|
{ |
|
|
|
|
/* assume if we've got the battery channel we have the output channel as well */ |
|
|
|
|
if (bus.vbat.dev != nullptr) { |
|
|
|
|
PX4_ERR("bus option already started"); |
|
|
|
|
exit(1); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* create the battery voltage / current channel */ |
|
|
|
|
bus.vbat.dev = new VOXLPM(bus.vbat.devpath, bus.busnum, bus.vbat.device, VOXLPM_CH_TYPE_VBATT); |
|
|
|
|
|
|
|
|
|
if (bus.vbat.dev == nullptr) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* create the 5VDC output / compute current channel */ |
|
|
|
|
bus.vpwr.dev = new VOXLPM(bus.vpwr.devpath, bus.busnum, bus.vpwr.device, VOXLPM_CH_TYPE_P5VDC); |
|
|
|
|
|
|
|
|
|
if (bus.vbat.dev == nullptr) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (bus.vbat.dev->init() != OK || bus.vpwr.dev->init() != OK) { |
|
|
|
|
delete bus.vbat.dev; |
|
|
|
|
bus.vbat.dev = nullptr; |
|
|
|
|
delete bus.vpwr.dev; |
|
|
|
|
bus.vpwr.dev = nullptr; |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
start(enum VOXLPM_BUS busid) |
|
|
|
|
{ |
|
|
|
|
bool started = false; |
|
|
|
|
uint8_t i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_BUS_OPTIONS; i++) { |
|
|
|
|
if (bus_options[i].busid == busid) { |
|
|
|
|
started = start_bus(bus_options[i]); |
|
|
|
|
break; // one bus only...
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
VOXLPM *instance = new VOXLPM(iterator.configuredBusOption(), iterator.bus(), cli.bus_frequency, |
|
|
|
|
(VOXLPM_CH_TYPE)cli.type); |
|
|
|
|
|
|
|
|
|
if (!started) { |
|
|
|
|
PX4_WARN("bus option number is %d", i); |
|
|
|
|
PX4_ERR("driver start failed"); |
|
|
|
|
exit(1); |
|
|
|
|
if (instance == nullptr) { |
|
|
|
|
PX4_ERR("alloc failed"); |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
info() |
|
|
|
|
{ |
|
|
|
|
uint8_t i; |
|
|
|
|
|
|
|
|
|
for (i = 0; i < NUM_BUS_OPTIONS; i++) { |
|
|
|
|
if (bus_options[i].vbat.dev) { |
|
|
|
|
bus_options[i].vbat.dev->print_info(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (bus_options[i].vpwr.dev) { |
|
|
|
|
bus_options[i].vpwr.dev->print_info(); |
|
|
|
|
} |
|
|
|
|
if (OK != instance->init()) { |
|
|
|
|
delete instance; |
|
|
|
|
return nullptr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
exit(0); |
|
|
|
|
return instance; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void |
|
|
|
|
usage() |
|
|
|
|
VOXLPM::print_usage() |
|
|
|
|
{ |
|
|
|
|
PRINT_MODULE_USAGE_NAME_SIMPLE("voxlpm", "command"); |
|
|
|
|
PRINT_MODULE_USAGE_NAME_SIMPLE("voxlpm", "driver"); |
|
|
|
|
|
|
|
|
|
PRINT_MODULE_USAGE_COMMAND_DESCR("start", "start monitoring"); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND_DESCR("info", "display info");; |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND_DESCR("-X", "PX4_I2C_BUS_EXPANSION"); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND_DESCR("-T", "PX4_I2C_BUS_EXPANSION1"); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND_DESCR("-R", "PX4_I2C_BUS_EXPANSION2 (default)"); |
|
|
|
|
PRINT_MODULE_USAGE_COMMAND("start"); |
|
|
|
|
PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); |
|
|
|
|
PRINT_MODULE_USAGE_PARAM_STRING('T', "VBATT", "VBATT|P5VDC", "Type", true); |
|
|
|
|
PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
|
|
extern "C" __EXPORT int voxlpm_main(int argc, char *argv[]) |
|
|
|
|
extern "C" int |
|
|
|
|
voxlpm_main(int argc, char *argv[]) |
|
|
|
|
{ |
|
|
|
|
int myoptind = 1; |
|
|
|
|
int ch; |
|
|
|
|
const char *myoptarg = nullptr; |
|
|
|
|
enum VOXLPM_BUS busid = VOXLPM_BUS_I2C_EXTERNAL2; |
|
|
|
|
using ThisDriver = VOXLPM; |
|
|
|
|
BusCLIArguments cli{true, false}; |
|
|
|
|
cli.default_i2c_frequency = 400000; |
|
|
|
|
cli.type = VOXLPM_CH_TYPE_VBATT; |
|
|
|
|
|
|
|
|
|
while ((ch = px4_getopt(argc, argv, "XTR", &myoptind, &myoptarg)) != EOF) { |
|
|
|
|
while ((ch = cli.getopt(argc, argv, "T:")) != EOF) { |
|
|
|
|
switch (ch) { |
|
|
|
|
case 'X': |
|
|
|
|
busid = VOXLPM_BUS_I2C_EXTERNAL; |
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
case 'T': |
|
|
|
|
busid = VOXLPM_BUS_I2C_EXTERNAL1; |
|
|
|
|
break; |
|
|
|
|
if (strcmp(cli.optarg(), "VBATT") == 0) { |
|
|
|
|
cli.type = VOXLPM_CH_TYPE_VBATT; |
|
|
|
|
|
|
|
|
|
case 'R': |
|
|
|
|
busid = VOXLPM_BUS_I2C_EXTERNAL2; |
|
|
|
|
break; |
|
|
|
|
} else if (strcmp(cli.optarg(), "P5VDC") == 0) { |
|
|
|
|
cli.type = VOXLPM_CH_TYPE_P5VDC; |
|
|
|
|
|
|
|
|
|
} else { |
|
|
|
|
PX4_ERR("unknown type"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
default: |
|
|
|
|
voxlpm::usage(); |
|
|
|
|
return 0; |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (myoptind >= argc) { |
|
|
|
|
voxlpm::usage(); |
|
|
|
|
const char *verb = cli.optarg(); |
|
|
|
|
|
|
|
|
|
if (!verb) { |
|
|
|
|
ThisDriver::print_usage(); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char *verb = argv[myoptind]; |
|
|
|
|
BusInstanceIterator iterator(MODULE_NAME, cli, DRV_POWER_DEVTYPE_VOXLPM); |
|
|
|
|
|
|
|
|
|
if (!strcmp(verb, "start")) { |
|
|
|
|
voxlpm::start(busid); |
|
|
|
|
return ThisDriver::module_start(cli, iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!strcmp(verb, "stop")) { |
|
|
|
|
return ThisDriver::module_stop(iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!strcmp(verb, "info")) { |
|
|
|
|
voxlpm::info(); |
|
|
|
|
if (!strcmp(verb, "status")) { |
|
|
|
|
return ThisDriver::module_status(iterator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
voxlpm::usage(); |
|
|
|
|
ThisDriver::print_usage(); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|