diff --git a/boards/px4/fmu-v3/default.cmake b/boards/px4/fmu-v3/default.cmake index e996050b2e..d1668699ee 100644 --- a/boards/px4/fmu-v3/default.cmake +++ b/boards/px4/fmu-v3/default.cmake @@ -19,6 +19,7 @@ px4_add_board( TEL4:/dev/ttyS6 DRIVERS adc/board_adc + adc/ads1115 barometer # all available barometer drivers batt_smbus camera_capture diff --git a/boards/px4/fmu-v4/default.cmake b/boards/px4/fmu-v4/default.cmake index 686983ea86..e673d16591 100644 --- a/boards/px4/fmu-v4/default.cmake +++ b/boards/px4/fmu-v4/default.cmake @@ -15,6 +15,7 @@ px4_add_board( TEL2:/dev/ttyS2 DRIVERS adc/board_adc + adc/ads1115 barometer # all available barometer drivers batt_smbus camera_capture diff --git a/boards/px4/fmu-v4pro/default.cmake b/boards/px4/fmu-v4pro/default.cmake index 4363d66942..e077ee3abe 100644 --- a/boards/px4/fmu-v4pro/default.cmake +++ b/boards/px4/fmu-v4pro/default.cmake @@ -18,6 +18,7 @@ px4_add_board( TEL4:/dev/ttyS6 DRIVERS adc/board_adc + adc/ads1115 barometer # all available barometer drivers batt_smbus camera_capture diff --git a/boards/px4/fmu-v5/default.cmake b/boards/px4/fmu-v5/default.cmake index 96c0e53bec..d3ceb4a54b 100644 --- a/boards/px4/fmu-v5/default.cmake +++ b/boards/px4/fmu-v5/default.cmake @@ -17,6 +17,7 @@ px4_add_board( TEL4:/dev/ttyS3 DRIVERS adc/board_adc + adc/ads1115 barometer # all available barometer drivers batt_smbus camera_capture diff --git a/boards/px4/fmu-v5x/default.cmake b/boards/px4/fmu-v5x/default.cmake index 9b4bd1b365..6ff61f13bc 100644 --- a/boards/px4/fmu-v5x/default.cmake +++ b/boards/px4/fmu-v5x/default.cmake @@ -18,6 +18,7 @@ px4_add_board( GPS2:/dev/ttyS7 DRIVERS adc/board_adc + adc/ads1115 barometer # all available barometer drivers batt_smbus camera_capture diff --git a/boards/px4/raspberrypi/default.cmake b/boards/px4/raspberrypi/default.cmake index 53ccae512d..c5241b1a32 100644 --- a/boards/px4/raspberrypi/default.cmake +++ b/boards/px4/raspberrypi/default.cmake @@ -11,6 +11,7 @@ px4_add_board( TOOLCHAIN arm-linux-gnueabihf TESTING DRIVERS + adc/ads1115 #barometer # all available barometer drivers barometer/ms5611 batt_smbus diff --git a/src/drivers/adc/ads1115/ADS1115.cpp b/src/drivers/adc/ads1115/ADS1115.cpp new file mode 100644 index 0000000000..a54fb8b91d --- /dev/null +++ b/src/drivers/adc/ads1115/ADS1115.cpp @@ -0,0 +1,197 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#include "ADS1115.h" +#include + +int ADS1115::init() +{ + int ret = I2C::init(); + + if (ret != PX4_OK) { + PX4_ERR("I2C init failed"); + return ret; + } + + uint8_t config[2] = {}; + config[0] = CONFIG_HIGH_OS_NOACT | CONFIG_HIGH_MUX_P0NG | CONFIG_HIGH_PGA_6144 | CONFIG_HIGH_MODE_SS; + config[1] = CONFIG_LOW_DR_250SPS | CONFIG_LOW_COMP_MODE_TRADITIONAL | CONFIG_LOW_COMP_POL_RESET | + CONFIG_LOW_COMP_LAT_NONE | CONFIG_LOW_COMP_QU_DISABLE; + return writeReg(ADDRESSPOINTER_REG_CONFIG, config, 2); +} + +int ADS1115::setChannel(ADS1115::ChannelSelection ch) +{ + uint8_t buf[2] = {}; + uint8_t next_mux_reg = CONFIG_HIGH_MUX_P0NG; + + switch (ch) { + case A0: + next_mux_reg = CONFIG_HIGH_MUX_P0NG; + break; + + case A1: + next_mux_reg = CONFIG_HIGH_MUX_P1NG; + break; + + case A2: + next_mux_reg = CONFIG_HIGH_MUX_P2NG; + break; + + case A3: + next_mux_reg = CONFIG_HIGH_MUX_P3NG; + break; + + default: + assert(false); + break; + } + + buf[0] = CONFIG_HIGH_OS_START_SINGLE | next_mux_reg | CONFIG_HIGH_PGA_6144 | CONFIG_HIGH_MODE_SS; + buf[1] = CONFIG_LOW_DR_250SPS | CONFIG_LOW_COMP_MODE_TRADITIONAL | CONFIG_LOW_COMP_POL_RESET | + CONFIG_LOW_COMP_LAT_NONE | CONFIG_LOW_COMP_QU_DISABLE; + return writeReg(ADDRESSPOINTER_REG_CONFIG, buf, 2); // must write whole register to take effect +} + +bool ADS1115::isSampleReady() +{ + uint8_t buf[1] = {0x00}; + + if (readReg(ADDRESSPOINTER_REG_CONFIG, buf, 1) != 0) { return false; } // Pull config register + + return (buf[0] & (uint8_t) 0x80); +} + +ADS1115::ChannelSelection ADS1115::getMeasurement(int16_t *value) +{ + uint8_t buf[2] = {0x00}; + readReg(ADDRESSPOINTER_REG_CONFIG, buf, 1); // Pull config register + ChannelSelection channel; + + switch ((buf[0] & (uint8_t) 0x70) >> 4) { + case 0x04: + channel = A0; + break; + + case 0x05: + channel = A1; + break; + + case 0x06: + channel = A2; + break; + + case 0x07: + channel = A3; + break; + + default: + return Invalid; + } + + readReg(ADDRESSPOINTER_REG_CONVERSATION, buf, 2); + uint16_t raw_adc_val = buf[0] * 256 + buf[1]; + + if (raw_adc_val & (uint16_t) 0x8000) { // Negetive value + raw_adc_val = ~raw_adc_val + 1; // 2's complement + *value = -raw_adc_val; + + } else { + *value = raw_adc_val; + } + + return channel; +} + +ADS1115::ChannelSelection ADS1115::cycleMeasure(int16_t *value) +{ + uint8_t buf[2] = {0x00}; + readReg(ADDRESSPOINTER_REG_CONFIG, buf, 1); // Pull config register + ChannelSelection channel; + uint8_t next_mux_reg = CONFIG_HIGH_MUX_P0NG; + + switch ((buf[0] & (uint8_t) 0x70) >> 4) { + case 0x04: + channel = A0; + next_mux_reg = CONFIG_HIGH_MUX_P1NG; + break; + + case 0x05: + channel = A1; + next_mux_reg = CONFIG_HIGH_MUX_P2NG; + break; + + case 0x06: + channel = A2; + next_mux_reg = CONFIG_HIGH_MUX_P3NG; + break; + + case 0x07: + channel = A3; + next_mux_reg = CONFIG_HIGH_MUX_P0NG; + break; + + default: + return Invalid; + } + + readReg(ADDRESSPOINTER_REG_CONVERSATION, buf, 2); + uint16_t raw_adc_val = buf[0] * 256 + buf[1]; + + if (raw_adc_val & (uint16_t) 0x8000) { // Negetive value + raw_adc_val = ~raw_adc_val + 1; // 2's complement + *value = -raw_adc_val; + + } else { + *value = raw_adc_val; + } + + buf[0] = CONFIG_HIGH_OS_START_SINGLE | next_mux_reg | CONFIG_HIGH_PGA_6144 | CONFIG_HIGH_MODE_SS; + buf[1] = CONFIG_LOW_DR_250SPS | CONFIG_LOW_COMP_MODE_TRADITIONAL | CONFIG_LOW_COMP_POL_RESET | + CONFIG_LOW_COMP_LAT_NONE | CONFIG_LOW_COMP_QU_DISABLE; + writeReg(ADDRESSPOINTER_REG_CONFIG, buf, 2); // must write whole register to take effect + return channel; +} + +int ADS1115::readReg(uint8_t addr, uint8_t *buf, size_t len) +{ + return transfer(&addr, 1, buf, len); +} + +int ADS1115::writeReg(uint8_t addr, uint8_t *buf, size_t len) +{ + uint8_t buffer[len + 1]; + buffer[0] = addr; + memcpy(buffer + 1, buf, sizeof(uint8_t)*len); + return transfer(buffer, len + 1, nullptr, 0); +} \ No newline at end of file diff --git a/src/drivers/adc/ads1115/ADS1115.h b/src/drivers/adc/ads1115/ADS1115.h new file mode 100644 index 0000000000..9681c8ef26 --- /dev/null +++ b/src/drivers/adc/ads1115/ADS1115.h @@ -0,0 +1,162 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#define ADDRESSPOINTER_REG_CONVERSATION 0x00 +#define ADDRESSPOINTER_REG_CONFIG 0x01 +#define ADDRESSPOINTER_REG_LO_THRESH 0x02 +#define ADDRESSPOINTER_REG_HI_THRESH 0x03 +#define CONVERSION_REG_RESET 0x00 +#define CONFIG_HIGH_OS_RESET 0x80 +#define CONFIG_HIGH_OS_NOACT 0x00 +#define CONFIG_HIGH_OS_START_SINGLE 0x80 +#define CONFIG_HIGH_MUX_RESET 0x00 +#define CONFIG_HIGH_MUX_P0N1 0x00 +#define CONFIG_HIGH_MUX_P0N3 0x10 +#define CONFIG_HIGH_MUX_P1N3 0x20 +#define CONFIG_HIGH_MUX_P2N3 0x30 +#define CONFIG_HIGH_MUX_P0NG 0x40 +#define CONFIG_HIGH_MUX_P1NG 0x50 +#define CONFIG_HIGH_MUX_P2NG 0x60 +#define CONFIG_HIGH_MUX_P3NG 0x70 +#define CONFIG_HIGH_PGA_RESET 0x02 +#define CONFIG_HIGH_PGA_6144 0x00 +#define CONFIG_HIGH_PGA_4096 0x02 +#define CONFIG_HIGH_PGA_2048 0x04 +#define CONFIG_HIGH_PGA_1024 0x06 +#define CONFIG_HIGH_PGA_0512 0x08 +#define CONFIG_HIGH_PGA_0256 0x0a +#define CONFIG_HIGH_MODE_RESET 0x01 +#define CONFIG_HIGH_MODE_SS 0x01 +#define CONFIG_HIGH_MODE_CC 0x00 + +#define CONFIG_LOW_DR_RESET 0x80 +#define CONFIG_LOW_DR_8SPS 0x00 +#define CONFIG_LOW_DR_16SPS 0x20 +#define CONFIG_LOW_DR_32SPS 0x40 +#define CONFIG_LOW_DR_64SPS 0x60 +#define CONFIG_LOW_DR_128SPS 0x80 +#define CONFIG_LOW_DR_250SPS 0xa0 +#define CONFIG_LOW_DR_475SPS 0xc0 +#define CONFIG_LOW_DR_860SPS 0xe0 +#define CONFIG_LOW_COMP_MODE_RESET 0x00 +#define CONFIG_LOW_COMP_MODE_TRADITIONAL 0x00 +#define CONFIG_LOW_COMP_MODE_WINDOW 0x10 +#define CONFIG_LOW_COMP_POL_RESET 0x00 +#define CONFIG_LOW_COMP_POL_ACTIVE_LOW 0x00 +#define CONFIG_LOW_COMP_POL_ACTIVE_HIGH 0x08 +#define CONFIG_LOW_COMP_LAT_DEFAULT 0x00 +#define CONFIG_LOW_COMP_LAT_NONE 0x00 +#define CONFIG_LOW_COMP_LAT_LATCH 0x04 +#define CONFIG_LOW_COMP_QU_DEFAULT 0x03 +#define CONFIG_LOW_COMP_QU_AFTER1 0x00 +#define CONFIG_LOW_COMP_QU_AFTER2 0x01 +#define CONFIG_LOW_COMP_QU_AFTER4 0x02 +#define CONFIG_LOW_COMP_QU_DISABLE 0x03 + +using namespace time_literals; + +/* + * This driver configure ADS1115 into 4 channels with gnd as baseline. + * Start each sample cycle by setting sample channel. + * PGA set to 6.144V + * SPS set to 256 + * Valid output ranges from 0 to 32767 on each channel. + */ +class ADS1115 : public device::I2C, public I2CSPIDriver +{ +public: + ADS1115(I2CSPIBusOption bus_option, int bus, int addr, int bus_frequency); + ~ADS1115() override; + + int Begin(); + + int init() override; + + static I2CSPIDriverBase *instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, + int runtime_instance); + + static void print_usage(); + + void RunImpl(); + +protected: + + adc_report_s _adc_report = {}; + + void print_status() override; + + void exit_and_cleanup() override; + +private: + + uORB::Publication _to_adc_report{ORB_ID(adc_report)}; + + static const hrt_abstime SAMPLE_INTERVAL{50_ms}; + + perf_counter_t _cycle_perf; + + int _channel_cycle_count = 0; + + // ADS1115 logic part + enum ChannelSelection { + Invalid = -1, A0 = 0, A1, A2, A3 + }; + /* set multiplexer to specific channel */ + int setChannel(ChannelSelection ch); + /* return true if sample result is valid */ + bool isSampleReady(); + /* + * get adc sample. return the channel being measured. + * Invalid indicates sample failure. + */ + ChannelSelection getMeasurement(int16_t *value); + /* + * get adc sample and automatically switch to next channel and start another measurement + */ + ChannelSelection cycleMeasure(int16_t *value); + + int readReg(uint8_t addr, uint8_t *buf, size_t len); + + int writeReg(uint8_t addr, uint8_t *buf, size_t len); + +}; \ No newline at end of file diff --git a/src/drivers/adc/ads1115/CMakeLists.txt b/src/drivers/adc/ads1115/CMakeLists.txt new file mode 100644 index 0000000000..d65265709d --- /dev/null +++ b/src/drivers/adc/ads1115/CMakeLists.txt @@ -0,0 +1,41 @@ +############################################################################ +# +# Copyright (c) 2020 PX4 Development Team. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name PX4 nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ +px4_add_module( + MODULE drivers__ads1115 + MAIN ads1115 + COMPILE_FLAGS + SRCS + ads1115_main.cpp + ADS1115.cpp + DEPENDS + ) \ No newline at end of file diff --git a/src/drivers/adc/ads1115/ads1115_main.cpp b/src/drivers/adc/ads1115/ads1115_main.cpp new file mode 100644 index 0000000000..9d09f09e95 --- /dev/null +++ b/src/drivers/adc/ads1115/ads1115_main.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** + * + * Copyright (C) 2020 PX4 Development Team. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name PX4 nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/** + * @file ads1115_main.cpp + * @author SalimTerryLi + * + * Driver for the ADS1115 connected via I2C. + */ + +#include "ADS1115.h" +#include +#include + +ADS1115::ADS1115(I2CSPIBusOption bus_option, int bus, int addr, int bus_frequency) : + I2C(DRV_ADC_DEVTYPE_ADS1115, nullptr, bus, addr, bus_frequency), + I2CSPIDriver(MODULE_NAME, px4::device_bus_to_wq(get_device_id()), bus_option, bus, addr), + _cycle_perf(perf_alloc(PC_ELAPSED, MODULE_NAME": single-sample")) +{ + _adc_report.device_id = this->get_device_id(); + _adc_report.resolution = 32768; + _adc_report.v_ref = 6.144f; + + for (unsigned i = 0; i < PX4_MAX_ADC_CHANNELS; ++i) { + _adc_report.channel_id[i] = -1; + } + +} + +ADS1115::~ADS1115() +{ + ScheduleClear(); + perf_free(_cycle_perf); +} + +int ADS1115::Begin() +{ + int ret = init(); + + if (ret != PX4_OK) { + PX4_ERR("ADS1115 init failed"); + return ret; + } + + setChannel(ADS1115::A0); // prepare for the first measure. + + ScheduleOnInterval(SAMPLE_INTERVAL / 4, SAMPLE_INTERVAL / 4); + + return PX4_OK; +} + +void ADS1115::exit_and_cleanup() +{ + I2CSPIDriverBase::exit_and_cleanup(); // nothing to do +} + +void ADS1115::RunImpl() +{ + if (should_exit()) { + PX4_INFO("stopping"); + return; // stop and return immediately to avoid unexpected schedule from stopping procedure + } + + perf_begin(_cycle_perf); + + _adc_report.timestamp = hrt_absolute_time(); + + if (isSampleReady()) { // whether ADS1115 is ready to be read or not + int16_t buf; + ADS1115::ChannelSelection ch = cycleMeasure(&buf); + ++_channel_cycle_count; + + switch (ch) { + case ADS1115::A0: + _adc_report.channel_id[0] = 0; + _adc_report.raw_data[0] = buf; + break; + + case ADS1115::A1: + _adc_report.channel_id[1] = 1; + _adc_report.raw_data[1] = buf; + break; + + case ADS1115::A2: + _adc_report.channel_id[2] = 2; + _adc_report.raw_data[2] = buf; + break; + + case ADS1115::A3: + _adc_report.channel_id[3] = 3; + _adc_report.raw_data[3] = buf; + break; + + default: + PX4_DEBUG("ADS1115: undefined behaviour"); + setChannel(ADS1115::A0); + --_channel_cycle_count; + break; + } + + if (_channel_cycle_count == 4) { // ADS1115 has 4 channels + _channel_cycle_count = 0; + _to_adc_report.publish(_adc_report); + } + + } else { + PX4_WARN("ADS1115 not ready!"); + } + + perf_end(_cycle_perf); +} + +I2CSPIDriverBase *ADS1115::instantiate(const BusCLIArguments &cli, const BusInstanceIterator &iterator, + int runtime_instance) +{ + ADS1115 *instance = new ADS1115(iterator.configuredBusOption(), iterator.bus(), cli.i2c_address, + cli.bus_frequency); + + if (!instance) { + PX4_ERR("alloc failed"); + return nullptr; + } + + if (OK != instance->Begin()) { + delete instance; + return nullptr; + } + + return instance; +} + +void ADS1115::print_usage() +{ + PRINT_MODULE_USAGE_NAME("ads1115", "driver"); + PRINT_MODULE_USAGE_COMMAND("start"); + PRINT_MODULE_USAGE_PARAMS_I2C_SPI_DRIVER(true, false); + PRINT_MODULE_USAGE_PARAMS_I2C_ADDRESS(0x48); + PRINT_MODULE_USAGE_DEFAULT_COMMANDS(); +} + +void ADS1115::print_status() +{ + I2CSPIDriverBase::print_status(); + perf_print_counter(_cycle_perf); +} + +extern "C" int ads1115_main(int argc, char *argv[]) +{ + int ch; + using ThisDriver = ADS1115; + BusCLIArguments cli{true, false}; + cli.default_i2c_frequency = 400000; + cli.i2c_address = 0x48; + + while ((ch = cli.getopt(argc, argv, "")) != EOF) { + + } + + const char *verb = cli.optarg(); + + if (!verb) { + ThisDriver::print_usage(); + return -1; + } + + BusInstanceIterator iterator(MODULE_NAME, cli, DRV_ADC_DEVTYPE_ADS1115); + + if (!strcmp(verb, "start")) { + return ThisDriver::module_start(cli, iterator); + } + + if (!strcmp(verb, "stop")) { + return ThisDriver::module_stop(iterator); + } + + if (!strcmp(verb, "status")) { + return ThisDriver::module_status(iterator); + } + + ThisDriver::print_usage(); + return -1; +} \ No newline at end of file diff --git a/src/drivers/drv_sensor.h b/src/drivers/drv_sensor.h index ffec8257af..333bdab2d3 100644 --- a/src/drivers/drv_sensor.h +++ b/src/drivers/drv_sensor.h @@ -163,6 +163,7 @@ #define DRV_MAG_DEVTYPE_UAVCAN 0x88 #define DRV_DIST_DEVTYPE_UAVCAN 0x89 +#define DRV_ADC_DEVTYPE_ADS1115 0x90 #define DRV_DEVTYPE_UNUSED 0xff