Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

drivers/ads101x: Changes for Common ADC API #10619

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
88 changes: 88 additions & 0 deletions drivers/ads101x/ads101x.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ int ads101x_init(ads101x_t *dev, const ads101x_params_t *params)
assert(dev && params);

dev->params = *params;
#if MODULE_ADC_NG
dev->ch_numof = ADS101X_CH_NUMOF(params->device);
dev->res = ADS101X_RES(params->device) - 1;
#endif

return _ads101x_init_test(DEV, ADDR);
}
Expand Down Expand Up @@ -216,3 +220,87 @@ int ads101x_set_alert_parameters(const ads101x_alert_t *dev,

return ADS101X_OK;
}

#if MODULE_ADC_NG

int ads101x_adc_ng_init(void* handle, uint8_t chn, uint8_t res, uint8_t ref)
{
ads101x_t *dev = (ads101x_t *)handle;
DEBUG("%s: dev %p, chn %u\n", __func__, dev, chn);

assert(dev != NULL);
assert(res == dev->res);

if (chn >= dev->ch_numof) {
return -ENXIO;
}

uint8_t mux_gain = 0;

if (dev->params.device == ADS101X_DEV_ADS1013 ||
dev->params.device == ADS101X_DEV_ADS1113) {
assert(ref == 0);
mux_gain = ADS101X_PGA_FSR_2V048;
}
else {
mux_gain = (5 - ref) << 1;
}

switch (chn) {
case 0: mux_gain |= ADS101X_AIN0_SINGM; break;
case 1: mux_gain |= ADS101X_AIN1_SINGM; break;
case 2: mux_gain |= ADS101X_AIN2_SINGM; break;
case 3: mux_gain |= ADS101X_AIN3_SINGM; break;
default: return -ENXIO;
}

/* set the channel for next conversion */
if (ads101x_set_mux_gain(dev, mux_gain) != ADS101X_OK) {
return -1;
}

return 0;
}

int ads101x_adc_ng_single(void *handle, int32_t *dest)
{
ads101x_t *dev = (ads101x_t *)handle;
DEBUG("%s: dev %p, dest %p\n", __func__, dev, dest);

assert(dev != NULL);

int16_t raw;
/* execute one conversion for the selected channel */
if (ads101x_read_raw(dev, &raw) != 0) {
return -EIO;
}

*dest = raw;

return 0;
}

#if (ADC_NG_NUMOF == 1) && MODULE_SAUL

extern ads101x_t ads101x_devs[];

const adc_ng_driver_t ads101x_adc_ng_driver = {
.init = ads101x_adc_ng_init,
.single = ads101x_adc_ng_single,
.res_supported = (1UL << (ADS101X_RES(ADS101X_PARAM_DEVICE) - 2)),
.refs = ADS101X_REF_VOL(ADS101X_PARAM_DEVICE),
.ref_input_idx = ADC_NG_NO_SUCH_REF,
.entropy_bits = 0,
.highest_single_ended_channel = ADS101X_CH_NUMOF(ADS101X_PARAM_DEVICE) - 1,
};

const adc_ng_backend_t adc_ng_backends[ADC_NG_NUMOF] = {
{
.driver = &ads101x_adc_ng_driver,
.handle = &ads101x_devs[0]
}
};

#endif /* (ADC_NG_NUMOF == 1) && MODULE_SAUL */

#endif /* MODULE_ADC_NG */
16 changes: 13 additions & 3 deletions drivers/ads101x/include/ads101x_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ extern "C" {
#define ADS101X_PARAM_ADDR (ADS101X_I2C_ADDRESS)
#endif
#ifndef ADS101X_PARAM_MUX_GAIN
#define ADS101X_PARAM_MUX_GAIN (ADS101X_AIN0_DIFFM_AIN1 \
| ADS101X_PGA_FSR_2V048)
#define ADS101X_PARAM_MUX_GAIN (ADS101X_AIN0_DIFFM_AIN1 | ADS101X_PGA_FSR_2V048)
#endif
#ifndef ADS101X_PARAM_DEVICE
#define ADS101X_PARAM_DEVICE (ADS101X_DEV_ADS1115)
#endif

