1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00

Merge pull request #11306 from MrKevinWeiss/pr/addi2ctocc26xx

cpu/cc260x: add I2C implementation
This commit is contained in:
Sebastian Meiling 2019-04-08 21:00:23 +02:00 committed by GitHub
commit 7484af6d36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 503 additions and 76 deletions

View File

@ -2,6 +2,7 @@
FEATURES_PROVIDED += periph_gpio periph_gpio_irq FEATURES_PROVIDED += periph_gpio periph_gpio_irq
FEATURES_PROVIDED += periph_timer FEATURES_PROVIDED += periph_timer
FEATURES_PROVIDED += periph_uart FEATURES_PROVIDED += periph_uart
FEATURES_PROVIDED += periph_i2c
# The board MPU family (used for grouping by the CI system) # The board MPU family (used for grouping by the CI system)
FEATURES_MCU_GROUP = cortex_m3_1 FEATURES_MCU_GROUP = cortex_m3_1

View File

@ -80,6 +80,15 @@ static const timer_conf_t timer_config[] = {
#define UART_TX_PIN (3) #define UART_TX_PIN (3)
/** @} */ /** @} */
/**
* @name I2C configuration
* @{
*/
#define I2C_NUMOF (1)
#define I2C_SDA_PIN (14)
#define I2C_SCL_PIN (15)
/** @} */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,3 +1,5 @@
export CPU_ARCH := cortex-m3 export CPU_ARCH := cortex-m3
USEMODULE += periph_common
include $(RIOTMAKE)/arch/cortexm.inc.mk include $(RIOTMAKE)/arch/cortexm.inc.mk

View File

@ -106,6 +106,7 @@ typedef enum IRQn
* @{ * @{
*/ */
#define FLASH_BASE 0x00000000 /**< FLASH base address */ #define FLASH_BASE 0x00000000 /**< FLASH base address */
#define PERIPH_BASE 0x40000000 /**< Peripheral base address */
/*@}*/ /*@}*/
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -55,6 +55,138 @@ typedef struct {
reg32_t MCR; /**< master configuration */ reg32_t MCR; /**< master configuration */
} i2c_regs_t; } i2c_regs_t;
/**
* @brief I2C master function enable
* @details 0h = Master mode is disabled.
* 1h = Master mode is enabled
*/
#define MCR_MFE 0x00000010
/**
* @brief SCL clock period set to 100 kHZ
* @details {PERDMACLK / [2 × (SCL_LP + SCL_HP) × SCL_CLK]} 1
* with SCL_LP==6 && SCL_HP==4 use 0x17 for 100kHZ with 48MHZ CPU clock
* This field specifies the period of the SCL clock.
* SCL_PRD = 2*(1+TPR)*(SCL_LP + SCL_HP)*CLK_PRD
* where:
* SCL_PRD is the SCL line period (I2C clock).
* TPR is the timer period register value (range of 1 to 127)
* SCL_LP is the SCL low period (fixed at 6).
* SCL_HP is the SCL high period (fixed at 4).
* CLK_PRD is the system clock period in ns.
*/
#define MTPR_TPR_100KHZ 0x00000017
/**
* @brief Receive or Send
* @details This bit-field specifies if the next operation is a receive (high) or a
* transmit/send (low) from the addressed slave SA.
* 0h = Transmit/send data to slave
* 1h = Receive data from slave
*/
#define MSA_RS 0x00000001
/**
* @brief Bus busy
* @details 0: The I2C bus is idle.
* 1: The I2C bus is busy.
* The bit changes based on the MCTRL.START and MCTRL.STOP
* conditions.
*/
#define MSTAT_BUSBSY 0x00000040
/**
* @brief I2C idle
* @details 0: The I2C controller is not idle.
* 1: The I2C controller is idle.
*/
#define MSTAT_IDLE 0x00000020
/**
* @brief Arbitration lost
* @details 0: The I2C controller won arbitration.
* 1: The I2C controller lost arbitration.
*/
#define MSTAT_ARBLST 0x00000010
/**
* @brief Data Was Not Acknowledge
* @details 0: The transmitted data was acknowledged.
* 1: The transmitted data was not acknowledged.
*/
#define MSTAT_DATACK_N 0x00000008
/**
* @brief Address Was Not Acknowledge
* @details 0: The transmitted address was acknowledged.
* 1: The transmitted address was not acknowledged.
*/
#define MSTAT_ADRACK_N 0x00000004
/**
* @brief Error
* @details 0: No error was detected on the last operation.
* 1: An error occurred on the last operation.
*/
#define MSTAT_ERR 0x00000002
/**
* @brief I2C busy
* @details 0: The controller is idle.
* 1: The controller is busy.
* When this bit-field is set, the other status bits are not valid.
@note The I2C controller requires four SYSBUS clock cycles to
* assert the BUSY status after I2C master operation has been initiated
* through MCTRL register.
* Hence after programming MCTRL register, application is requested
* to wait for four SYSBUS clock cycles before issuing a controller
* status inquiry through MSTAT register.
* Any prior inquiry would result in wrong status being reported.
*/
#define MSTAT_BUSY 0x00000001
/**
* @brief Data acknowledge enable
* @details 0: The received data byte is not acknowledged automatically by the
* master.
* 1: The received data byte is acknowledged automatically by the
* master.
* This bit-field must be cleared when the I2C bus controller requires
* no further data to be transmitted from the slave transmitter.
* 0h = Disable acknowledge
* 1h = Enable acknowledge
*/
#define MCTRL_ACK 0x00000008
/**
* @brief This bit-field determines if the cycle stops at the end of the data
cycle or continues on to a repeated START condition
* @details 0: The controller does not generate the Stop condition.
* 1: The controller generates the Stop condition.
* 0h = Disable STOP
* 1h = Enable STOP
*/
#define MCTRL_STOP 0x00000004
/**
* @brief This bit-field generates the Start or Repeated Start condition
* @details 0: The controller does not generate the Start condition.
* 1: The controller generates the Start condition.
* 0h = Disable START
* 1h = Enable START
*/
#define MCTRL_START 0x00000002
/**
* @brief I2C master enable
* @details 0: The master is disabled.
* 1: The master is enabled to transmit or receive data.
* 0h = Disable Master
* 1h = Enable Master
*/
#define MCTRL_RUN 0x00000001
/** @ingroup cpu_specific_peripheral_memory_map /** @ingroup cpu_specific_peripheral_memory_map
* @{ * @{
*/ */

View File

@ -76,6 +76,11 @@ typedef struct {
uint8_t chn; /**< number of channels [1,2] */ uint8_t chn; /**< number of channels [1,2] */
} timer_conf_t; } timer_conf_t;
#define PERIPH_I2C_NEED_READ_REG
#define PERIPH_I2C_NEED_READ_REGS
#define PERIPH_I2C_NEED_WRITE_REG
#define PERIPH_I2C_NEED_WRITE_REGS
#endif /* ifndef DOXYGEN */ #endif /* ifndef DOXYGEN */
#ifdef __cplusplus #ifdef __cplusplus

277
cpu/cc26x0/periph/i2c.c Normal file
View File

@ -0,0 +1,277 @@
/*
* Copyright (C) 2018 Kaspar Schleiser <kaspar@schleiser.de>
*
* 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 cpu_cc26x0
* @ingroup drivers_periph_i2c
* @{
*
* @file
* @brief Low-level I2C driver implementation
* @note This CPU has weak pullups, external pullup resistors may be
* required.
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*
* @}
*/
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include "mutex.h"
#include "cpu.h"
#include "periph/i2c.h"
#define ENABLE_DEBUG 0
#include "debug.h"
#define PREG(x) DEBUG("%s=0x%08x\n", #x, (unsigned)x);
/**
* @brief Mutex lock for the only available I2C periph
* @note If multiple I2C devices are added locks must be an array for each one.
*/
static mutex_t _lock;
static int _check_errors(void)
{
int ret = 0;
/* The reference manual (SWCU117H) is ambiguous on how to wait:
*
* 1. 21.4 8. says "wait until BUSBUSY is cleared"
* 2. command flow diagrams (e.g., 21.3.5.1) indicate to wait while
* BUSY is set
*
* (3. 21.5.1.10 says BUSY is only valid after 4 SYSBUS clock cycles)
*
* Waiting first for cleared IDLE and then for cleared BUSY works fine.
*/
/* wait for transfer to be complete, this also could be a few nops... */
while (I2C->MSTAT & MSTAT_IDLE) {}
while (I2C->MSTAT & MSTAT_BUSY) {}
/* check if there was an error */
if (I2C->MSTAT & MSTAT_ERR) {
DEBUG("%s\n", __FUNCTION__);
PREG(I2C->MSTAT);
ret = -ETIMEDOUT;
if (I2C->MSTAT & MSTAT_ADRACK_N) {
DEBUG("ADDRESS NACK\n");
return -ENXIO;
}
else if (I2C->MSTAT & MSTAT_DATACK_N) {
DEBUG("DATA NACK\n");
ret = -EIO;
}
else if (I2C->MSTAT & MSTAT_ARBLST) {
DEBUG("ARBITRATION LOSS\n");
ret = -EAGAIN;
}
/*
* If a non-NACK error occurs we must reinit or lock up.
* dev = 0 since it is the only one, if more are added it should be
* the dev num, this is done to avoid passing in arguments and
* increasing code size.
*/
i2c_init(0);
return ret;
}
return ret;
}
void i2c_init(i2c_t devnum)
{
(void)devnum;
assert(devnum < I2C_NUMOF);
/* Make sure everything is shut off in case of reinit */
PRCM->PDCTL0SERIAL = 0;
I2C->MCR = 0;
PRCM->I2CCLKGR = 0;
/* enable SERIAL power domain */
PRCM->PDCTL0SERIAL = 1;
while (!(PRCM->PDSTAT0 & PDSTAT0_SERIAL_ON)) {}
/* enable i2c clock in run mode */
PRCM->I2CCLKGR = 1;
PRCM->CLKLOADCTL |= CLKLOADCTL_LOAD;
while (!(PRCM->CLKLOADCTL & CLKLOADCTL_LOADDONE)) {}
/* configure pins */
IOC->CFG[I2C_SDA_PIN] = (IOCFG_PORTID_I2C_MSSDA
| IOCFG_INPUT_ENABLE
| IOCFG_IOMODE_OPEN_DRAIN
| IOCFG_PULLCTL_UP);
IOC->CFG[I2C_SCL_PIN] = (IOCFG_PORTID_I2C_MSSCL
| IOCFG_INPUT_ENABLE
| IOCFG_IOMODE_OPEN_DRAIN
| IOCFG_PULLCTL_UP);
/* initialize I2C master */
I2C->MCR = MCR_MFE;
/* configure clock speed
* {PERDMACLK / [2 × (SCL_LP + SCL_HP) × SCL_CLK]} 1
* with SCL_LP==6 && SCL_HP==4 use 0x17 for 100kHZ with 48MHZ CPU clock */
I2C->MTPR = MTPR_TPR_100KHZ;
}
int i2c_acquire(i2c_t dev)
{
assert(dev < I2C_NUMOF);
mutex_lock(&_lock);
return 0;
}
int i2c_release(i2c_t dev)
{
assert(dev < I2C_NUMOF);
mutex_unlock(&_lock);
return 0;
}
int i2c_read_bytes(i2c_t dev, uint16_t addr,
void *data, size_t len, uint8_t flags)
{
(void)dev;
int ret = 0;
char *bufpos = data;
DEBUG("%s %u\n", __FUNCTION__, len);
PREG(I2C->MSTAT);
assert(dev < I2C_NUMOF);
assert(data != NULL);
/* Check for unsupported operations */
if (flags & I2C_ADDR10) {
return -EOPNOTSUPP;
}
/* Check for wrong arguments given */
if (len == 0) {
return -EINVAL;
}
if (!(I2C->MSTAT & MSTAT_BUSBSY) && (flags & I2C_NOSTART)) {
return -EINVAL;
}
/* Sequence may be omitted in a single master system */
while (I2C->MSTAT & MSTAT_BUSY) {}
I2C->MSA = ((uint32_t)addr << 1) | MSA_RS;
while (len--) {
DEBUG("LOOP %u\n", len);
/* setup transfer */
uint32_t mctrl = MCTRL_RUN;
if (!(flags & I2C_NOSTART)) {
DEBUG("START\n");
mctrl |= MCTRL_START;
/* make note not to generate START from second byte onwards */
flags |= I2C_NOSTART;
}
/* after last byte, generate STOP unless told not to */
if (!len && !(flags & I2C_NOSTOP)) {
DEBUG("STOP\n");
mctrl |= MCTRL_STOP;
}
else {
DEBUG("ACK\n");
mctrl |= MCTRL_ACK;
}
while (I2C->MSTAT & MSTAT_BUSY) {}
/* initiate transfer */
I2C->MCTRL = mctrl;
/* check if there was an error */
ret = _check_errors();
if (ret != 0) {
return ret;
}
/* copy next byte from I2C data register */
DEBUG("IN=0x%02x\n", (unsigned)I2C->MDR);
*bufpos++ = I2C->MDR;
}
return ret;
}
int i2c_write_bytes(i2c_t dev, uint16_t addr, const void *data, size_t len,
uint8_t flags)
{
(void)dev;
int ret = 0;
const unsigned char *bufpos = data;
DEBUG("%s %u\n", __FUNCTION__, len);
PREG(I2C->MSTAT);
assert(dev < I2C_NUMOF);
assert(data != NULL);
/* Check for unsupported operations */
if (flags & I2C_ADDR10) {
return -EOPNOTSUPP;
}
/* Check for wrong arguments given */
if (len == 0) {
return -EINVAL;
}
if (!(I2C->MSTAT & MSTAT_BUSBSY) && (flags & I2C_NOSTART)) {
return -EINVAL;
}
/* Since write is 0 we just need shift the address in */
I2C->MSA = (uint32_t)addr << 1;
/* Sequence may be omitted in a single master system. */
while (I2C->MSTAT & MSTAT_BUSY) {}
while (len--) {
DEBUG("LOOP %u 0x%2x\n", len, (unsigned)*bufpos);
/* copy next byte into I2C data register */
I2C->MDR = *bufpos++;
/* setup transfer */
uint32_t mctrl = MCTRL_RUN;
if (!(flags & I2C_NOSTART)) {
DEBUG("START\n");
mctrl |= MCTRL_START;
/* make note not to generate START from second byte onwards */
flags |= I2C_NOSTART;
}
/* after last byte, generate STOP unless told not to */
if (!len && !(flags & I2C_NOSTOP)) {
DEBUG("STOP\n");
mctrl |= MCTRL_STOP;
}
/* initiate transfer */
I2C->MCTRL = mctrl;
/* check if there was an error */
ret = _check_errors();
if (ret != 0) {
return ret;
}
}
return ret;
}

View File

@ -30,7 +30,7 @@
#include "xtimer.h" #include "xtimer.h"
#define I2C (dev->params.i2c) #define DEV (dev->params.i2c)
#define ADDR (dev->params.addr) #define ADDR (dev->params.addr)
#define CONF_TEST_VALUE (1 << AD7746_CONFIGURATION_VTF1_BIT) #define CONF_TEST_VALUE (1 << AD7746_CONFIGURATION_VTF1_BIT)
@ -122,13 +122,13 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
assert(dev && params); assert(dev && params);
dev->params = *params; dev->params = *params;
i2c_acquire(I2C); i2c_acquire(DEV);
uint8_t reg = 0; uint8_t reg = 0;
/* Test communication write and read configuration register */ /* Test communication write and read configuration register */
status = i2c_write_reg(I2C, ADDR, AD7746_REG_CONFIGURATION, CONF_TEST_VALUE, status = i2c_write_reg(DEV, ADDR, AD7746_REG_CONFIGURATION, CONF_TEST_VALUE,
0); 0);
status += i2c_read_reg(I2C, ADDR, AD7746_REG_CONFIGURATION, &reg, 0); status += i2c_read_reg(DEV, ADDR, AD7746_REG_CONFIGURATION, &reg, 0);
if (status < 0 || reg != CONF_TEST_VALUE) { if (status < 0 || reg != CONF_TEST_VALUE) {
DEBUG("[ad7746] init - error: unable to communicate with the device " DEBUG("[ad7746] init - error: unable to communicate with the device "
@ -140,7 +140,7 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
/* Enable capacitive channel and select input */ /* Enable capacitive channel and select input */
reg = (1 << AD7746_CAP_SETUP_CAPEN_BIT) | reg = (1 << AD7746_CAP_SETUP_CAPEN_BIT) |
(dev->params.cap_input << AD7746_CAP_SETUP_CIN2_BIT); (dev->params.cap_input << AD7746_CAP_SETUP_CIN2_BIT);
if (i2c_write_reg(I2C, ADDR, AD7746_REG_CAP_SETUP, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_CAP_SETUP, reg, 0)) {
DEBUG("[ad7746] init - error: unable to enable capacitive channel\n"); DEBUG("[ad7746] init - error: unable to enable capacitive channel\n");
goto release; goto release;
} }
@ -150,7 +150,7 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
reg = (1 << AD7746_VT_SETUP_VTEN_BIT) | reg = (1 << AD7746_VT_SETUP_VTEN_BIT) |
(dev->params.vt_mode << AD7746_VT_SETUP_VTMD0_BIT) | (dev->params.vt_mode << AD7746_VT_SETUP_VTMD0_BIT) |
(1 << AD7746_VT_SETUP_VTCHOP_BIT); (1 << AD7746_VT_SETUP_VTCHOP_BIT);
if (i2c_write_reg(I2C, ADDR, AD7746_REG_VT_SETUP, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_VT_SETUP, reg, 0)) {
DEBUG("[ad7746] init - error: unable to enable the v/t channel\n"); DEBUG("[ad7746] init - error: unable to enable the v/t channel\n");
goto release; goto release;
} }
@ -158,7 +158,7 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
/* Set EXC sources */ /* Set EXC sources */
reg = (dev->params.exc_config << AD7746_EXC_SETUP_INV_EXCA_BIT); reg = (dev->params.exc_config << AD7746_EXC_SETUP_INV_EXCA_BIT);
if (i2c_write_reg(I2C, ADDR, AD7746_REG_EXC_SETUP, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_EXC_SETUP, reg, 0)) {
DEBUG("[ad7746] init - error: unable to set EXC outputs\n"); DEBUG("[ad7746] init - error: unable to set EXC outputs\n");
goto release; goto release;
} }
@ -167,7 +167,7 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
if (dev->params.dac_a_cap) { if (dev->params.dac_a_cap) {
assert(dev->params.dac_a_cap <= AD7746_DAC_MAX); assert(dev->params.dac_a_cap <= AD7746_DAC_MAX);
reg = (1 << AD7746_DACAEN_BIT) | dev->params.dac_a_cap; reg = (1 << AD7746_DACAEN_BIT) | dev->params.dac_a_cap;
if (i2c_write_reg(I2C, ADDR, AD7746_REG_CAP_DAC_A, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_CAP_DAC_A, reg, 0)) {
DEBUG("[ad7746] init - error: unable to set DAC A\n"); DEBUG("[ad7746] init - error: unable to set DAC A\n");
goto release; goto release;
} }
@ -177,7 +177,7 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
if (dev->params.dac_b_cap) { if (dev->params.dac_b_cap) {
assert(dev->params.dac_b_cap <= AD7746_DAC_MAX); assert(dev->params.dac_b_cap <= AD7746_DAC_MAX);
reg = (1 << AD7746_DACBEN_BIT) | dev->params.dac_b_cap; reg = (1 << AD7746_DACBEN_BIT) | dev->params.dac_b_cap;
if (i2c_write_reg(I2C, ADDR, AD7746_REG_CAP_DAC_B, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_CAP_DAC_B, reg, 0)) {
DEBUG("[ad7746] init - error: unable to set DAC B\n"); DEBUG("[ad7746] init - error: unable to set DAC B\n");
goto release; goto release;
} }
@ -187,7 +187,7 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
reg = (1 << AD7746_CONFIGURATION_MD0_BIT) | reg = (1 << AD7746_CONFIGURATION_MD0_BIT) |
(dev->params.cap_sample_rate << AD7746_CONFIGURATION_CAPF0_BIT) | (dev->params.cap_sample_rate << AD7746_CONFIGURATION_CAPF0_BIT) |
(dev->params.vt_sample_rate << AD7746_CONFIGURATION_VTF0_BIT); (dev->params.vt_sample_rate << AD7746_CONFIGURATION_VTF0_BIT);
if (i2c_write_reg(I2C, ADDR, AD7746_REG_CONFIGURATION, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_CONFIGURATION, reg, 0)) {
DEBUG("[ad7746] init - error: unable to set mode and SR\n"); DEBUG("[ad7746] init - error: unable to set mode and SR\n");
goto release; goto release;
} }
@ -195,7 +195,7 @@ int ad7746_init(ad7746_t *dev, const ad7746_params_t *params)
res = AD7746_OK; res = AD7746_OK;
release: release:
i2c_release(I2C); i2c_release(DEV);
return res; return res;
} }
@ -205,8 +205,8 @@ int ad7746_set_vt_ch_mode(ad7746_t *dev, ad7746_vt_mode_t mode)
int res = AD7746_NOI2C; int res = AD7746_NOI2C;
assert(dev); assert(dev);
i2c_acquire(I2C); i2c_acquire(DEV);
if (i2c_read_reg(I2C, ADDR, AD7746_REG_VT_SETUP, &reg, 0)) { if (i2c_read_reg(DEV, ADDR, AD7746_REG_VT_SETUP, &reg, 0)) {
goto release; goto release;
} }
@ -221,7 +221,7 @@ int ad7746_set_vt_ch_mode(ad7746_t *dev, ad7746_vt_mode_t mode)
(mode << AD7746_VT_SETUP_VTMD0_BIT); (mode << AD7746_VT_SETUP_VTMD0_BIT);
} }
if (i2c_write_reg(I2C, ADDR, AD7746_REG_VT_SETUP, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_VT_SETUP, reg, 0)) {
DEBUG("[ad7746] set_vt_ch - error: unable to set v/t channel mode\n"); DEBUG("[ad7746] set_vt_ch - error: unable to set v/t channel mode\n");
goto release; goto release;
} }
@ -230,7 +230,7 @@ int ad7746_set_vt_ch_mode(ad7746_t *dev, ad7746_vt_mode_t mode)
dev->params.vt_mode = mode; dev->params.vt_mode = mode;
release: release:
i2c_release(I2C); i2c_release(DEV);
return res; return res;
} }
@ -270,9 +270,9 @@ int ad7746_set_cap_ch_input(const ad7746_t *dev, ad7746_cap_input_t input)
int res = AD7746_NOI2C; int res = AD7746_NOI2C;
assert(dev); assert(dev);
i2c_acquire(I2C); i2c_acquire(DEV);
if (i2c_read_reg(I2C, ADDR, AD7746_REG_CAP_SETUP, &reg, 0)) { if (i2c_read_reg(DEV, ADDR, AD7746_REG_CAP_SETUP, &reg, 0)) {
goto release; goto release;
} }
@ -283,14 +283,14 @@ int ad7746_set_cap_ch_input(const ad7746_t *dev, ad7746_cap_input_t input)
reg &= ~(1 << AD7746_CAP_SETUP_CIN2_BIT); reg &= ~(1 << AD7746_CAP_SETUP_CIN2_BIT);
} }
if (i2c_write_reg(I2C, ADDR, AD7746_REG_CAP_SETUP, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_CAP_SETUP, reg, 0)) {
goto release; goto release;
} }
res = AD7746_OK; res = AD7746_OK;
release: release:
i2c_release(I2C); i2c_release(DEV);
return res; return res;
} }
@ -300,23 +300,23 @@ int ad7746_set_cap_sr(const ad7746_t *dev, ad7746_cap_sample_rate_t sr)
int res = AD7746_NOI2C; int res = AD7746_NOI2C;
assert(dev); assert(dev);
i2c_acquire(I2C); i2c_acquire(DEV);
if (i2c_read_reg(I2C, ADDR, AD7746_REG_CONFIGURATION, &reg, 0)) { if (i2c_read_reg(DEV, ADDR, AD7746_REG_CONFIGURATION, &reg, 0)) {
goto release; goto release;
} }
reg &= ~(7 << AD7746_CONFIGURATION_CAPF0_BIT); reg &= ~(7 << AD7746_CONFIGURATION_CAPF0_BIT);
reg |= (sr << AD7746_CONFIGURATION_CAPF0_BIT); reg |= (sr << AD7746_CONFIGURATION_CAPF0_BIT);
if (i2c_write_reg(I2C, ADDR, AD7746_REG_CONFIGURATION, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_CONFIGURATION, reg, 0)) {
goto release; goto release;
} }
res = AD7746_OK; res = AD7746_OK;
release: release:
i2c_release(I2C); i2c_release(DEV);
return res; return res;
} }
@ -326,23 +326,23 @@ int ad7746_set_vt_sr(const ad7746_t *dev, ad7746_vt_sample_rate_t sr)
int res = AD7746_NOI2C; int res = AD7746_NOI2C;
assert(dev); assert(dev);
i2c_acquire(I2C); i2c_acquire(DEV);
if (i2c_read_reg(I2C, ADDR, AD7746_REG_CONFIGURATION, &reg, 0)) { if (i2c_read_reg(DEV, ADDR, AD7746_REG_CONFIGURATION, &reg, 0)) {
goto release; goto release;
} }
reg &= ~(3 << AD7746_CONFIGURATION_VTF0_BIT); reg &= ~(3 << AD7746_CONFIGURATION_VTF0_BIT);
reg |= (sr << AD7746_CONFIGURATION_VTF0_BIT); reg |= (sr << AD7746_CONFIGURATION_VTF0_BIT);
if (i2c_write_reg(I2C, ADDR, AD7746_REG_CONFIGURATION, reg, 0)) { if (i2c_write_reg(DEV, ADDR, AD7746_REG_CONFIGURATION, reg, 0)) {
goto release; goto release;
} }
res = AD7746_OK; res = AD7746_OK;
release: release:
i2c_release(I2C); i2c_release(DEV);
return res; return res;
} }
@ -406,9 +406,9 @@ static int _read_raw_ch(const ad7746_t *dev, uint8_t ch, uint32_t *raw)
assert(dev); assert(dev);
assert((ch == AD7746_READ_CAP_CH) || (ch == AD7746_READ_VT_CH)); assert((ch == AD7746_READ_CAP_CH) || (ch == AD7746_READ_VT_CH));
i2c_acquire(I2C); i2c_acquire(DEV);
if (i2c_read_reg(I2C, ADDR, AD7746_REG_STATUS, buf, 0)) { if (i2c_read_reg(DEV, ADDR, AD7746_REG_STATUS, buf, 0)) {
goto release; goto release;
} }
@ -418,7 +418,7 @@ static int _read_raw_ch(const ad7746_t *dev, uint8_t ch, uint32_t *raw)
goto release; goto release;
} }
if (i2c_read_regs(I2C, ADDR, reg, buf, 3, 0)) { if (i2c_read_regs(DEV, ADDR, reg, buf, 3, 0)) {
goto release; goto release;
} }
@ -427,7 +427,7 @@ static int _read_raw_ch(const ad7746_t *dev, uint8_t ch, uint32_t *raw)
res = AD7746_OK; res = AD7746_OK;
release: release:
i2c_release(I2C); i2c_release(DEV);
return res; return res;
} }

