Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions drivers/ads1115/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base
1 change: 1 addition & 0 deletions drivers/ads1115/Makefile.dep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FEATURES_REQUIRED += periph_i2c
2 changes: 2 additions & 0 deletions drivers/ads1115/Makefile.include
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
USEMODULE_INCLUDES_ads1115 := $(LAST_MAKEFILEDIR)/include
USEMODULE_INCLUDES += $(USEMODULE_INCLUDES_ads1115)
175 changes: 175 additions & 0 deletions drivers/ads1115/ads1115.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
/*
* SPDX-FileCopyrightText: 2025 Baptiste Le Duc <[email protected]>
* SPDX-License-Identifier: LGPL-2.1-only
*/

/**
* @ingroup drivers_ads1115
* @{
* @file
* @brief ADS1115 Analog-to-digital converter driver
* @author Baptiste Le Duc <[email protected]>
* @}
*/

#include <assert.h>

#include "ads1115.h"
#include "ads1115_params.h"
#include "ads1115_internal.h"

#include "periph/i2c.h"
#include "byteorder.h"

#define ENABLE_DEBUG 0
#include "debug.h"

#define DEV (dev->params.i2c)
#define ADDR (dev->params.addr)

#define ADS1115_CONF_TEST_VALUE (1)

static inline int _ads1115_get_pga_voltage(ads1115_pga_t pga)
{
switch (pga) {
case ADS1115_PGA_6_144V: return 6144;
case ADS1115_PGA_4_096V: return 4096;
case ADS1115_PGA_2_048V: return 2048;
case ADS1115_PGA_1_024V: return 1024;
case ADS1115_PGA_0_512V: return 512;
case ADS1115_PGA_0_256V:
case ADS1115_PGA_0_256V_B:
case ADS1115_PGA_0_256V_C:
return 256;
default:
return 0;
}
}

/**
* @brief Builds the configuration register value from the parameters
*
* @param[in] params ADS1115 parameters
*
* @return Configuration register value
*/
static uint16_t _build_config_reg(const ads1115_params_t *params)
{
uint16_t conf = 0;

conf |= (params->mux << ADS1115_CONF_MUX_BIT);
conf |= (params->pga << ADS1115_CONF_PGA_BIT);
conf |= (params->mode << ADS1115_CONF_MODE_BIT);
conf |= (params->dr << ADS1115_CONF_DR_BIT);
conf |= (params->comp_mode << ADS1115_CONF_COMP_MODE_BIT);
conf |= (params->comp_polarity << ADS1115_CONF_COMP_POLARITY_BIT);
conf |= (params->comp_latch << ADS1115_CONF_COMP_LATCH_BIT);
conf |= (params->comp_queue << ADS1115_CONF_COMP_QUEUE_BIT);

return conf;
}

int ads1115_init(ads1115_t *dev, const ads1115_params_t *params)
{
assert(dev && params);

dev->params = *params;
DEBUG("[ads1115] init - i2c=%d, addr=0x%02x\n", dev->params.i2c, dev->params.addr);

int res = ADS1115_NOI2C;

i2c_acquire(DEV);

/* Test communication */
uint16_t test_conf = htons(ADS1115_CONF_TEST_VALUE);
if (i2c_write_regs(DEV, ADDR, ADS1115_REG_CONFIG, &test_conf, sizeof(test_conf), 0) < 0) {
DEBUG("[ads1115] init - error: write test failed\n");
res = ADS1115_NODEV;
}

uint16_t reg;
if (i2c_read_regs(DEV, ADDR, ADS1115_REG_CONFIG, &reg, sizeof(reg), 0) < 0 ||
ntohs(reg) != ADS1115_CONF_TEST_VALUE) {
DEBUG("[ads1115] init - error: read test failed (reg=%04x)\n", ntohs(reg));
res = ADS1115_NOI2C;
goto release;
}

/* Apply actual configuration */
uint16_t conf = htons(_build_config_reg(&dev->params));
if (i2c_write_regs(DEV, ADDR, ADS1115_REG_CONFIG, &conf, sizeof(conf), 0) < 0) {
DEBUG("[ads1115] init - error: setting config failed\n");
res = ADS1115_NOI2C;
goto release;
}

res = ADS1115_OK;

release:
i2c_release(DEV);
return res;
}

