123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230 |
- #include <AP_HAL/AP_HAL.h>
- #include <AP_HAL/utility/sparse-endian.h>
- #include "AP_ADC_ADS1115.h"
- #define ADS1115_ADDRESS_ADDR_GND 0x48 // address pin low (GND)
- #define ADS1115_ADDRESS_ADDR_VDD 0x49 // address pin high (VCC)
- #define ADS1115_ADDRESS_ADDR_SDA 0x4A // address pin tied to SDA pin
- #define ADS1115_ADDRESS_ADDR_SCL 0x4B // address pin tied to SCL pin
- #define ADS1115_I2C_ADDR ADS1115_ADDRESS_ADDR_GND
- #define ADS1115_I2C_BUS 1
- #define ADS1115_RA_CONVERSION 0x00
- #define ADS1115_RA_CONFIG 0x01
- #define ADS1115_RA_LO_THRESH 0x02
- #define ADS1115_RA_HI_THRESH 0x03
- #define ADS1115_OS_SHIFT 15
- #define ADS1115_OS_INACTIVE 0x00 << ADS1115_OS_SHIFT
- #define ADS1115_OS_ACTIVE 0x01 << ADS1115_OS_SHIFT
- #define ADS1115_MUX_SHIFT 12
- #define ADS1115_MUX_P0_N1 0x00 << ADS1115_MUX_SHIFT /* default */
- #define ADS1115_MUX_P0_N3 0x01 << ADS1115_MUX_SHIFT
- #define ADS1115_MUX_P1_N3 0x02 << ADS1115_MUX_SHIFT
- #define ADS1115_MUX_P2_N3 0x03 << ADS1115_MUX_SHIFT
- #define ADS1115_MUX_P0_NG 0x04 << ADS1115_MUX_SHIFT
- #define ADS1115_MUX_P1_NG 0x05 << ADS1115_MUX_SHIFT
- #define ADS1115_MUX_P2_NG 0x06 << ADS1115_MUX_SHIFT
- #define ADS1115_MUX_P3_NG 0x07 << ADS1115_MUX_SHIFT
- #define ADS1115_PGA_SHIFT 9
- #define ADS1115_PGA_6P144 0x00 << ADS1115_PGA_SHIFT
- #define ADS1115_PGA_4P096 0x01 << ADS1115_PGA_SHIFT
- #define ADS1115_PGA_2P048 0x02 << ADS1115_PGA_SHIFT // default
- #define ADS1115_PGA_1P024 0x03 << ADS1115_PGA_SHIFT
- #define ADS1115_PGA_0P512 0x04 << ADS1115_PGA_SHIFT
- #define ADS1115_PGA_0P256 0x05 << ADS1115_PGA_SHIFT
- #define ADS1115_PGA_0P256B 0x06 << ADS1115_PGA_SHIFT
- #define ADS1115_PGA_0P256C 0x07 << ADS1115_PGA_SHIFT
- #define ADS1115_MV_6P144 0.187500f
- #define ADS1115_MV_4P096 0.125000f
- #define ADS1115_MV_2P048 0.062500f // default
- #define ADS1115_MV_1P024 0.031250f
- #define ADS1115_MV_0P512 0.015625f
- #define ADS1115_MV_0P256 0.007813f
- #define ADS1115_MV_0P256B 0.007813f
- #define ADS1115_MV_0P256C 0.007813f
- #define ADS1115_MODE_SHIFT 8
- #define ADS1115_MODE_CONTINUOUS 0x00 << ADS1115_MODE_SHIFT
- #define ADS1115_MODE_SINGLESHOT 0x01 << ADS1115_MODE_SHIFT // default
- #define ADS1115_RATE_SHIFT 5
- #define ADS1115_RATE_8 0x00 << ADS1115_RATE_SHIFT
- #define ADS1115_RATE_16 0x01 << ADS1115_RATE_SHIFT
- #define ADS1115_RATE_32 0x02 << ADS1115_RATE_SHIFT
- #define ADS1115_RATE_64 0x03 << ADS1115_RATE_SHIFT
- #define ADS1115_RATE_128 0x04 << ADS1115_RATE_SHIFT // default
- #define ADS1115_RATE_250 0x05 << ADS1115_RATE_SHIFT
- #define ADS1115_RATE_475 0x06 << ADS1115_RATE_SHIFT
- #define ADS1115_RATE_860 0x07 << ADS1115_RATE_SHIFT
- #define ADS1115_COMP_MODE_SHIFT 4
- #define ADS1115_COMP_MODE_HYSTERESIS 0x00 << ADS1115_COMP_MODE_SHIFT // default
- #define ADS1115_COMP_MODE_WINDOW 0x01 << ADS1115_COMP_MODE_SHIFT
- #define ADS1115_COMP_POL_SHIFT 3
- #define ADS1115_COMP_POL_ACTIVE_LOW 0x00 << ADS1115_COMP_POL_SHIFT // default
- #define ADS1115_COMP_POL_ACTIVE_HIGH 0x01 << ADS1115_COMP_POL_SHIFT
- #define ADS1115_COMP_LAT_SHIFT 2
- #define ADS1115_COMP_LAT_NON_LATCHING 0x00 << ADS1115_COMP_LAT_SHIFT // default
- #define ADS1115_COMP_LAT_LATCHING 0x01 << ADS1115_COMP_LAT_SHIFT
- #define ADS1115_COMP_QUE_SHIFT 0
- #define ADS1115_COMP_QUE_ASSERT1 0x00 << ADS1115_COMP_SHIFT
- #define ADS1115_COMP_QUE_ASSERT2 0x01 << ADS1115_COMP_SHIFT
- #define ADS1115_COMP_QUE_ASSERT4 0x02 << ADS1115_COMP_SHIFT
- #define ADS1115_COMP_QUE_DISABLE 0x03 // default
- #define ADS1115_DEBUG 0
- #if ADS1115_DEBUG
- #include <cstdio>
- #define debug(fmt, args ...) do {hal.console->printf("%s:%d: " fmt "\n", __FUNCTION__, __LINE__, ## args); } while(0)
- #define error(fmt, args ...) do {fprintf(stderr,"%s:%d: " fmt "\n", __FUNCTION__, __LINE__, ## args); } while(0)
- #else
- #define debug(fmt, args ...)
- #define error(fmt, args ...)
- #endif
- extern const AP_HAL::HAL &hal;
- #define ADS1115_CHANNELS_COUNT 6
- const uint8_t AP_ADC_ADS1115::_channels_number = ADS1115_CHANNELS_COUNT;
- /* Only two differential channels used */
- static const uint16_t mux_table[ADS1115_CHANNELS_COUNT] = {
- ADS1115_MUX_P1_N3,
- ADS1115_MUX_P2_N3,
- ADS1115_MUX_P0_NG,
- ADS1115_MUX_P1_NG,
- ADS1115_MUX_P2_NG,
- ADS1115_MUX_P3_NG
- };
- AP_ADC_ADS1115::AP_ADC_ADS1115()
- : _dev{}
- , _gain(ADS1115_PGA_4P096)
- , _channel_to_read(0)
- {
- _samples = new adc_report_s[_channels_number];
- }
- AP_ADC_ADS1115::~AP_ADC_ADS1115()
- {
- delete[] _samples;
- }
- bool AP_ADC_ADS1115::init()
- {
- _dev = hal.i2c_mgr->get_device(ADS1115_I2C_BUS, ADS1115_I2C_ADDR);
- if (!_dev) {
- return false;
- }
- _gain = ADS1115_PGA_4P096;
- _dev->register_periodic_callback(100000, FUNCTOR_BIND_MEMBER(&AP_ADC_ADS1115::_update, void));
- return true;
- }
- bool AP_ADC_ADS1115::_start_conversion(uint8_t channel)
- {
- struct PACKED {
- uint8_t reg;
- be16_t val;
- } config;
- config.reg = ADS1115_RA_CONFIG;
- config.val = htobe16(ADS1115_OS_ACTIVE | _gain | mux_table[channel] |
- ADS1115_MODE_SINGLESHOT | ADS1115_COMP_QUE_DISABLE |
- ADS1115_RATE_250);
- return _dev->transfer((uint8_t *)&config, sizeof(config), nullptr, 0);
- }
- size_t AP_ADC_ADS1115::read(adc_report_s *report, size_t length) const
- {
- for (size_t i = 0; i < length; i++) {
- report[i].data = _samples[i].data;
- report[i].id = _samples[i].id;
- }
- return length;
- }
- float AP_ADC_ADS1115::_convert_register_data_to_mv(int16_t word) const
- {
- float pga;
- switch (_gain) {
- case ADS1115_PGA_6P144:
- pga = ADS1115_MV_6P144;
- break;
- case ADS1115_PGA_4P096:
- pga = ADS1115_MV_4P096;
- break;
- case ADS1115_PGA_2P048:
- pga = ADS1115_MV_2P048;
- break;
- case ADS1115_PGA_1P024:
- pga = ADS1115_MV_1P024;
- break;
- case ADS1115_PGA_0P512:
- pga = ADS1115_MV_0P512;
- break;
- case ADS1115_PGA_0P256:
- pga = ADS1115_MV_0P256;
- break;
- case ADS1115_PGA_0P256B:
- pga = ADS1115_MV_0P256B;
- break;
- case ADS1115_PGA_0P256C:
- pga = ADS1115_MV_0P256C;
- break;
- default:
- pga = 0.0f;
- hal.console->printf("Wrong gain");
- AP_HAL::panic("ADS1115: wrong gain selected");
- break;
- }
- return (float) word * pga;
- }
- void AP_ADC_ADS1115::_update()
- {
- uint8_t config[2];
- be16_t val;
- if (!_dev->read_registers(ADS1115_RA_CONFIG, config, sizeof(config))) {
- error("_dev->read_registers failed in ADS1115");
- return;
- }
- /* check rdy bit */
- if ((config[1] & 0x80) != 0x80 ) {
- return;
- }
- if (!_dev->read_registers(ADS1115_RA_CONVERSION, (uint8_t *)&val, sizeof(val))) {
- return;
- }
- float sample = _convert_register_data_to_mv(be16toh(val));
- _samples[_channel_to_read].data = sample;
- _samples[_channel_to_read].id = _channel_to_read;
- /* select next channel */
- _channel_to_read = (_channel_to_read + 1) % _channels_number;
- _start_conversion(_channel_to_read);
- }
|