View File

@ -27,7 +27,7 @@
#define ENABLE_DEBUG (0) #define ENABLE_DEBUG (0)
#include "debug.h" #include "debug.h"
#define I2C (dev->params.i2c) #define DEV (dev->params.i2c)
#define ADDR (dev->params.addr) #define ADDR (dev->params.addr)
/* Configuration register test value /* Configuration register test value
@ -42,23 +42,23 @@ int adcxx1c_init(adcxx1c_t *dev, const adcxx1c_params_t *params)
dev->params = *params; dev->params = *params;
dev->cb = NULL; dev->cb = NULL;
i2c_acquire(I2C); i2c_acquire(DEV);
uint8_t reg = 0; uint8_t reg = 0;
/* Test communication write and read configuration register */ /* Test communication write and read configuration register */
status = i2c_write_reg(I2C, ADDR, ADCXX1C_CONF_ADDR, CONF_TEST_VALUE, 0); status = i2c_write_reg(DEV, ADDR, ADCXX1C_CONF_ADDR, CONF_TEST_VALUE, 0);
status += i2c_read_reg(I2C, ADDR, ADCXX1C_CONF_ADDR, &reg, 0); status += i2c_read_reg(DEV, ADDR, ADCXX1C_CONF_ADDR, &reg, 0);
if (status < 0 || reg != CONF_TEST_VALUE) { if (status < 0 || reg != CONF_TEST_VALUE) {
i2c_release(I2C); i2c_release(DEV);
DEBUG("[adcxx1c] init - error: unable to communicate with the device " DEBUG("[adcxx1c] init - error: unable to communicate with the device "
"(reg=%x)\n", reg); "(reg=%x)\n", reg);
return ADCXX1C_NODEV; return ADCXX1C_NODEV;
} }
reg = dev->params.cycle << 5; reg = dev->params.cycle << 5;
status = i2c_write_reg(I2C, ADDR, ADCXX1C_CONF_ADDR, reg, 0); status = i2c_write_reg(DEV, ADDR, ADCXX1C_CONF_ADDR, reg, 0);
i2c_release(I2C); i2c_release(DEV);
if (status < 0) { if (status < 0) {
DEBUG("[adcxx1c] init - error: unable to communicate with the device " DEBUG("[adcxx1c] init - error: unable to communicate with the device "
"(err=%x)\n", status); "(err=%x)\n", status);
@ -75,9 +75,9 @@ int adcxx1c_read_raw(const adcxx1c_t *dev, int16_t *raw)
uint8_t buf[2]; uint8_t buf[2];
int status; int status;
i2c_acquire(I2C); i2c_acquire(DEV);
status = i2c_read_regs(I2C, ADDR, ADCXX1C_CONV_RES_ADDR, buf, 2, 0); status = i2c_read_regs(DEV, ADDR, ADCXX1C_CONV_RES_ADDR, buf, 2, 0);
i2c_release(I2C); i2c_release(DEV);
if (status < 0) { if (status < 0) {
return ADCXX1C_NOI2C; return ADCXX1C_NOI2C;
} }
@ -101,12 +101,12 @@ int adcxx1c_enable_alert(adcxx1c_t *dev, adcxx1c_cb_t cb, void *arg)
uint8_t reg; uint8_t reg;
int status; int status;
i2c_acquire(I2C); i2c_acquire(DEV);
i2c_read_reg(I2C, ADDR, ADCXX1C_CONF_ADDR, &reg, 0); i2c_read_reg(DEV, ADDR, ADCXX1C_CONF_ADDR, &reg, 0);
reg |= (dev->params.alert_pin != GPIO_UNDEF ? ADCXX1C_CONF_ALERT_PIN_EN : 0) reg |= (dev->params.alert_pin != GPIO_UNDEF ? ADCXX1C_CONF_ALERT_PIN_EN : 0)
| ADCXX1C_CONF_ALERT_FLAG_EN; | ADCXX1C_CONF_ALERT_FLAG_EN;
status = i2c_write_reg(I2C, ADDR, ADCXX1C_CONF_ADDR, reg, 0); status = i2c_write_reg(DEV, ADDR, ADCXX1C_CONF_ADDR, reg, 0);
i2c_release(I2C); i2c_release(DEV);
if (status < 0) { if (status < 0) {
DEBUG("[adcxx1c] enable_alert - error: unable to communicate with the " DEBUG("[adcxx1c] enable_alert - error: unable to communicate with the "
"device (err=%d)\n", status); "device (err=%d)\n", status);
@ -129,14 +129,14 @@ int adcxx1c_set_alert_parameters(const adcxx1c_t *dev, int16_t low_limit,
uint8_t buf[2]; uint8_t buf[2];
int status; int status;
i2c_acquire(I2C); i2c_acquire(DEV);
low_limit <<= (12 - dev->params.bits); low_limit <<= (12 - dev->params.bits);
buf[0] = low_limit >> 8; buf[0] = low_limit >> 8;
buf[1] = low_limit & 0xFF; buf[1] = low_limit & 0xFF;
status = i2c_write_regs(I2C, ADDR, ADCXX1C_LOW_LIMIT_ADDR, buf, 2, 0); status = i2c_write_regs(DEV, ADDR, ADCXX1C_LOW_LIMIT_ADDR, buf, 2, 0);
if (status < 0) { if (status < 0) {
i2c_release(I2C); i2c_release(DEV);
DEBUG("[adcxx1c] set_alert (low limit) - error: unable to communicate " DEBUG("[adcxx1c] set_alert (low limit) - error: unable to communicate "
"with the device (err=%d)\n", status); "with the device (err=%d)\n", status);
return ADCXX1C_NOI2C; return ADCXX1C_NOI2C;
@ -145,9 +145,9 @@ int adcxx1c_set_alert_parameters(const adcxx1c_t *dev, int16_t low_limit,
high_limit <<= (12 - dev->params.bits); high_limit <<= (12 - dev->params.bits);
buf[0] = high_limit >> 8; buf[0] = high_limit >> 8;
buf[1] = high_limit & 0xFF; buf[1] = high_limit & 0xFF;
status = i2c_write_regs(I2C, ADDR, ADCXX1C_HIGH_LIMIT_ADDR, buf, 2, 0); status = i2c_write_regs(DEV, ADDR, ADCXX1C_HIGH_LIMIT_ADDR, buf, 2, 0);
if (status < 0) { if (status < 0) {
i2c_release(I2C); i2c_release(DEV);
DEBUG("[adcxx1c] set_alert (high limit) - error: unable to communicate " DEBUG("[adcxx1c] set_alert (high limit) - error: unable to communicate "
"with the device (err=%d)\n", status); "with the device (err=%d)\n", status);
return ADCXX1C_NOI2C; return ADCXX1C_NOI2C;
@ -156,15 +156,15 @@ int adcxx1c_set_alert_parameters(const adcxx1c_t *dev, int16_t low_limit,
hysteresis <<= (12 - dev->params.bits); hysteresis <<= (12 - dev->params.bits);
buf[0] = hysteresis >> 8; buf[0] = hysteresis >> 8;
buf[1] = hysteresis & 0xFF; buf[1] = hysteresis & 0xFF;
status = i2c_write_regs(I2C, ADDR, ADCXX1C_HYSTERESIS_ADDR, buf, 2, 0); status = i2c_write_regs(DEV, ADDR, ADCXX1C_HYSTERESIS_ADDR, buf, 2, 0);
if (status < 0) { if (status < 0) {
i2c_release(I2C); i2c_release(DEV);
DEBUG("[adcxx1c] set_alert (hysteresis) - error: unable to communicate " DEBUG("[adcxx1c] set_alert (hysteresis) - error: unable to communicate "
"with the device (err=%d)\n", status); "with the device (err=%d)\n", status);
return ADCXX1C_NOI2C; return ADCXX1C_NOI2C;
} }
i2c_release(I2C); i2c_release(DEV);
return ADCXX1C_OK; return ADCXX1C_OK;
} }

View File

@ -35,7 +35,7 @@
#define ADS101X_READ_DELAY (8 * US_PER_MS) /* Compatible with 128SPS */ #define ADS101X_READ_DELAY (8 * US_PER_MS) /* Compatible with 128SPS */
#endif #endif
#define I2C (dev->params.i2c) #define DEV (dev->params.i2c)
#define ADDR (dev->params.addr) #define ADDR (dev->params.addr)
static int _ads101x_init_test(i2c_t i2c, uint8_t addr); static int _ads101x_init_test(i2c_t i2c, uint8_t addr);
@ -46,7 +46,7 @@ int ads101x_init(ads101x_t *dev, const ads101x_params_t *params)
dev->params = *params; dev->params = *params;
return _ads101x_init_test(I2C, ADDR); return _ads101x_init_test(DEV, ADDR);
} }
int ads101x_alert_init(ads101x_alert_t *dev, int ads101x_alert_init(ads101x_alert_t *dev,
@ -62,7 +62,7 @@ int ads101x_alert_init(ads101x_alert_t *dev,
ads101x_set_alert_parameters(dev, dev->params.low_limit, ads101x_set_alert_parameters(dev, dev->params.low_limit,
dev->params.high_limit); dev->params.high_limit);
return _ads101x_init_test(I2C, ADDR); return _ads101x_init_test(DEV, ADDR);
} }
static int _ads101x_init_test(i2c_t i2c, uint8_t addr) static int _ads101x_init_test(i2c_t i2c, uint8_t addr)
@ -106,9 +106,9 @@ int ads101x_set_mux_gain(const ads101x_t *dev, uint8_t mux_gain)
{ {
uint8_t regs[2]; uint8_t regs[2];
i2c_acquire(I2C); i2c_acquire(DEV);
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_read_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
/* Zero mux and gain */ /* Zero mux and gain */
regs[0] &= ~ADS101X_MUX_MASK; regs[0] &= ~ADS101X_MUX_MASK;
@ -117,9 +117,9 @@ int ads101x_set_mux_gain(const ads101x_t *dev, uint8_t mux_gain)
/* Write mux and gain */ /* Write mux and gain */
regs[0] |= mux_gain; regs[0] |= mux_gain;
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_write_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
i2c_release(I2C); i2c_release(DEV);
return ADS101X_OK; return ADS101X_OK;
} }
@ -128,25 +128,25 @@ int ads101x_read_raw(const ads101x_t *dev, int16_t *raw)
{ {
uint8_t regs[2]; uint8_t regs[2];
i2c_acquire(I2C); i2c_acquire(DEV);
/* Read control register */ /* Read control register */
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_read_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
/* Tell the ADC to aquire a single-shot sample */ /* Tell the ADC to aquire a single-shot sample */
regs[0] |= ADS101X_CONF_OS_CONV; regs[0] |= ADS101X_CONF_OS_CONV;
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_write_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
/* Wait for the sample to be aquired */ /* Wait for the sample to be aquired */
xtimer_usleep(ADS101X_READ_DELAY); xtimer_usleep(ADS101X_READ_DELAY);
/* Read the sample */ /* Read the sample */
if (i2c_read_regs(I2C, ADDR, ADS101X_CONV_RES_ADDR, &regs, 2, 0x0) < 0) { if (i2c_read_regs(DEV, ADDR, ADS101X_CONV_RES_ADDR, &regs, 2, 0x0) < 0) {
i2c_release(I2C); i2c_release(DEV);
return ADS101X_NODATA; return ADS101X_NODATA;
} }
i2c_release(I2C); i2c_release(DEV);
/* If all okay, change raw value */ /* If all okay, change raw value */
*raw = (int16_t)(regs[0] << 8) | (int16_t)(regs[1]); *raw = (int16_t)(regs[0] << 8) | (int16_t)(regs[1]);
@ -164,14 +164,14 @@ int ads101x_enable_alert(ads101x_alert_t *dev,
} }
/* Read control register */ /* Read control register */
i2c_acquire(I2C); i2c_acquire(DEV);
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_read_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
/* Enable alert comparator */ /* Enable alert comparator */
regs[1] &= ~ADS101X_CONF_COMP_DIS; regs[1] &= ~ADS101X_CONF_COMP_DIS;
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_write_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
i2c_release(I2C); i2c_release(DEV);
/* Enable interrupt */ /* Enable interrupt */
dev->arg = arg; dev->arg = arg;
@ -186,20 +186,20 @@ int ads101x_set_alert_parameters(const ads101x_alert_t *dev,
{ {
uint8_t regs[2]; uint8_t regs[2];
i2c_acquire(I2C); i2c_acquire(DEV);
/* Set up low_limit */ /* Set up low_limit */
regs[0] = (uint8_t)(low_limit >> 8); regs[0] = (uint8_t)(low_limit >> 8);
regs[1] = (uint8_t)low_limit; regs[1] = (uint8_t)low_limit;
i2c_write_regs(I2C, ADDR, ADS101X_LOW_LIMIT_ADDR, &regs, 2, 0x0); i2c_write_regs(DEV, ADDR, ADS101X_LOW_LIMIT_ADDR, &regs, 2, 0x0);
/* Set up high_limit */ /* Set up high_limit */
regs[0] = (uint8_t)(high_limit >> 8); regs[0] = (uint8_t)(high_limit >> 8);
regs[1] = (uint8_t)high_limit; regs[1] = (uint8_t)high_limit;
i2c_write_regs(I2C, ADDR, ADS101X_HIGH_LIMIT_ADDR, &regs, 2, 0x0); i2c_write_regs(DEV, ADDR, ADS101X_HIGH_LIMIT_ADDR, &regs, 2, 0x0);
/* Read control register */ /* Read control register */
i2c_read_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_read_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
/* Set up window mode */ /* Set up window mode */
if (low_limit != 0) { if (low_limit != 0) {
@ -210,9 +210,9 @@ int ads101x_set_alert_parameters(const ads101x_alert_t *dev,
/* Disable window mode */ /* Disable window mode */
regs[1] &= ~ADS101X_CONF_COMP_MODE_WIND; regs[1] &= ~ADS101X_CONF_COMP_MODE_WIND;
} }
i2c_write_regs(I2C, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0); i2c_write_regs(DEV, ADDR, ADS101X_CONF_ADDR, &regs, 2, 0x0);
i2c_release(I2C); i2c_release(DEV);
return ADS101X_OK; return ADS101X_OK;
} }