int ads1115_set_ain_ch_input(ads1115_t *dev, ads1115_mux_t mux)
{
assert(dev);

int res = ADS1115_NOI2C;

i2c_acquire(DEV);

/* Read current configuration */
uint16_t reg;
if (i2c_read_regs(DEV, ADDR, ADS1115_REG_CONFIG, &reg, sizeof(reg), 0) < 0) {
i2c_release(DEV);
goto release;
}

/* Update MUX bits */
uint16_t conf = ntohs(reg);
conf &= ~(0x07 << ADS1115_CONF_MUX_BIT); /* Clear MUX bits */
conf |= (mux << ADS1115_CONF_MUX_BIT); /* Set new MUX */

/* Write back updated configuration */
reg = htons(conf);

if (i2c_write_regs(DEV, ADDR, ADS1115_REG_CONFIG, &reg, sizeof(reg), 0) < 0) {
goto release;
}

res = ADS1115_OK;
dev->params.mux = mux;

release:
i2c_release(DEV);
return res;
}

int ads1115_read_conversion(ads1115_t *dev, uint16_t *value)
{
assert(dev && value);

int res = ADS1115_NOI2C;
uint16_t buf;

i2c_acquire(DEV);

/* Read conversion register */
if (i2c_read_regs(DEV, ADDR, ADS1115_REG_CONVERSION, &buf, sizeof(buf), 0) < 0) {
goto release;
}

/* Combine bytes into a single value */
*value = ntohs(buf);
res = ADS1115_OK;

release:
i2c_release(DEV);
return res;
}

int ads1115_convert_to_mv(ads1115_t *dev, uint16_t value)
{
assert(dev);
return value * _ads1115_get_pga_voltage(dev->params.pga) / (1 << 15); /* Msb is sign bit */
}
52 changes: 52 additions & 0 deletions drivers/ads1115/include/ads1115_internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Copyright (C) Baptiste Le Duc <[email protected]>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/

#pragma once

/**
* @ingroup drivers_ads1115
* @{
*
* @file
* @brief Internal definitions for ADS1115 Analog-to-digital converter
*
* @author Baptiste Le Duc <[email protected]>
* @}
*/

#ifdef __cplusplus
extern "C" {
#endif

/**
* @name ADS1115 registers
* @{
*/

#define ADS1115_REG_CONVERSION (0x00) /**< Conversion register */
#define ADS1115_REG_CONFIG (0x01) /**< Configuration register */
/** @} */

/**
* @name ADS1115 configuration register bits
* @{
*/
#define ADS1115_CONF_OS_BIT (15) /**< Operational status */
#define ADS1115_CONF_MUX_BIT (12) /**< Input multiplexer configuration */
#define ADS1115_CONF_PGA_BIT (9) /**< Programmable gain amplifier configuration */
#define ADS1115_CONF_MODE_BIT (8) /**< Device mode */
#define ADS1115_CONF_DR_BIT (5) /**< Data rate configuration */
#define ADS1115_CONF_COMP_MODE_BIT (4) /**< Comparator mode */
#define ADS1115_CONF_COMP_POLARITY_BIT (3) /**< Comparator polarity */
#define ADS1115_CONF_COMP_LATCH_BIT (2) /**< Comparator latch */
#define ADS1115_CONF_COMP_QUEUE_BIT (0) /**< Comparator queue */
/** @} */

#ifdef __cplusplus
}
#endif
141 changes: 141 additions & 0 deletions drivers/ads1115/include/ads1115_params.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/*
* SPDX-FileCopyrightText: 2025 Baptiste Le Duc <[email protected]>
* SPDX-License-Identifier: LGPL-2.1-only
*/

#pragma once

/**
* @ingroup drivers_ads1115
* @{
*
* @file
* @brief Default configuration for ADS1115 device
*
* @author Baptiste Le Duc <[email protected]>
*/

