1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

Merge pull request #8915 from ZetaR60/RIOT_ads101x

drivers/ads101x: support for ADCs
This commit is contained in:
Alexandre Abadie 2018-05-03 08:31:03 +02:00 committed by GitHub
commit f9c75d0df7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 893 additions and 0 deletions

View File

@ -6,6 +6,13 @@ ifneq (,$(filter adc%1c,$(USEMODULE)))
USEMODULE += adcxx1c
endif
ifneq (,$(filter ads101%,$(USEMODULE)))
FEATURES_REQUIRED += periph_gpio
FEATURES_REQUIRED += periph_i2c
USEMODULE += ads101x
USEMODULE += xtimer
endif
ifneq (,$(filter adxl345,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
endif

View File

@ -2,6 +2,10 @@ ifneq (,$(filter adcxx1c,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/adcxx1c/include
endif
ifneq (,$(filter ads101x,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ads101x/include
endif
ifneq (,$(filter adxl345,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/adxl345/include
endif

1
drivers/ads101x/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

216
drivers/ads101x/ads101x.c Normal file
View File

@ -0,0 +1,216 @@
/*
* Copyright (C) 2017 OTA keys S.A.
* 2018 Matthew Blue <matthew.blue.neuro@gmail.com>
*
* 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.
*/
/**
* @ingroup drivers_ads101x
* @{
*
* @file
* @brief ADS101x/111x ADC device driver
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
* @}
*/
#include "assert.h"
#include "periph/i2c.h"
#include "periph/gpio.h"
#include "xtimer.h"
#include "ads101x.h"
#include "ads101x_params.h"
#include "ads101x_regs.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
#ifndef ADS101X_READ_DELAY
#define ADS101X_READ_DELAY (8 * US_PER_MS) /* Compatible with 128SPS */
#endif
#define I2C_SPEED I2C_SPEED_FAST
#define I2C (dev->params.i2c)
#define ADDR (dev->params.addr)
static int _ads101x_init_test(i2c_t i2c, uint8_t addr);
int ads101x_init(ads101x_t *dev, const ads101x_params_t *params)
{
assert(dev && params);
dev->params = *params;
return _ads101x_init_test(I2C, ADDR);
}
int ads101x_alert_init(ads101x_alert_t *dev,
const ads101x_alert_params_t *params)
{
assert(dev && params);
dev->params = *params;
dev->cb = NULL;
dev->arg = NULL;
/* Set up alerts */
ads101x_set_alert_parameters(dev, dev->params.low_limit,
dev->params.high_limit);
return _ads101x_init_test(I2C, ADDR);
}
int _ads101x_init_test(i2c_t i2c, uint8_t addr)
{
uint8_t regs[2];
/* Acquire test */
i2c_acquire(i2c);
if (i2c_init_master(i2c, I2C_SPEED) < 0) {
i2c_release(i2c);
DEBUG("[ads101x] init - error: unable to initialize I2C bus\n");
return ADS101X_NOI2C;
}
/* Register read/write test */
i2c_read_regs(i2c, addr, ADS101X_CONF_ADDR, &regs, 2);
regs[1] = (regs[1] & ~ADS101X_DATAR_MASK) | ADS101X_DATAR_3300;
i2c_write_regs(i2c, addr, ADS101X_CONF_ADDR, &regs, 2);
i2c_read_regs(i2c, addr, ADS101X_CONF_ADDR, &regs, 2);
i2c_release(i2c);
/* Write should have actually written the register */
if ((regs[1] & ADS101X_DATAR_MASK) != ADS101X_DATAR_3300) {
DEBUG("[ads101x] init - error: unable to set reg (reg=%x)\n", regs[1]);
return ADS101X_NODEV;
}
return ADS101X_OK;
}
int ads101x_set_mux_gain(const ads101x_t *dev, uint8_t mux_gain)
{
uint8_t regs[2];
i2c_acquire(I2C);
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
/* Zero mux and gain */
regs[0] &= ~ADS101X_MUX_MASK;
regs[0] &= ~ADS101X_PGA_MASK;
/* Write mux and gain */
regs[0] |= mux_gain;
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
i2c_release(I2C);
return ADS101X_OK;
}
int ads101x_read_raw(const ads101x_t *dev, int16_t *raw)
{
uint8_t regs[2];
int status;
i2c_acquire(I2C);
/* Read control register */
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
/* Tell the ADC to aquire a single-shot sample */
regs[0] |= ADS101X_CONF_OS_CONV;
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
/* Wait for the sample to be aquired */
xtimer_usleep(ADS101X_READ_DELAY);
/* Read the sample */
status = i2c_read_regs(I2C, ADDR, ADS101X_CONV_RES_ADDR, &regs, 2);
i2c_release(I2C);
/* Status should equal bytes asked for (2) */
if (status != 2) {
return ADS101X_NODATA;
}
/* If all okay, change raw value */
*raw = (int16_t)(regs[0] << 8) | (int16_t)(regs[1]);
return ADS101X_OK;
}
int ads101x_enable_alert(ads101x_alert_t *dev,
ads101x_alert_cb_t cb, void *arg)
{
uint8_t regs[2];
if (dev->params.alert_pin == GPIO_UNDEF) {
return ADS101X_OK;
}
/* Read control register */
i2c_acquire(I2C);
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
/* Enable alert comparator */
regs[1] &= ~ADS101X_CONF_COMP_DIS;
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
i2c_release(I2C);
/* Enable interrupt */
dev->arg = arg;
dev->cb = cb;
gpio_init_int(dev->params.alert_pin, GPIO_IN, GPIO_FALLING, cb, arg);
return ADS101X_OK;
}
int ads101x_set_alert_parameters(const ads101x_alert_t *dev,
int16_t low_limit, int16_t high_limit)
{
uint8_t regs[2];
i2c_acquire(I2C);
/* Set up low_limit */
regs[0] = (uint8_t)(low_limit >> 8);
regs[1] = (uint8_t)low_limit;
i2c_write_regs(I2C, ADDR, ADS101X_LOW_LIMIT_ADDR, &regs, 2);
/* Set up high_limit */
regs[0] = (uint8_t)(high_limit >> 8);
regs[1] = (uint8_t)high_limit;
i2c_write_regs(I2C, ADDR, ADS101X_HIGH_LIMIT_ADDR, &regs, 2);
/* Read control register */
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
/* Set up window mode */
if (low_limit != 0) {
/* Enable window mode */
regs[1] |= ADS101X_CONF_COMP_MODE_WIND;
}
else {
/* Disable window mode */
regs[1] &= ~ADS101X_CONF_COMP_MODE_WIND;
}
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2);
i2c_release(I2C);
return ADS101X_OK;
}

View File

@ -0,0 +1,70 @@
/*
* Copyright (C) 2017 OTA keys S.A.
* 2018 Matthew Blue <matthew.blue.neuro@gmail.com>
*
* 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.
*/
/**
* @ingroup drivers_ads101x
* @{
*
* @file
* @brief ADS101x/111x adaption to the RIOT actuator/sensor interface
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
*
* @}
*/
#include <string.h>
#include <stdio.h>
#include "saul.h"
#include "ads101x.h"
#include "ads101x_regs.h"
/* LSB conversion to power of 10
* (5/8) * 2^16 = 40960 */
#define CONV_TO_B10 (40960L)
static int read_adc(const void *dev, phydat_t *res)
{
/* Change the mux channel */
ads101x_set_mux_gain((const ads101x_t *)dev,
((ads101x_t *)dev)->params.mux_gain);
/* Read raw value */
if (ads101x_read_raw((const ads101x_t *)dev, res->val) < 0) {
return ECANCELED;
}
/* Special case for 2.048V */
/* (this is the fixed FSR of ADS1013 and ADS1113) */
if ((((ads101x_t *)dev)->params.mux_gain & ADS101X_PGA_MASK)
== ADS101X_PGA_FSR_2V048) {
/* LSB == 62.5uV to LSB == 100uV */
*(res->val) = (int16_t)((CONV_TO_B10 * (int32_t)*(res->val)) >> 16);
/* 100uV == 2^-4 V */
res->unit = UNIT_V;
res->scale = -4;
}
else {
/* Otherwise let the user deal with it */
res->unit = UNIT_NONE;
res->scale = 0;
}
return 1;
}
const saul_driver_t ads101x_saul_driver = {
.read = read_adc,
.write = saul_notsup,
.type = SAUL_SENSE_ANALOG,
};

View File

@ -0,0 +1,100 @@
/*
* Copyright (C) 2017 OTA keys S.A.
* 2018 Matthew Blue <matthew.blue.neuro@gmail.com>
*
* 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.
*/
/**
* @ingroup drivers_ads101x
* @{
*
* @file
* @brief Default configuration for ADS101x/111x devices
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
*/
#ifndef ADS101X_PARAMS_H
#define ADS101X_PARAMS_H
#include "board.h"
#include "saul_reg.h"
#include "ads101x.h"
#include "ads101x_regs.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Set default configuration parameters for the ADS101x/111x driver
* @{
*/
#ifndef ADS101X_PARAM_I2C
#define ADS101X_PARAM_I2C (I2C_DEV(0))
#endif
#ifndef ADS101X_PARAM_ADDR
#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)
#endif
#ifndef ADS101X_PARAM_ALERT_PIN
#define ADS101X_PARAM_ALERT_PIN (GPIO_UNDEF)
#endif
#ifndef ADS101X_PARAM_LOW_LIMIT
#define ADS101X_PARAM_LOW_LIMIT (10000U)
#endif
#ifndef ADS101X_PARAM_HIGH_LIMIT
#define ADS101X_PARAM_HIGH_LIMIT (20000U)
#endif
#ifndef ADS101X_PARAMS
#define ADS101X_PARAMS { .i2c = ADS101X_PARAM_I2C, \
.addr = ADS101X_PARAM_ADDR, \
.mux_gain = ADS101X_PARAM_MUX_GAIN }
#endif
#ifndef ADS101X_ALERT_PARAMS
#define ADS101X_ALERT_PARAMS { .i2c = ADS101X_PARAM_I2C, \
.addr = ADS101X_PARAM_ADDR, \
.alert_pin = ADS101X_PARAM_ALERT_PIN, \
.low_limit = ADS101X_PARAM_LOW_LIMIT, \
.high_limit = ADS101X_PARAM_HIGH_LIMIT }
#endif
#ifndef ADS101X_SAUL_INFO
#define ADS101X_SAUL_INFO { .name = "ads101x" }
#endif
/** @} */
/**
* @brief ADS101X/111x defaults if not defined for a board or application
*/
static const ads101x_params_t ads101x_params[] =
{
ADS101X_PARAMS
};
static const ads101x_alert_params_t ads101x_alert_params[] =
{
ADS101X_ALERT_PARAMS
};
/**
* @brief Additional meta information to keep in the SAUL registry
*/
static const saul_reg_info_t ads101x_saul_info[] =
{
ADS101X_SAUL_INFO
};
#ifdef __cplusplus
}
#endif
#endif /* ADS101X_PARAMS_H */
/** @} */

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2017 OTA keys S.A.
* 2018 Matthew Blue <matthew.blue.neuro@gmail.com>
*
* 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.
*/
/**
* @ingroup drivers_ads101x
* @{
*
* @file
* @brief Register definition for ADS101x/111x devices
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
*/
#ifndef ADS101X_REGS_H
#define ADS101X_REGS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name ADS101x/111x register addesses
* @{
*/
#define ADS101X_CONV_RES_ADDR (0)
#define ADS101X_CONF_ADDR (1)
#define ADS101X_LOW_LIMIT_ADDR (2)
#define ADS101X_HIGH_LIMIT_ADDR (3)
/** @} */
/**
* @name ADS101x/111x Config flags
*
* Comparator flags have no effect on ADS1013 and ADS1113.
*
* @{
*/
#define ADS101X_CONF_OS_CONV (1 << 7)
#define ADS101X_CONF_COMP_MODE_WIND (1 << 4)
#define ADS101X_CONF_COMP_DIS ((1 << 1) | (1 << 0))
/** @} */
/**
* @name ADS101x/111x mux settings
*
* Supports both single mode and differential.
* This has no effect on ADS1013-4 and ADS1113-4.
*
* @{
*/
#define ADS101X_MUX_MASK ((1 << 6) | (1 << 5) | (1 << 4))
#define ADS101X_AIN0_DIFFM_AIN1 ((0 << 6) | (0 << 5) | (0 << 4))
#define ADS101X_AIN0_DIFFM_AIN3 ((0 << 6) | (0 << 5) | (1 << 4))
#define ADS101X_AIN1_DIFFM_AIN3 ((0 << 6) | (1 << 5) | (0 << 4))
#define ADS101X_AIN2_DIFFM_AIN3 ((0 << 6) | (1 << 5) | (1 << 4))
#define ADS101X_AIN0_SINGM ((1 << 6) | (0 << 5) | (0 << 4))
#define ADS101X_AIN1_SINGM ((1 << 6) | (0 << 5) | (1 << 4))
#define ADS101X_AIN2_SINGM ((1 << 6) | (1 << 5) | (0 << 4))
#define ADS101X_AIN3_SINGM ((1 << 6) | (1 << 5) | (1 << 4))
/** @} */
/**
* @name ADS101x/111x programmable gain
*
* Sets the full-scale range (max voltage value).
* This has no effect on ADS1013 and ADS1113 (both use 2.048V FSR).
*
* @{
*/
#define ADS101X_PGA_MASK ((1 << 3) | (1 << 2) | (1 << 1))
#define ADS101X_PGA_FSR_6V144 ((0 << 3) | (0 << 2) | (0 << 1))
#define ADS101X_PGA_FSR_4V096 ((0 << 3) | (0 << 2) | (1 << 1))
#define ADS101X_PGA_FSR_2V048 ((0 << 3) | (1 << 2) | (0 << 1))
#define ADS101X_PGA_FSR_1V024 ((0 << 3) | (1 << 2) | (1 << 1))
#define ADS101X_PGA_FSR_0V512 ((1 << 3) | (0 << 2) | (0 << 1))
#define ADS101X_PGA_FSR_0V256 ((1 << 3) | (0 << 2) | (1 << 1))
/** @} */
/**
* @name ADS101x/111x data rate settings
*
* Determines how quickly samples are taken (even on one-shot mode)
*
* @{
*/
#define ADS101X_DATAR_MASK ((1 << 7) | (1 << 6) | (1 << 5))
#define ADS101X_DATAR_128 ((0 << 7) | (0 << 6) | (0 << 5))
#define ADS101X_DATAR_250 ((0 << 7) | (0 << 6) | (1 << 5))
#define ADS101X_DATAR_490 ((0 << 7) | (1 << 6) | (0 << 5))
#define ADS101X_DATAR_920 ((0 << 7) | (1 << 6) | (1 << 5))
#define ADS101X_DATAR_1600 ((1 << 7) | (0 << 6) | (0 << 5))
#define ADS101X_DATAR_2400 ((1 << 7) | (0 << 6) | (1 << 5))
#define ADS101X_DATAR_3300 ((1 << 7) | (1 << 6) | (0 << 5))
#ifdef __cplusplus
}
#endif
#endif /* ADS101X_REGS_H */
/** @} */

175
drivers/include/ads101x.h Normal file
View File

@ -0,0 +1,175 @@
/*
* Copyright (C) 2017 OTA keys S.A.
* 2018 Matthew Blue <matthew.blue.neuro@gmail.com>
*
* 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.
*/
/**
* @defgroup drivers_ads101x ADS101x/111x ADC device driver
* @ingroup drivers_sensors
* @brief I2C Analog-to-Digital Converter device driver
*
* This driver works with ADS1013-5 and ADS1113-5.
* @{
*
* @file
* @brief ADS101x/111x ADC device driver
*
* ADC and alert functionality are separated into two devices to
* prevent wasteful representations on muxed devices.
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
*/
#ifndef ADS101X_H
#define ADS101X_H
#ifdef __cplusplus
extern "C" {
#endif
#include "periph/i2c.h"
#include "periph/gpio.h"
/**
* @brief ADS101x/111x default address
*
* Address pin tied to: GND (0x48), Vcc (0x49), SDA (0x50), SCL (0x51)
*/
#ifndef ADS101X_I2C_ADDRESS
#define ADS101X_I2C_ADDRESS (0x48)
#endif
/**
* @brief Named return values
*/
enum {
ADS101X_OK = 0, /**< everything was fine */
ADS101X_NOI2C = -1, /**< I2C communication failed */
ADS101X_NODEV = -2, /**< no ADS101X device found on the bus */
ADS101X_NODATA = -3 /**< no data available */
};
/**
* @brief ADS101x/111x params
*/
typedef struct ads101x_params {
i2c_t i2c; /**< i2c device */
uint8_t addr; /**< i2c address */
uint8_t mux_gain; /**< Mux and gain boolean settings */
} ads101x_params_t;
/**
* @brief ADS101x/111x alert params
*/
typedef struct ads101x_alert_params {
i2c_t i2c; /**< i2c device */
uint8_t addr; /**< i2c address */
gpio_t alert_pin; /**< alert pin (GPIO_UNDEF if not connected) */
int16_t low_limit; /**< alert low value */
int16_t high_limit; /**< alert high value */
} ads101x_alert_params_t;
/**
* @brief ADS101x/111x device descriptor
*/
typedef struct ads101x {
ads101x_params_t params; /**< device driver configuration */
} ads101x_t;
/**
* @brief ADS101x/111x alert callback
*/
typedef void (*ads101x_alert_cb_t)(void *);
/**
* @brief ADS101x/111x alert device descriptor
*/
typedef struct ads101x_alert {
ads101x_alert_params_t params; /**< device driver configuration */
ads101x_alert_cb_t cb; /**< alert callback */
void *arg; /**< alert callback param */
} ads101x_alert_t;
/**
* @brief Initialize an ADS101x/111x ADC device (ADC only)
*
* @param[in,out] dev device descriptor
* @param[in] params device configuration
*
* @return zero on successful initialization, non zero on error
*/
int ads101x_init(ads101x_t *dev, const ads101x_params_t *params);
/**
* @brief Initialize an ADS101x/111x alert device
*
* @param[in,out] dev device descriptor
* @param[in] params device configuration
*
* @return zero on successful initialization, non zero on error
*/
int ads101x_alert_init(ads101x_alert_t *dev,
const ads101x_alert_params_t *params);
/**
* @brief Set mux and gain
*
* Mux settings have no effect on ADS1013-4 and ADS1113-4.
* Gain settings have no effect on ADS1013 and ADS1113.
*
* @param[in] dev device descriptor
* @param[in] mux_gain mux and gain boolean values
*
* @return zero on successful read, non zero on error
*/
int ads101x_set_mux_gain(const ads101x_t *dev, uint8_t mux_gain);
/**
* @brief Read a raw ADC value
*
* @param[in] dev device descriptor
* @param[out] raw read value
*
* @return zero on successful read, non zero on error
*/
int ads101x_read_raw(const ads101x_t *dev, int16_t *raw);
/**
* @brief Enable alert interrupt
*
* Alert settings have no effect on ADS1013 and ADS1113.
*
* @param[in] dev device descriptor
* @param[in] cb callback called when the alert fires
* @param[in] arg callback argument
*
* @return zero on success, non zero on error
*/
int ads101x_enable_alert(ads101x_alert_t *dev,
ads101x_alert_cb_t cb, void *arg);
/**
* @brief Set the alert parameters
*
* Alert settings have no effect on ADS1013 and ADS1113.
*
* @param[in,out] dev device descriptor
* @param[in] low_limit alert low limit
* @param[in] high_limit alert high limit
*
* @return zero on success, non zero on error
*/
int ads101x_set_alert_parameters(const ads101x_alert_t *dev,
int16_t low_limit, int16_t high_limit);
#ifdef __cplusplus
}
#endif
#endif /* ADS101X_H */
/** @} */

View File

@ -389,6 +389,10 @@ auto_init_mpu9150();
extern void auto_init_adcxx1c(void);
auto_init_adcxx1c();
#endif
#ifdef MODULE_ADS101X
extern void auto_init_ads101x(void);
auto_init_ads101x();
#endif
#ifdef MODULE_LIS2DH12
extern void auto_init_lis2dh12(void);
auto_init_lis2dh12();

View File

@ -0,0 +1,78 @@
/*
* Copyright (C) 2017 OTA keys S.A.
* 2018 Matthew Blue <matthew.blue.neuro@gmail.com>
*
* 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.
*
*/
/**
* @ingroup auto_init_saul
* @{
*
* @file
* @brief Auto initialization of ADS101x/111x ADCs
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
*
* @}
*/
#ifdef MODULE_ADS101X
#include "assert.h"
#include "log.h"
#include "saul_reg.h"
#include "ads101x.h"
#include "ads101x_params.h"
/**
* @brief Define the number of configured sensors
*/
#define ADS101X_NUM (sizeof(ads101x_params) / sizeof(ads101x_params[0]))
/**
* @brief Allocate memory for the device descriptors
*/
static ads101x_t ads101x_devs[ADS101X_NUM];
/**
* @brief Memory for the SAUL registry entries
*/
static saul_reg_t saul_entries[ADS101X_NUM];
/**
* @brief Define the number of saul info
*/
#define ADS101X_INFO_NUM (sizeof(ads101x_saul_info) / sizeof(ads101x_saul_info[0]))
/**
* @brief Reference the driver struct
*/
extern saul_driver_t ads101x_saul_driver;
void auto_init_ads101x(void)
{
assert(ADS101X_INFO_NUM == ADS101X_NUM);
for (unsigned i = 0; i < ADS101X_NUM; i++) {
LOG_DEBUG("[auto_init_saul] initializing ads101x #%d\n", i);
if (ads101x_init(&ads101x_devs[i], &ads101x_params[i]) < 0) {
LOG_ERROR("[auto_init_saul] error initializing ads101x #%d\n", i);
continue;
}
saul_entries[i].dev = &(ads101x_devs[i]);
saul_entries[i].name = ads101x_saul_info[i].name;
saul_entries[i].driver = &ads101x_saul_driver;
saul_reg_add(&(saul_entries[i]));
}
}
#else
typedef int dont_be_pedantic;
#endif /* MODULE_ADS101X */

View File

@ -0,0 +1,7 @@
include ../Makefile.tests_common
FEATURES_REQUIRED = periph_i2c
USEMODULE += ads101x
include $(RIOTBASE)/Makefile.include

124
tests/driver_ads101x/main.c Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright (C) 2017 OTA keys S.A.
* 2018 Matthew Blue <matthew.blue.neuro@gmail.com>
*
* 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.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Test application for the ADS101x/111x ADC driver
*
* @author Vincent Dupont <vincent@otakeys.com>
* @author Matthew Blue <matthew.blue.neuro@gmail.com>
* @}
*/
#include <stdio.h>
#include "xtimer.h"
#include "timex.h"
#include "ads101x.h"
#include "ads101x_params.h"
#include "ads101x_regs.h"
#define SLEEP (100 * US_PER_MS)
static ads101x_t dev;
static ads101x_alert_t alert_dev;
static void alert_cb(void *arg)
{
(void)arg;
puts("\n[Alert!]");
}
int main(void)
{
int16_t data;
puts("ADS101X analog to digital driver test application\n");
printf("Initializing ADS101x analog to digital at I2C_DEV(%i)... ",
ads101x_params->i2c);
if (ads101x_init(&dev, ads101x_params) == ADS101X_OK) {
puts("[OK]");
}
else {
puts("[Failed]");
return -1;
}
printf("Initializing ADS101x alert at I2C_DEV(%i)... ",
ads101x_alert_params->i2c);
if (ads101x_alert_init(&alert_dev, ads101x_alert_params) == ADS101X_OK) {
puts("[OK]");
}
else {
puts("[Failed]");
return -1;
}
printf("Enabling alert interrupt: ");
if (ads101x_enable_alert(&alert_dev, alert_cb, NULL) == ADS101X_OK) {
puts("[OK]");
}
else {
puts("[Failed]");
return -1;
}
while (1) {
printf("Raw analog read. CH0: ");
ads101x_set_mux_gain(&dev, ADS101X_AIN0_SINGM | ADS101X_PGA_FSR_2V048);
if (ads101x_read_raw(&dev, &data) == ADS101X_OK) {
printf("%d", data);
}
else {
puts("[Fail]");
continue;
}
printf(" CH1: ");
ads101x_set_mux_gain(&dev, ADS101X_AIN1_SINGM | ADS101X_PGA_FSR_2V048);
if (ads101x_read_raw(&dev, &data) == ADS101X_OK) {
printf("%d", data);
}
else {
puts("[Fail]");
continue;
}
printf(" CH2: ");
ads101x_set_mux_gain(&dev, ADS101X_AIN2_SINGM | ADS101X_PGA_FSR_2V048);
if (ads101x_read_raw(&dev, &data) == ADS101X_OK) {
printf("%d", data);
}
else {
puts("[Fail]");
continue;
}
printf(" CH3: ");
ads101x_set_mux_gain(&dev, ADS101X_AIN3_SINGM | ADS101X_PGA_FSR_2V048);
if (ads101x_read_raw(&dev, &data) == ADS101X_OK) {
printf("%d", data);
}
else {
puts("[Fail]");
continue;
}
puts("");
xtimer_usleep(SLEEP);
}
return 0;
}