#ifndef ADS101X_PARAM_ALERT_PIN
#define ADS101X_PARAM_ALERT_PIN (GPIO_UNDEF)
#endif
Expand All @@ -55,10 +58,17 @@ extern "C" {
#endif

#ifndef ADS101X_PARAMS
#ifndef MODULE_ADC_NG
#define ADS101X_PARAMS { .i2c = ADS101X_PARAM_I2C, \
.addr = ADS101X_PARAM_ADDR, \
.mux_gain = ADS101X_PARAM_MUX_GAIN }
#endif
#else
#define ADS101X_PARAMS { .i2c = ADS101X_PARAM_I2C, \
.addr = ADS101X_PARAM_ADDR, \
.mux_gain = ADS101X_PARAM_MUX_GAIN, \
.device = ADS101X_PARAM_DEVICE }
#endif /* MODULE_ADC_NG */
#endif /* ADS101X_PARAMS */

#ifndef ADS101X_ALERT_PARAMS
#define ADS101X_ALERT_PARAMS { .i2c = ADS101X_PARAM_I2C, \
Expand Down
102 changes: 102 additions & 0 deletions drivers/include/ads101x.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ extern "C" {
#include "periph/i2c.h"
#include "periph/gpio.h"

#if MODULE_ADC_NG || DOXYGEN
#include "adc_ng.h"
#endif

/**
* @brief ADS101x/111x default address
*
Expand All @@ -47,6 +51,57 @@ extern "C" {
#define ADS101X_I2C_ADDRESS (0x48)
#endif

#if MODULE_ADC_NG || DOXYGEN

/**
* @brief Resolution supported by given ADS101x/ADS111x device
*/
#define ADS101X_RES(d) (((d == ADS101X_DEV_ADS1113) || \
(d == ADS101X_DEV_ADS1114) || \
(d == ADS101X_DEV_ADS1115)) ? 16 : 12)

/**
* @brief Reference to the corresponding array of reference voltages
*/
#define ADS101X_REF_VOL(d) (((d == ADS101X_DEV_ADS1013) || \
(d == ADS101X_DEV_ADS1113)) ? ads1013_adc_ng_refs \
: ads101x_adc_ng_refs)

/**
* @brief Number of channels supported by given ADS101x/ADS111x device
*/
#define ADS101X_CH_NUMOF(d) (((d == ADS101X_DEV_ADS1015) || \
(d == ADS101X_DEV_ADS1115)) ? 4 : 1)

/**
* @brief Array of reference voltages supported by ADS1013/ADS1113
*/
static const int16_t ads1013_adc_ng_refs[] = { 2048, 0 };

/**
* @brief Array of reference voltages supported by the other ADS101x/ADS111x devices
*/
static const int16_t ads101x_adc_ng_refs[] = { 256, 512, 1024, 2048, 4096, 6144, 0 };

/**
* @brief ADS101x/111x device variants required by the Common ADC API
*
* ADS101x/111x device variant is required by the Common ADC API to have
* information about the number of channels and the ADC resolution. The
* ADS101x/111x device variant has to be specified in configuration
* parameters.
*/
typedef enum {
ADS101X_DEV_UNKOWN = 0, /**< unknown device variant */
ADS101X_DEV_ADS1013, /**< 1 channel, 12-bit ADC */
ADS101X_DEV_ADS1014, /**< 1 channel, 12-bit ADC */
ADS101X_DEV_ADS1015, /**< 4 channel, 12-bit ADC */
ADS101X_DEV_ADS1113, /**< 1 channel, 16-bit ADC */
ADS101X_DEV_ADS1114, /**< 1 channel, 16-bit ADC */
ADS101X_DEV_ADS1115, /**< 4 channel, 16-bit ADC */
} ads101x_device_t;
#endif

/**
* @brief Named return values
*/
Expand All @@ -64,6 +119,9 @@ typedef struct ads101x_params {
i2c_t i2c; /**< i2c device */
uint8_t addr; /**< i2c address */
uint8_t mux_gain; /**< Mux and gain boolean settings */
#if MODULE_ADC_NG || DOXYGEN
ads101x_device_t device; /**< ADS101x/111x device variant */
#endif
} ads101x_params_t;