#include "board.h"
#include "ads1115.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
* @name Set default configuration parameters for the ADS1115 driver
* @{
*/

/**
* @def ADS1115_PARAM_I2C
* @brief Default I2C bus
*/
#ifndef ADS1115_PARAM_I2C
# define ADS1115_PARAM_I2C (I2C_DEV(0))
#endif

/**
* @def ADS1115_PARAM_ADDR
* @brief Default I2C address
*/
#ifndef ADS1115_PARAM_ADDR
# define ADS1115_PARAM_ADDR (0x48)
#endif

/**
* @def ADS1115_PARAM_MUX
* @brief Default multiplexer configuration
*/
#ifndef ADS1115_PARAM_MUX
# define ADS1115_PARAM_MUX (ADS1115_MUX_AIN0_AIN1)
#endif

/**
* @def ADS1115_PARAM_PGA
* @brief Default programmable gain amplifier configuration
*/
#ifndef ADS1115_PARAM_PGA
# define ADS1115_PARAM_PGA (ADS1115_PGA_2_048V)
#endif

/**
* @def ADS1115_PARAM_MODE
* @brief Default device mode
*/
#ifndef ADS1115_PARAM_MODE
# define ADS1115_PARAM_MODE (ADS1115_MODE_SINGLE)
#endif

/**
* @def ADS1115_PARAM_DR
* @brief Default data rate configuration
*/
#ifndef ADS1115_PARAM_DR
# define ADS1115_PARAM_DR (ADS1115_DR_128)
#endif

/**
* @def ADS1115_PARAM_COMP_MODE
* @brief Default comparator mode
*/
#ifndef ADS1115_PARAM_COMP_MODE
# define ADS1115_PARAM_COMP_MODE (ADS1115_COMP_MODE_TRADITIONAL)
#endif

/**
* @def ADS1115_PARAM_COMP_POLARITY
* @brief Default comparator polarity
*/
#ifndef ADS1115_PARAM_COMP_POLARITY
# define ADS1115_PARAM_COMP_POLARITY (ADS1115_COMP_POLARITY_LOW)
#endif

/**
* @def ADS1115_PARAM_COMP_LATCH
* @brief Default comparator latch
*/
#ifndef ADS1115_PARAM_COMP_LATCH
# define ADS1115_PARAM_COMP_LATCH (ADS1115_COMP_LATCH_DISABLE)
#endif

/**
* @def ADS1115_PARAM_COMP_QUEUE
* @brief Default comparator queue
*/
#ifndef ADS1115_PARAM_COMP_QUEUE
# define ADS1115_PARAM_COMP_QUEUE (ADS1115_COMP_QUEUE_DISABLE)
#endif

/**
* @def ADS1115_PARAMS
* @brief Default configuration structure for the ADS1115 driver
*/
#ifndef ADS1115_PARAMS
# define ADS1115_PARAMS { \
.i2c = ADS1115_PARAM_I2C, \
.addr = ADS1115_PARAM_ADDR, \
.mux = ADS1115_PARAM_MUX, \
.pga = ADS1115_PARAM_PGA, \
.mode = ADS1115_PARAM_MODE, \
.dr = ADS1115_PARAM_DR, \
.comp_mode = ADS1115_PARAM_COMP_MODE, \
.comp_polarity = ADS1115_PARAM_COMP_POLARITY, \
.comp_latch = ADS1115_PARAM_COMP_LATCH, \
.comp_queue = ADS1115_PARAM_COMP_QUEUE \
}
#endif
/** @} */

/**
* @brief Default parameters structure
*/
static const ads1115_params_t ads1115_params[] = {
ADS1115_PARAMS
};

/** @} */ /* close @ingroup drivers_ads1115 */

Check warning on line 137 in drivers/ads1115/include/ads1115_params.h

View workflow job for this annotation

GitHub Actions / static-tests

trailing whitespace

Check failure on line 137 in drivers/ads1115/include/ads1115_params.h

View workflow job for this annotation

GitHub Actions / static-tests

trailing whitespace.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** @} */ /* close @ingroup drivers_ads1115 */
/** @} */ /* close @ingroup drivers_ads1115 */


#ifdef __cplusplus
}
#endif
Loading
Loading