diff --git a/examples/ads1115_test/Makefile b/examples/ads1115_test/Makefile new file mode 100644 index 0000000..924bf11 --- /dev/null +++ b/examples/ads1115_test/Makefile @@ -0,0 +1,4 @@ +PROGRAM = ads1115_test +EXTRA_COMPONENTS = extras/i2c extras/ads111x +#ESPBAUD = 460800 +include ../../common.mk diff --git a/examples/ads1115_test/main.c b/examples/ads1115_test/main.c new file mode 100644 index 0000000..8065f04 --- /dev/null +++ b/examples/ads1115_test/main.c @@ -0,0 +1,55 @@ +/* + * Example of using DS1302 RTC driver + * + * Part of esp-open-rtos + * Copyright (C) 2016 Ruslan V. Uss + * Pavel Merzlyakov + * BSD Licensed as described in the file LICENSE + */ +#include +#include +#include +#include +#include +#include +#include + +// Connect ADDR pin to GND +#define ADDR ADS111X_ADDR_GND + +#define SCL_PIN 5 +#define SDA_PIN 4 + +// +-4.096V +#define GAIN ADS111X_GAIN_4V096 + +void user_init(void) +{ + uart_set_baud(0, 115200); + printf("SDK version:%s\n", sdk_system_get_sdk_version()); + + i2c_init(SCL_PIN, SDA_PIN); + + ads111x_set_mode(ADDR, ADS111X_MODE_CONTUNOUS); + ads111x_set_data_rate(ADDR, ADS111X_DATA_RATE_32); + + ads111x_set_input_mux(ADDR, ADS111X_MUX_0_GND); + ads111x_set_gain(ADDR, GAIN); + + float gain_val = ads111x_gain_values[GAIN]; + + while (true) + { + // wait for conversion end + while (ads111x_busy(ADDR)) {} + + // Read result + int16_t raw = ads111x_get_value(ADDR); + + float voltage = gain_val / ADS111X_MAX_VALUE * raw; + + printf("Raw ADC value: %d, voltage: %.04f volts\n", raw, voltage); + + vTaskDelay(500 / portTICK_PERIOD_MS); + } +} diff --git a/extras/ads111x/ads111x.c b/extras/ads111x/ads111x.c new file mode 100644 index 0000000..9241e13 --- /dev/null +++ b/extras/ads111x/ads111x.c @@ -0,0 +1,195 @@ +/* + * Driver for ADS1113/ADS1114/ADS1115 I2C ADC + * + * Part of esp-open-rtos + * Copyright (C) 2016 Ruslan V. Uss + * BSD Licensed as described in the file LICENSE + */ +#include "ads111x.h" +#include + +#define ADS111X_DEBUG + +#ifdef ADS111X_DEBUG +#include +#define debug(fmt, ...) printf("%s" fmt "\n", "ADS111x: ", ## __VA_ARGS__) +#else +#define debug(fmt, ...) +#endif + +#define REG_CONVERSION 0 +#define REG_CONFIG 1 +#define REG_THRESH_L 2 +#define REG_THRESH_H 3 + +#define COMP_QUE_OFFSET 1 +#define COMP_QUE_MASK 0x03 +#define COMP_LAT_OFFSET 2 +#define COMP_LAT_MASK 0x01 +#define COMP_POL_OFFSET 3 +#define COMP_POL_MASK 0x01 +#define COMP_MODE_OFFSET 4 +#define COMP_MODE_MASK 0x01 +#define DR_OFFSET 5 +#define DR_MASK 0x07 +#define MODE_OFFSET 8 +#define MODE_MASK 0x01 +#define PGA_OFFSET 9 +#define PGA_MASK 0x07 +#define MUX_OFFSET 12 +#define MUX_MASK 0x07 +#define OS_OFFSET 15 +#define OS_MASK 0x01 + +const float ads111x_gain_values[] = { + [ADS111X_GAIN_6V144] = 6.144, + [ADS111X_GAIN_4V096] = 4.096, + [ADS111X_GAIN_2V048] = 2.048, + [ADS111X_GAIN_1V024] = 1.024, + [ADS111X_GAIN_0V512] = 0.512, + [ADS111X_GAIN_0V256] = 0.256, + [ADS111X_GAIN_0V256_2] = 0.256, + [ADS111X_GAIN_0V256_3] = 0.256 +}; + +static uint16_t read_reg(uint8_t addr, uint8_t reg) +{ + uint16_t res = 0; + if (!i2c_slave_read(addr, reg, (uint8_t *)&res, 2)) + debug("Could not read register %d", reg); + //debug("Read %d: 0x%04x", reg, res); + return res; +} + +static void write_reg(uint8_t addr, uint8_t reg, uint16_t val) +{ + //debug("Write %d: 0x%04x", reg, val); + uint8_t buf[3] = {reg, val >> 8, val}; + if (!i2c_slave_write(addr, buf, 3)) + debug("Could not write 0x%04x to register %d", val, reg); +} + +static uint16_t read_conf_bits(uint8_t addr, uint8_t offs, uint16_t mask) +{ + return (read_reg(addr, REG_CONFIG) >> offs) & mask; +} + +static void write_conf_bits(uint8_t addr, uint16_t val, uint8_t offs, uint16_t mask) +{ + write_reg(addr, REG_CONFIG, (read_reg(addr, REG_CONFIG) & ~(mask << offs)) | (val << offs)); +} + +bool ads111x_busy(uint8_t addr) +{ + return read_conf_bits(addr, OS_OFFSET, OS_MASK); +} + +void ads111x_start_conversion(uint8_t addr) +{ + write_conf_bits(addr, 1, OS_OFFSET, OS_MASK); +} + +int16_t ads111x_get_value(uint8_t addr) +{ + return read_reg(addr, REG_CONVERSION); +} + +ads111x_gain_t ads111x_get_gain(uint8_t addr) +{ + return read_conf_bits(addr, PGA_OFFSET, PGA_MASK); +} + +void ads111x_set_gain(uint8_t addr, ads111x_gain_t gain) +{ + write_conf_bits(addr, gain, PGA_OFFSET, PGA_MASK); +} + +ads111x_mux_t ads111x_get_input_mux(uint8_t addr) +{ + return read_conf_bits(addr, MUX_OFFSET, MUX_MASK); +} + +void ads111x_set_input_mux(uint8_t addr, ads111x_mux_t mux) +{ + write_conf_bits(addr, mux, MUX_OFFSET, MUX_MASK); +} + +ads111x_mode_t ads111x_get_mode(uint8_t addr) +{ + return read_conf_bits(addr, MODE_OFFSET, MODE_MASK); +} + +void ads111x_set_mode(uint8_t addr, ads111x_mode_t mode) +{ + write_conf_bits(addr, mode, MODE_OFFSET, MODE_MASK); +} + +ads111x_data_rate_t ads111x_get_data_rate(uint8_t addr) +{ + return read_conf_bits(addr, DR_OFFSET, DR_MASK); +} + +void ads111x_set_data_rate(uint8_t addr, ads111x_data_rate_t rate) +{ + write_conf_bits(addr, rate, DR_OFFSET, DR_MASK); +} + +ads111x_comp_mode_t ads111x_get_comp_mode(uint8_t addr) +{ + return read_conf_bits(addr, COMP_MODE_OFFSET, COMP_MODE_MASK); +} + +void ads111x_set_comp_mode(uint8_t addr, ads111x_comp_mode_t mode) +{ + write_conf_bits(addr, mode, COMP_MODE_OFFSET, COMP_MODE_MASK); +} + +ads111x_comp_polarity_t ads111x_get_comp_polarity(uint8_t addr) +{ + return read_conf_bits(addr, COMP_POL_OFFSET, COMP_POL_MASK); +} + +void ads111x_set_comp_polarity(uint8_t addr, ads111x_comp_polarity_t polarity) +{ + write_conf_bits(addr, polarity, COMP_POL_OFFSET, COMP_POL_MASK); +} + +ads111x_comp_latch_t ads111x_get_comp_latch(uint8_t addr) +{ + return read_conf_bits(addr, COMP_LAT_OFFSET, COMP_LAT_MASK); +} + +void ads111x_set_comp_latch(uint8_t addr, ads111x_comp_latch_t latch) +{ + write_conf_bits(addr, latch, COMP_LAT_OFFSET, COMP_LAT_MASK); +} + +ads111x_comp_queue_t ads111x_get_comp_queue(uint8_t addr) +{ + return read_conf_bits(addr, COMP_QUE_OFFSET, COMP_QUE_MASK); +} + +void ads111x_set_comp_queue(uint8_t addr, ads111x_comp_queue_t queue) +{ + write_conf_bits(addr, queue, COMP_QUE_OFFSET, COMP_QUE_MASK); +} + +int16_t ads111x_get_comp_low_thresh(uint8_t addr) +{ + return read_reg(addr, REG_THRESH_L); +} + +void ads111x_set_comp_low_thresh(uint8_t addr, int16_t thresh) +{ + write_reg(addr, REG_THRESH_L, thresh); +} + +int16_t ads111x_get_comp_high_thresh(uint8_t addr) +{ + return read_reg(addr, REG_THRESH_H); +} + +void ads111x_set_comp_high_thresh(uint8_t addr, int16_t thresh) +{ + write_reg(addr, REG_THRESH_H, thresh); +} diff --git a/extras/ads111x/ads111x.h b/extras/ads111x/ads111x.h new file mode 100644 index 0000000..fe64464 --- /dev/null +++ b/extras/ads111x/ads111x.h @@ -0,0 +1,292 @@ +/* + * Driver for ADS1113/ADS1114/ADS1115 I2C ADC + * + * Part of esp-open-rtos + * Copyright (C) 2016 Ruslan V. Uss + * BSD Licensed as described in the file LICENSE + */ +#ifndef _EXTRAS_ADS111X_H_ +#define _EXTRAS_ADS111X_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ADS111X_ADDR_GND 0x48 +#define ADS111X_ADDR_VCC 0x49 +#define ADS111X_ADDR_SDA 0x4a +#define ADS111X_ADDR_SCL 0x4b + +#define ADS111X_MAX_VALUE 0x7fff + +/** + * Gain amplifier + */ +typedef enum +{ + ADS111X_GAIN_6V144 = 0, //!< +-6.144V + ADS111X_GAIN_4V096, //!< +-4.096V + ADS111X_GAIN_2V048, //!< +-2.048V (default) + ADS111X_GAIN_1V024, //!< +-1.024V + ADS111X_GAIN_0V512, //!< +-0.512V + ADS111X_GAIN_0V256, //!< +-0.256V + ADS111X_GAIN_0V256_2, //!< +-0.256V (same as ADS111X_GAIN_0V256) + ADS111X_GAIN_0V256_3, //!< +-0.256V (same as ADS111X_GAIN_0V256) +} ads111x_gain_t; + +/** + * Gain values + */ +extern const float ads111x_gain_values[]; + +/** + * Input multiplexer configuration (ADS1115 only) + */ +typedef enum +{ + ADS111X_MUX_0_1 = 0, //!< positive = AIN0, negative = AIN1 (default) + ADS111X_MUX_0_3, //!< positive = AIN0, negative = AIN3 + ADS111X_MUX_1_3, //!< positive = AIN1, negative = AIN3 + ADS111X_MUX_2_3, //!< positive = AIN2, negative = AIN3 + ADS111X_MUX_0_GND, //!< positive = AIN0, negative = GND + ADS111X_MUX_1_GND, //!< positive = AIN1, negative = GND + ADS111X_MUX_2_GND, //!< positive = AIN2, negative = GND + ADS111X_MUX_3_GND, //!< positive = AIN3, negative = GND +} ads111x_mux_t; + +/** + * Data rate + */ +typedef enum +{ + ADS111X_DATA_RATE_8 = 0, //!< 8 samples per second + ADS111X_DATA_RATE_16, //!< 16 samples per second + ADS111X_DATA_RATE_32, //!< 32 samples per second + ADS111X_DATA_RATE_64, //!< 64 samples per second + ADS111X_DATA_RATE_128, //!< 128 samples per second (default) + ADS111X_DATA_RATE_250, //!< 250 samples per second + ADS111X_DATA_RATE_475, //!< 475 samples per second + ADS111X_DATA_RATE_860 //!< 860 samples per second +} ads111x_data_rate_t; + +/** + * Operational mode + */ +typedef enum +{ + ADS111X_MODE_CONTUNOUS = 0, //!< Continuous conversion mode + ADS111X_MODE_SINGLE_SHOT //!< Power-down single-shot mode (default) +} ads111x_mode_t; + +/** + * Comparator mode (ADS1114 and ADS1115 only) + */ +typedef enum +{ + ADS111X_COMP_MODE_NORMAL = 0, //!< Traditional comparator with hysteresis (default) + ADS111X_COMP_MODE_WINDOW //!< Window comparator +} ads111x_comp_mode_t; + +/** + * Comparator polarity (ADS1114 and ADS1115 only) + */ +typedef enum +{ + ADS111X_COMP_POLARITY_LOW = 0, //!< Active low (default) + ADS111X_COMP_POLARITY_HIGH //!< Active high +} ads111x_comp_polarity_t; + +/** + * Comparator latch (ADS1114 and ADS1115 only) + */ +typedef enum +{ + ADS111X_COMP_LATCH_DISABLED = 0, //!< Non-latching comparator (default) + ADS111X_COMP_LATCH_ENABLED //!< Latching comparator +} ads111x_comp_latch_t; + +/** + * Comparator queue + */ +typedef enum +{ + ADS111X_COMP_QUEUE_1 = 0, //!< Assert ALERT/RDY pin after one conversion + ADS111X_COMP_QUEUE_2, //!< Assert ALERT/RDY pin after two conversions + ADS111X_COMP_QUEUE_4, //!< Assert ALERT/RDY pin after four conversions + ADS111X_COMP_QUEUE_DISABLED //!< Disable comparator (default) +} ads111x_comp_queue_t; + +/** + * Get device operational status + * @param addr Deivce address + * @return true when device performing conversion + */ +bool ads111x_busy(uint8_t addr); + +/** + * Begin a single conversion (when in single-shot mode) + * @param addr Deivce address + */ +void ads111x_start_conversion(uint8_t addr); + +/** + * Read last conversion result + * @param addr + * @return Last conversion result + */ +int16_t ads111x_get_value(uint8_t addr); + +/** + * Read the programmable gain amplifier configuration + * (ADS1114 and ADS1115 only). + * @param addr Deivce address + * @return Gain value + */ +ads111x_gain_t ads111x_get_gain(uint8_t addr); + +/** + * Configure the programmable gain amplifier (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @param gain Gain value + */ +void ads111x_set_gain(uint8_t addr, ads111x_gain_t gain); + +/** + * Read the input multiplexer configuration (ADS1115 only) + * @param addr Deivce address + * @return Input multiplexer configuration + */ +ads111x_mux_t ads111x_get_input_mux(uint8_t addr); + +/** + * Configure the input multiplexer configuration (ADS1115 only) + * @param addr Deivce address + * @param mux Input multiplexer configuration + */ +void ads111x_set_input_mux(uint8_t addr, ads111x_mux_t mux); + +/** + * Read the device operating mode + * @param addr Deivce address + * @return Device operating mode + */ +ads111x_mode_t ads111x_get_mode(uint8_t addr); + +/** + * Set the device operating mode + * @param addr Deivce address + * @param mode Device operating mode + */ +void ads111x_set_mode(uint8_t addr, ads111x_mode_t mode); + +/** + * Read the data rate + * @param addr Deivce address + * @return Data rate + */ +ads111x_data_rate_t ads111x_get_data_rate(uint8_t addr); + +/** + * Configure the data rate + * @param addr Deivce address + * @param rate Data rate + */ +void ads111x_set_data_rate(uint8_t addr, ads111x_data_rate_t rate); + +/** + * Get comparator mode (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @return Comparator mode + */ +ads111x_comp_mode_t ads111x_get_comp_mode(uint8_t addr); + +/** + * Set comparator mode (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @param mode Comparator mode + */ +void ads111x_set_comp_mode(uint8_t addr, ads111x_comp_mode_t mode); + +/** + * Get polarity of the comparator output pin ALERT/RDY + * (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @return Comparator output pin polarity + */ +ads111x_comp_polarity_t ads111x_get_comp_polarity(uint8_t addr); + +/** + * Set polarity of the comparator output pin ALERT/RDY + * (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @param polarity Comparator output pin polarity + */ +void ads111x_set_comp_polarity(uint8_t addr, ads111x_comp_polarity_t polarity); + +/** + * Get comparator output latch mode, see datasheet. + * (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @return Comparator output latch mode + */ +ads111x_comp_latch_t ads111x_get_comp_latch(uint8_t addr); + +/** + * Set comparator output latch mode (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @param latch Comparator output latch mode + */ +void ads111x_set_comp_latch(uint8_t addr, ads111x_comp_latch_t latch); + +/** + * Set number of the comparator conversions before pin ALERT/RDY + * assertion, or disable comparator (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @return Number of the comparator conversions + */ +ads111x_comp_queue_t ads111x_get_comp_queue(uint8_t addr); + +/** + * Get number of the comparator conversions before pin ALERT/RDY + * assertion (ADS1114 and ADS1115 only) + * @param addr Deivce address + * @param queue Number of the comparator conversions + */ +void ads111x_set_comp_queue(uint8_t addr, ads111x_comp_queue_t queue); + +/** + * Get the lower threshold value used by comparator + * @param addr Deivce address + * @return Lower threshold value + */ +int16_t ads111x_get_comp_low_thresh(uint8_t addr); + +/** + * Set the lower threshold value used by comparator + * @param addr Deivce address + * @param thresh Lower threshold value + */ +void ads111x_set_comp_low_thresh(uint8_t addr, int16_t thresh); + +/** + * Get the upper threshold value used by comparator + * @param addr Deivce address + * @return Upper threshold value + */ +int16_t ads111x_get_comp_high_thresh(uint8_t addr); + +/** + * Set the upper threshold value used by comparator + * @param addr Deivce address + * @param thresh Upper threshold value + */ +void ads111x_set_comp_high_thresh(uint8_t addr, int16_t thresh); + +#ifdef __cplusplus +} +#endif + +#endif /* _EXTRAS_ADS111X_H_ */ diff --git a/extras/ads111x/component.mk b/extras/ads111x/component.mk new file mode 100644 index 0000000..5ae835c --- /dev/null +++ b/extras/ads111x/component.mk @@ -0,0 +1,9 @@ +# Component makefile for extras/ads111x + +# expected anyone using ADC driver includes it as 'ads111x/ads111x.h' +INC_DIRS += $(ads111x_ROOT).. + +# args for passing into compile rule generation +ads111x_SRC_DIR = $(ads111x_ROOT) + +$(eval $(call component_compile_rules,ads111x))