/**
Expand All @@ -82,6 +140,10 @@ typedef struct ads101x_alert_params {
*/
typedef struct ads101x {
ads101x_params_t params; /**< device driver configuration */
#if MODULE_ADC_NG || DOXYGEN
uint8_t res; /**< supported resolution */
uint8_t ch_numof; /**< number of available channels */
#endif
} ads101x_t;

/**
Expand Down Expand Up @@ -170,6 +232,46 @@ int ads101x_enable_alert(ads101x_alert_t *dev,
int ads101x_set_alert_parameters(const ads101x_alert_t *dev,
int16_t low_limit, int16_t high_limit);

#if MODULE_ADC_NG || DOXYGEN
/**
* @name ADC extension API functions
*
* These functions are defined for compatibility with the Common ADC API.
* They are required to use ADS101x/111x devices as ADC extensions.
*
* @{
*/

/**
* @brief #adc_ng_init_t callback function for the Common ADC API
*
* @note This function is for use with the Common ADC API.
*
* This function is the implementation of of #adc_ng_init function of the
* ADC extension API. Since ADS101x/ADS111x channels have not to be
* initialized, this function will not do anything.
*
* @see #adc_ng_init_t for details.
*/
int ads101x_adc_ng_init(void* handle, uint8_t chn, uint8_t res, uint8_t ref);

/**
* @brief #adc_ng_single_t callback function for the Common ADC API
*
* @note This function is for use with the Common ADC API.
*
* The function starts a single conversion and returns the result of the
* conversion or -1 in case of error. The gain that is used for the conversion
* is defined in the ads101x_params_t::mux_gain parameter. The conversion
* takes about 8 ms.
*
* @see #adc_ng_single_t for details.
*/
int ads101x_adc_ng_single(void *handle, int32_t *dest);

/** @} */
#endif /* MODULE_ADC_NG || DOXYGEN */

#ifdef __cplusplus
}
#endif
Expand Down
2 changes: 1 addition & 1 deletion sys/auto_init/saul/auto_init_ads101x.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
/**
* @brief Allocate memory for the device descriptors
*/
static ads101x_t ads101x_devs[ADS101X_NUM];
ads101x_t ads101x_devs[ADS101X_NUM];

/**
* @brief Memory for the SAUL registry entries
Expand Down
13 changes: 13 additions & 0 deletions tests/driver_ads101x_adc_ng/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
BOARD ?= arduino-mega2560
include ../Makefile.tests_common

FEATURES_PROVIDED += adc_ng

USEMODULE += ads101x
USEMODULE += adc_ng
USEMODULE += adc_ng_util
USEMODULE += fmt
USEMODULE += saul_default
USEMODULE += shell

include $(RIOTBASE)/Makefile.include
33 changes: 33 additions & 0 deletions tests/driver_ads101x_adc_ng/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Test for TI ADS101x/ADS111x as ADC extension

## Overview

This application can be used for testing the ADS101x/ADS111x device driver
together with the Common ADC API. It uses the default parameter definition
from the file `$(RIOTBASE)/drivers/ads101x/include/ads101x_params.h`.

## Usage

The shell commands `init`, `single`, `burst`, ... allow the initialization and
reading of ADS101x/ADS111x channels with a certain full scale range.

The ADS101x/ADS111x variant as well as the I2C bus and the address
are defined by the standard parameter definition from the file
`$(RIOTBASE)/drivers/ads101x/include/ads101x_params.h`. The parameter
`ADS101X_PARAM_MUX_GAIN` is not used for the test application.

By default, an ADS1115 is used as test device. To use another ADS101x/ADS111x
variant, the parameter `DADS101X_PARAM_DEVICE` has to be overriden:
```
CFLAGS='-DADS101X_PARAM_DEVICE=ADS101X_DEV_ADS1013' \
make -C tests/driver_ads101x_adc_ng BOARD=...
```

Parameters like `ADS101X_PARAM_I2C` and `ADS101X_PARAM_ADDR` can also be
overridden from the make command line:
```
CFLAGS='-ADS101X_PARAM_I2C=I2C_DEV\(1\) -DADS101X_PARAM_ADDR=\(0x49\)'
make -C tests/driver_ads101x_adc_ng BOARD=...
```

**Please note:** ADS1115 can also be used to test all other device variants.
Loading