hdc1008 sensor

This commit is contained in:
Stephane D'Alu 2016-02-07 16:48:22 +01:00
parent 5af8452153
commit ee5bea89c2
5 changed files with 1031 additions and 0 deletions

138
os/various/bswap.h Normal file
View File

@ -0,0 +1,138 @@
#ifndef BSWAP_H
#define BSWAP_H
#if defined(__cplusplus)
extern "C" {
#endif
#if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN))
#if YOTTA_CFG_CONFIG_ARCH_LITTLE_ENDIAN
#define ARCH_LITTLE_ENDIAN
#endif
#if YOTTA_CFG_CONFIG_ARCH_BIG_ENDIAN
#define ARCH_BIG_ENDIAN
#endif
#endif
#if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN))
#error "ARCH_BIG_ENDIAN or ARCH_LITTLE_ENDIAN not set."
#endif
#if defined(ARCH_BIG_ENDIAN) && defined(ARCH_LITTLE_ENDIAN)
#error "ARCH_BIG_ENDIAN and ARCH_LITTLE_ENDIAN are both set."
#endif
#define BSWAP_16(x) \
(uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
#define BSWAP_32(x) \
(uint32_t)((((x) & 0xFF000000UL) >> 24UL) | \
(((x) & 0x00FF0000UL) >> 8UL) | \
(((x) & 0x0000FF00UL) << 8UL) | \
(((x) & 0x000000FFUL) << 24UL))
#if defined(ARCH_BIG_ENDIAN)
#define le16_to_cpu(x) bswap_16(x)
#define le32_to_cpu(x) bswap_32(x)
#define be16_to_cpu(x) (x)
#define be32_to_cpu(x) (x)
#define cpu_to_le16(x) bswap_16(x)
#define cpu_to_le32(x) bswap_32(x)
#define cpu_to_be16(x) (x)
#define cpu_to_be32(x) (x)
#define LE16_TO_CPU(x) BSWAP_16(x)
#define LE32_TO_CPU(x) BSWAP_32(x)
#define BE16_TO_CPU(x) (x)
#define BE32_TO_CPU(x) (x)
#define CPU_TO_LE16(x) BSWAP_16(x)
#define CPU_TO_LE32(x) BSWAP_32(x)
#define CPU_TO_BE16(x) (x)
#define CPU_TO_BE32(x) (x)
#endif
#if defined(ARCH_LITTLE_ENDIAN)
#define le16_to_cpu(x) (x)
#define le32_to_cpu(x) (x)
#define be16_to_cpu(x) bswap_16(x)
#define be32_to_cpu(x) bswap_32(x)
#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
#define cpu_to_be16(x) bswap_16(x)
#define cpu_to_be32(x) bswap_32(x)
#define LE16_TO_CPU(x) (x)
#define LE32_TO_CPU(x) (x)
#define BE16_TO_CPU(x) BSWAP_16(x)
#define BE32_TO_CPU(x) BSWAP_32(x)
#define CPU_TO_LE16(x) (x)
#define CPU_TO_LE32(x) (x)
#define CPU_TO_BE16(x) BSWAP_16(x)
#define CPU_TO_BE32(x) BSWAP_32(x)
#endif
static inline uint16_t bswap_16(const uint16_t x)
__attribute__ ((warn_unused_result))
__attribute__ ((const))
__attribute__ ((always_inline));
static inline uint16_t bswap_16(const uint16_t x) {
if (__builtin_constant_p(x))
return BSWAP_16(x);
uint8_t tmp;
union { uint16_t x; uint8_t b[2]; } data;
data.x = x;
tmp = data.b[0];
data.b[0] = data.b[1];
data.b[1] = tmp;
return data.x;
}
static inline uint32_t bswap_32(const uint32_t x)
__attribute__ ((warn_unused_result))
__attribute__ ((const))
__attribute__ ((always_inline));
static inline uint32_t bswap_32(const uint32_t x) {
if (__builtin_constant_p(x))
return BSWAP_32(x);
uint8_t tmp;
union { uint32_t x; uint8_t b[4]; } data;
data.x = x;
tmp = data.b[0];
data.b[0] = data.b[3];
data.b[3] = tmp;
tmp = data.b[1];
data.b[1] = data.b[2];
data.b[2] = tmp;
return data.x;
}
static inline void bswap_n(void* const data, uint8_t len)
__attribute__ ((nonnull (1)));
static inline void bswap_n(void* const data, uint8_t len) {
uint8_t* ptr = (uint8_t*)data;
for ( ; len > 1 ; ptr++, len -= 2 ) {
uint8_t tmp = *ptr;
*ptr = *(ptr + len - 1);
*(ptr + len - 1) = tmp;
}
}
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,138 @@
#ifndef BSWAP_H
#define BSWAP_H
#if defined(__cplusplus)
extern "C" {
#endif
#if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN))
#if YOTTA_CFG_CONFIG_ARCH_LITTLE_ENDIAN
#define ARCH_LITTLE_ENDIAN
#endif
#if YOTTA_CFG_CONFIG_ARCH_BIG_ENDIAN
#define ARCH_BIG_ENDIAN
#endif
#endif
#if !(defined(ARCH_BIG_ENDIAN) || defined(ARCH_LITTLE_ENDIAN))
#error "ARCH_BIG_ENDIAN or ARCH_LITTLE_ENDIAN not set."
#endif
#if defined(ARCH_BIG_ENDIAN) && defined(ARCH_LITTLE_ENDIAN)
#error "ARCH_BIG_ENDIAN and ARCH_LITTLE_ENDIAN are both set."
#endif
#define BSWAP_16(x) \
(uint16_t)((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
#define BSWAP_32(x) \
(uint32_t)((((x) & 0xFF000000UL) >> 24UL) | \
(((x) & 0x00FF0000UL) >> 8UL) | \
(((x) & 0x0000FF00UL) << 8UL) | \
(((x) & 0x000000FFUL) << 24UL))
#if defined(ARCH_BIG_ENDIAN)
#define le16_to_cpu(x) bswap_16(x)
#define le32_to_cpu(x) bswap_32(x)
#define be16_to_cpu(x) (x)
#define be32_to_cpu(x) (x)
#define cpu_to_le16(x) bswap_16(x)
#define cpu_to_le32(x) bswap_32(x)
#define cpu_to_be16(x) (x)
#define cpu_to_be32(x) (x)
#define LE16_TO_CPU(x) BSWAP_16(x)
#define LE32_TO_CPU(x) BSWAP_32(x)
#define BE16_TO_CPU(x) (x)
#define BE32_TO_CPU(x) (x)
#define CPU_TO_LE16(x) BSWAP_16(x)
#define CPU_TO_LE32(x) BSWAP_32(x)
#define CPU_TO_BE16(x) (x)
#define CPU_TO_BE32(x) (x)
#endif
#if defined(ARCH_LITTLE_ENDIAN)
#define le16_to_cpu(x) (x)
#define le32_to_cpu(x) (x)
#define be16_to_cpu(x) bswap_16(x)
#define be32_to_cpu(x) bswap_32(x)
#define cpu_to_le16(x) (x)
#define cpu_to_le32(x) (x)
#define cpu_to_be16(x) bswap_16(x)
#define cpu_to_be32(x) bswap_32(x)
#define LE16_TO_CPU(x) (x)
#define LE32_TO_CPU(x) (x)
#define BE16_TO_CPU(x) BSWAP_16(x)
#define BE32_TO_CPU(x) BSWAP_32(x)
#define CPU_TO_LE16(x) (x)
#define CPU_TO_LE32(x) (x)
#define CPU_TO_BE16(x) BSWAP_16(x)
#define CPU_TO_BE32(x) BSWAP_32(x)
#endif
static inline uint16_t bswap_16(const uint16_t x)
__attribute__ ((warn_unused_result))
__attribute__ ((const))
__attribute__ ((always_inline));
static inline uint16_t bswap_16(const uint16_t x) {
if (__builtin_constant_p(x))
return BSWAP_16(x);
uint8_t tmp;
union { uint16_t x; uint8_t b[2]; } data;
data.x = x;
tmp = data.b[0];
data.b[0] = data.b[1];
data.b[1] = tmp;
return data.x;
}
static inline uint32_t bswap_32(const uint32_t x)
__attribute__ ((warn_unused_result))
__attribute__ ((const))
__attribute__ ((always_inline));
static inline uint32_t bswap_32(const uint32_t x) {
if (__builtin_constant_p(x))
return BSWAP_32(x);
uint8_t tmp;
union { uint32_t x; uint8_t b[4]; } data;
data.x = x;
tmp = data.b[0];
data.b[0] = data.b[3];
data.b[3] = tmp;
tmp = data.b[1];
data.b[1] = data.b[2];
data.b[2] = tmp;
return data.x;
}
static inline void bswap_n(void* const data, uint8_t len)
__attribute__ ((nonnull (1)));
static inline void bswap_n(void* const data, uint8_t len) {
uint8_t* ptr = (uint8_t*)data;
for ( ; len > 1 ; ptr++, len -= 2 ) {
uint8_t tmp = *ptr;
*ptr = *(ptr + len - 1);
*(ptr + len - 1) = tmp;
}
}
#if defined(__cplusplus)
}
#endif
#endif

View File

@ -0,0 +1,255 @@
/*
HDC1008 for ChibiOS/RT - Copyright (C) 2016 Stephane D'Alu
*/
/**
* @file HDC1000.c
* @brief HDC1000 interface module code.
*
* @addtogroup hdc1000
* @{
*/
#define I2C_HELPERS_AUTOMATIC_DRV TRUE
#include "hal.h"
#include "i2c_helpers.h"
#include "hdc1000.h"
/* DOC: http://www.ti.com/lit/ds/symlink/hdc1008.pdf
*/
/*===========================================================================*/
/* Driver local definitions. */
/*===========================================================================*/
/* I2C Register */
#define HDC1000_REG_TEMP_HUMID 0x00
#define HDC1000_REG_TEMP 0x00
#define HDC1000_REG_HUMID 0x01
#define HDC1000_REG_CONFIG 0x02
#define HDC1000_REG_SERIAL 0xFB
#define HDC1000_REG_SERIAL_1 0xFB
#define HDC1000_REG_SERIAL_2 0xFC
#define HDC1000_REG_SERIAL_3 0xFD
#define HDC1000_REG_MANUF_ID 0xFE
#define HDC1000_REG_DEVICE_ID 0xFF
/* Configuration */
#define HDC1000_CONFIG_RST (1 << 15)
#define HDC1000_CONFIG_HEATER (1 << 13)
#define HDC1000_CONFIG_MODE_ONE (0 << 12)
#define HDC1000_CONFIG_MODE_BOTH (1 << 12)
#define HDC1000_CONFIG_BATT (1 << 11)
#define HDC1000_CONFIG_TRES_14 (0)
#define HDC1000_CONFIG_TRES_11 (1 << 10)
#define HDC1000_CONFIG_HRES_14 (0)
#define HDC1000_CONFIG_HRES_11 (1 << 8)
#define HDC1000_CONFIG_HRES_8 (1 << 9)
/* Value */
#define HDC1000_MANUF_ID 0x5449
#define HDC1000_DEVICE_ID 0x1000
/* Delay in micro seconds */
#define HDC1000_DELAY_ACQUIRE_SAFETY 1000
#define HDC1000_DELAY_ACQUIRE_TRES_14 6350
#define HDC1000_DELAY_ACQUIRE_TRES_11 3650
#define HDC1000_DELAY_ACQUIRE_HRES_14 6500
#define HDC1000_DELAY_ACQUIRE_HRES_11 3850
#define HDC1000_DELAY_ACQUIRE_HRES_8 2500
#define HDC1000_DELAY_STARTUP 15000
// Deefault config (high res)
#define HDC1000_CONFIG_RES (HDC1000_CONFIG_TRES_14 | \
HDC1000_CONFIG_HRES_14)
#define HDC1000_DELAY_ACQUIRE (HDC1000_DELAY_ACQUIRE_TRES_14 + \
HDC1000_DELAY_ACQUIRE_HRES_14)
/*===========================================================================*/
/* Driver exported variables. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local variables and types. */
/*===========================================================================*/
/*===========================================================================*/
/* Driver local functions. */
/*===========================================================================*/
inline msg_t
_apply_config(HDC1000_drv *drv) {
struct __attribute__((packed)) {
uint8_t reg;
uint16_t conf;
} tx = { HDC1000_REG_CONFIG, cpu_to_be16(drv->cfg) };
return i2c_send((uint8_t*)&tx, sizeof(tx));
}
inline msg_t
_decode_measure(HDC1000_drv *drv,
uint32_t val, float *temperature, float *humidity) {
(void)drv;
/* Temperature */
if (temperature) {
float temp = (val >> 16);
temp /= 65536;
temp *= 165;
temp -= 40;
*temperature = temp;
}
/* Humidiy */
if (humidity) {
float hum = (val & 0xFFFF);
hum /= 65535;
hum *= 100;
*humidity = hum;
}
return MSG_OK;
}
/*===========================================================================*/
/* Driver exported functions. */
/*===========================================================================*/
void
HDC1000_init(HDC1000_drv *drv, HDC1000_config *config) {
drv->config = config;
drv->cfg = HDC1000_CONFIG_RST | HDC1000_CONFIG_MODE_BOTH |
HDC1000_CONFIG_RES;
drv->delay = (HDC1000_DELAY_ACQUIRE +
HDC1000_DELAY_ACQUIRE_SAFETY) / 1000;
drv->state = HDC1000_INIT;
}
msg_t
HDC1000_check(HDC1000_drv *drv) {
msg_t msg = -10;
uint16_t val;
if ((msg = i2c_reg_recv16_be(HDC1000_REG_MANUF_ID, &val)) < MSG_OK)
return msg;
if (val != HDC1000_MANUF_ID)
return -2;
if ((msg = i2c_reg_recv16_be(HDC1000_REG_DEVICE_ID, &val)) < MSG_OK)
return msg;
if (val != HDC1000_DEVICE_ID)
return -2;
return MSG_OK;
}
msg_t
HDC1000_start(HDC1000_drv *drv) {
osalDbgAssert((drv->state == HDC1000_INIT ) ||
(drv->state == HDC1000_ERROR ) ||
(drv->state == HDC1000_STOPPED),
"invalid state");
msg_t msg;
if ((msg = _apply_config(drv)) < MSG_OK) {
drv->state = HDC1000_ERROR;
return msg;
}
drv->state = HDC1000_STARTED;
return MSG_OK;
}
msg_t
HDC1000_stop(HDC1000_drv *drv) {
drv->state = HDC1000_STOPPED;
return MSG_OK;
}
msg_t
HDC1000_setHeater(HDC1000_drv *drv, bool on) {
if (on) { drv->cfg |= HDC1000_CONFIG_HEATER; }
else { drv->cfg &= ~HDC1000_CONFIG_HEATER; }
msg_t msg;
if ((msg = _apply_config(drv)) < MSG_OK) {
drv->state = HDC1000_ERROR;
return msg;
}
return MSG_OK;
}
msg_t
HDC1000_startMeasure(HDC1000_drv *drv) {
msg_t msg;
osalDbgAssert(drv->state == HDC1000_STARTED, "invalid state");
if ((msg = i2c_reg(HDC1000_REG_TEMP_HUMID)) < MSG_OK)
return msg;
drv->state = HDC1000_MEASURING;
return MSG_OK;
}
msg_t
HDC1000_readSerial(HDC1000_drv *drv, uint8_t *serial) {
msg_t msg;
osalDbgAssert(drv->state == HDC1000_STARTED, "invalid state");
if (((msg = i2c_reg_recv16(HDC1000_REG_SERIAL_1,
(uint16_t*)&serial[0])) < MSG_OK) ||
((msg = i2c_reg_recv16(HDC1000_REG_SERIAL_2,
(uint16_t*)&serial[2])) < MSG_OK) ||
((msg = i2c_reg_recv8 (HDC1000_REG_SERIAL_3,
(uint8_t*) &serial[4])) < MSG_OK))
return msg;
return MSG_OK;
}
msg_t
HDC1000_readMeasure(HDC1000_drv *drv,
float *temperature, float *humidity) {
msg_t msg;
uint32_t val;
osalDbgAssert((drv->state == HDC1000_MEASURING) ||
(drv->state == HDC1000_READY ),
"invalid state");
if ((msg = i2c_recv32_be(&val)) < MSG_OK) {
drv->state = HDC1000_ERROR;
return msg;
}
drv->state = HDC1000_STARTED;
return _decode_measure(drv, val, temperature, humidity);
}
msg_t
HDC1000_readTemperatureHumidity(HDC1000_drv *drv,
float *temperature, float *humidity) {
msg_t msg;
uint32_t val;
osalDbgAssert(drv->state == HDC1000_STARTED, "invalid state");
/* Request value */
if ((msg = i2c_reg(HDC1000_REG_TEMP_HUMID)) < MSG_OK)
return msg;
/* Wait */
osalThreadSleepMilliseconds(drv->delay);
/* Get value */
if ((msg = i2c_recv32_be(&val)) < MSG_OK) {
drv->state = HDC1000_ERROR;
return msg;
}
return _decode_measure(drv, val, temperature, humidity);
}
/** @} */

View File

@ -0,0 +1,233 @@
/*
HDC1000 for ChibiOS/RT - Copyright (C) 2016 Stephane D'Alu
*/
/**
* @file hdc1000.h
* @brief HDC1000 Temperature/Humidiry sensor interface module header.
*
* @{
*/
#ifndef _SENSOR_HDC1000_H_
#define _SENSOR_HDC1000_H_
#include <math.h>
#include <stdbool.h>
#include "i2c_helpers.h"
// I2C address
#define HDC1000_I2CADDR_1 0x40
#define HDC1000_I2CADDR_2 0x41
#define HDC1000_I2CADDR_3 0x42
#define HDC1000_I2CADDR_4 0x43
#ifndef HDC1000_I2CADDR
#define HDC1000_I2CADDR HDC1000_I2CADDR_1
#endif
// Size of serial (40 bits)
#define HDC1000_SERIAL_SIZE 5
#define HDC1000_CONTINUOUS_ACQUISITION_SUPPORTED FALSE
/**
* When changing sensor settings, you generally need to wait
* for 2 * getAquisitionTime(), as usually the first acquisition
* will be corrupted by the change of settings.
*
* No locking is done.
*/
/**
* @brief HDC1000 configuration structure.
*/
typedef struct {
I2CHelper i2c; /* keep it first */
} HDC1000_config;
/**
* @brief Driver state machine possible states.
*/
typedef enum __attribute__ ((__packed__)) {
HDC1000_UNINIT = 0, /**< Not initialized. */
HDC1000_INIT = 1, /**< Initialized. */
HDC1000_STARTED = 2, /**< Started. */
HDC1000_MEASURING = 4, /**< Measuring. */
HDC1000_READY = 3, /**< Ready. */
HDC1000_STOPPED = 5, /**< Stopped. */
HDC1000_ERROR = 6, /**< Error. */
} HDC1000_state_t;
/**
* @brief HDC1000 configuration structure.
*/
typedef struct {
HDC1000_config *config;
HDC1000_state_t state;
unsigned int delay;
uint16_t cfg;
} HDC1000_drv;
/**
* @brief Initialize the sensor driver
*/
void
HDC1000_init(HDC1000_drv *drv,
HDC1000_config *config);
/**
* @brief Start the sensor
*/
msg_t
HDC1000_start(HDC1000_drv *drv);
/**
* @brief Stop the sensor
*
* @details If the sensor support it, it will be put in low energy mode.
*/
msg_t
HDC1000_stop(HDC1000_drv *drv);
/**
* @brief Check that the sensor is really present
*/
msg_t
HDC1000_check(HDC1000_drv *drv);
msg_t
HDC1000_readSerial(HDC1000_drv *drv, uint8_t *serial);
/**
* @brief Control the HD1000 heater.
*/
msg_t
HDC1000_setHeater(HDC1000_drv *drv,
bool on);
/**
* @brief Time necessary for the sensor to boot
*
* @returns
* unsigned int time in millis-seconds
*/
static inline unsigned int
HDC1000_getBootupTime(HDC1000_drv *drv) {
(void)drv;
return 15;
};
/**
* @brief Time necessary the sensor to for starting
*
* @returns
* unsigned int time in millis-seconds
*/
static inline unsigned int
HDC1000_getStartupTime(HDC1000_drv *drv) {
(void)drv;
return 0;
};
/**
* @brief Time in milli-seconds necessary for acquiring a naw measure
*
* @returns
* unsigned int time in millis-seconds
*/
static inline unsigned int
HDC1000_getAcquisitionTime(HDC1000_drv *drv) {
return drv->delay;
}
/**
* @brief Trigger a mesure acquisition
*/
msg_t
HDC1000_startMeasure(HDC1000_drv *drv);
/**
* @brief Read the newly acquiered measure
*
* @note According the the sensor design the measure read
* can be any value acquired after the acquisition time
* and the call to readMeasure.
*/
msg_t
HDC1000_readMeasure(HDC1000_drv *drv,
float *temperature, float *humidity);
/**
* @brief Read temperature and humidity
*
* @details According to the sensor specification/configuration
* (see #HDC1000_CONTINUOUS_ACQUISITION_SUPPORTED),
* if the sensor is doing continuous measurement
* it's value will be requested and returned immediately.
* Otherwise a measure is started, the necessary amount of
* time for acquiring the value is spend sleeping (not spinning),
* and finally the measure is read.
*
* @note In continuous measurement mode, if you just started
* the sensor, you will need to wait getAcquisitionTime()
* in addition to the usual getStartupTime()
* @note If using several sensors, it is better to start all the
* measure together, wait for the sensor having the longuest
* aquisition time, and finally read all the values
*/
msg_t
HDC1000_readTemperatureHumidity(HDC1000_drv *drv,
float *temperature, float *humidity);
/**
* @brief Return the humidity value in percent.
*
* @details Use readTemperatureHumidity() for returning the humidity value.
*
* @note Prefere readTemperatureHumidity(), if you need both temperature
* and humidity, or if you need better error handling.
*
* @returns
* float humidity percent
* NAN on failure
*/
static inline float
HDC1000_getHumidity(HDC1000_drv *drv) {
float humidity = NAN;
HDC1000_readTemperatureHumidity(drv, NULL, &humidity);
return humidity;
}
/**
* @brief Return the temperature value in °C.
*
* @details Use readTemperatureHumidity() for returning the humidity value.
*
* @note Prefere readTemperatureHumidity(), if you need both temperature
* and humidity, or if you need better error handling.
*
* @returns
* float humidity percent
* NAN on failure
*/
static inline float
HDC1000_getTemperature(HDC1000_drv *drv) {
float temperature = NAN;
HDC1000_readTemperatureHumidity(drv, &temperature, NULL);
return temperature;
}
#endif

267
os/various/i2c_helpers.h Normal file
View File

@ -0,0 +1,267 @@
#ifndef I2C_HELPERS_H
#define I2C_HELPERS_H
#include "hal.h"
#include "bswap.h"
typedef struct {
/**
* @brief Pointer to the I2C driver.
*/
I2CDriver *driver;
/**
* @brief I2C address.
*/
i2caddr_t addr;
} I2CHelper;
#if !defined(I2C_HELPERS_AUTOMATIC_DRV) || (I2C_HELPERS_AUTOMATIC_DRV == FALSE)
#define i2c_send(i2c, txbuf, txbytes) \
_i2c_send(i2c, txbuf, txbytes)
#define i2c_transmit(i2c, txbuf, txbytes, rxbuf, rxbytes) \
_i2c_transmit(i2c, txbuf, txbytes, rxbuf, rxbytes)
#define i2c_receive(i2, rxbuf, rxbytes) \
_i2c_receive(i2c, rxbuf, rxbytes)
#define i2c_send_timeout(i2c, txbuf, txbytes) \
_i2c_send(i2c, txbuf, txbytes)
#define i2c_transmit_timeout(i2c, txbuf, txbytes, rxbuf, rxbytes) \
_i2c_transmit(i2c, txbuf, txbytes, rxbuf, rxbytes)
#define i2c_receive_timeout(i2, rxbuf, rxbytes) \
_i2c_receive(i2c, rxbuf, rxbytes)
#define i2c_reg(i2c, reg) \
_i2c_reg(i2c, reg)
#define i2c_reg_recv8(i2c, reg, val) \
_i2c_reg_recv8(i2c, reg, val)
#define i2c_reg_recv16(i2c, reg, val) \
_i2c_reg_recv16(i2c, reg, val)
#define i2c_reg_recv16_le(i2c, reg, val) \
_i2c_reg_recv16_le(i2c, reg, val)
#define i2c_reg_recv16_be(i2c, reg, val) \
_i2c_reg_recv16_be(i2c, reg, val)
#define i2c_reg_recv32(i2c, reg, val) \
_i2c_reg_recv32(i2c, reg, val)
#define i2c_reg_recv32_le(i2c, reg, val) \
_i2c_reg_recv32_le(i2c, reg, val)
#define i2c_reg_recv32_be(i2c, reg, val) \
_i2c_reg_recv32_be(i2c, reg, val)
#define i2c_recv8(i2c, val) \
_i2c_recv8(i2c, val)
#define i2c_recv16(i2c, val) \
_i2c_recv16(i2c, val)
#define i2c_recv16_le(i2c, val) \
_i2c_recv16_le(i2c, val)
#define i2c_recv16_be(i2c, val) \
_i2c_recv16_be(i2c, val)
#define i2c_recv32(i2c, val) \
_i2c_recv32(i2c, val)
#define i2c_recv32_le(i2c, val) \
_i2c_recv32_le(i2c, val)
#define i2c_recv32_be(i2c, val) \
_i2c_recv32_be(i2c, val)
#else
#define i2c_send(txbuf, txbytes) \
_i2c_send(&drv->config->i2c, txbuf, txbytes)
#define i2c_transmit(txbuf, txbytes, rxbuf, rxbytes) \
_i2c_transmit(&drv->config->i2c, txbuf, txbytes, rxbuf, rxbytes)
#define i2c_receive(rxbuf, rxbytes) \
_i2c_receive(&drv->config->i2c, rxbuf, rxbytes)
#define i2c_send_timeout(txbuf, txbytes) \
_i2c_send(&drv->config->i2c, txbuf, txbytes)
#define i2c_transmit_timeout(txbuf, txbytes, rxbuf, rxbytes) \
_i2c_transmit(&drv->config->i2c, txbuf, txbytes, rxbuf, rxbytes)
#define i2c_receive_timeout(rxbuf, rxbytes) \
_i2c_receive(&drv->config->i2c, rxbuf, rxbytes)
#define i2c_reg(reg) \
_i2c_reg(&drv->config->i2c, reg)
#define i2c_reg_recv8(reg, val) \
_i2c_reg_recv8(&drv->config->i2c, reg, val)
#define i2c_reg_recv16(reg, val) \
_i2c_reg_recv16(&drv->config->i2c, reg, val)
#define i2c_reg_recv16_le(reg, val) \
_i2c_reg_recv16_le(&drv->config->i2c, reg, val)
#define i2c_reg_recv16_be(reg, val) \
_i2c_reg_recv16_be(&drv->config->i2c, reg, val)
#define i2c_reg_recv32(reg, val) \
_i2c_reg_recv32(&drv->config->i2c, reg, val)
#define i2c_reg_recv32_le(reg, val) \
_i2c_reg_recv32_le(&drv->config->i2c, reg, val)
#define i2c_reg_recv32_be(reg, val) \
_i2c_reg_recv32_be(&drv->config->i2c, reg, val)
#define i2c_recv8(val) \
_i2c_recv8(&drv->config->i2c, val)
#define i2c_recv16(val) \
_i2c_recv16(&drv->config->i2c, val)
#define i2c_recv16_le(val) \
_i2c_recv16_le(&drv->config->i2c, val)
#define i2c_recv16_be(val) \
_i2c_recv16_be(&drv->config->i2c, val)
#define i2c_recv32(val) \
_i2c_recv32(&drv->config->i2c, val)
#define i2c_recv32_le(val) \
_i2c_recv32_le(&drv->config->i2c, val)
#define i2c_recv32_be(val) \
_i2c_recv32_be(&drv->config->i2c, val)
#endif
static inline msg_t
_i2c_send(I2CHelper *i2c, const uint8_t *txbuf, size_t txbytes) {
return i2cMasterTransmitTimeout(i2c->driver, i2c->addr,
txbuf, txbytes, NULL, 0, TIME_INFINITE);
};
static inline msg_t
_i2c_transmit(I2CHelper *i2c, const uint8_t *txbuf, size_t txbytes,
uint8_t *rxbuf, size_t rxbytes) {
return i2cMasterTransmitTimeout(i2c->driver, i2c->addr,
txbuf, txbytes, rxbuf, rxbytes, TIME_INFINITE);
}
static inline msg_t
_i2c_receive(I2CHelper *i2c, uint8_t *rxbuf, size_t rxbytes) {
return i2cMasterReceiveTimeout(i2c->driver, i2c->addr,
rxbuf, rxbytes, TIME_INFINITE);
};
static inline msg_t
_i2c_send_timeout(I2CHelper *i2c, const uint8_t *txbuf, size_t txbytes,
systime_t timeout) {
return i2cMasterTransmitTimeout(i2c->driver, i2c->addr,
txbuf, txbytes, NULL, 0, timeout);
};
static inline msg_t
_i2c_transmit_timeout(I2CHelper *i2c, const uint8_t *txbuf, size_t txbytes,
uint8_t *rxbuf, size_t rxbytes, systime_t timeout) {
return i2cMasterTransmitTimeout(i2c->driver, i2c->addr,
txbuf, txbytes, rxbuf, rxbytes, timeout);
}
static inline msg_t
_i2c_receive_timeout(I2CHelper *i2c, uint8_t *rxbuf, size_t rxbytes, systime_t timeout) {
return i2cMasterReceiveTimeout(i2c->driver, i2c->addr,
rxbuf, rxbytes, timeout);
};
/*======================================================================*/
static inline msg_t
_i2c_reg(I2CHelper *i2c, uint8_t reg) {
return _i2c_transmit(i2c, &reg, sizeof(reg), NULL, 0);
};
/*======================================================================*/
static inline msg_t
_i2c_reg_recv8(I2CHelper *i2c, uint8_t reg, uint8_t *val) {
return _i2c_transmit(i2c, &reg, sizeof(reg), (uint8_t*)val, sizeof(val));
};
static inline msg_t
_i2c_reg_recv16(I2CHelper *i2c, uint8_t reg, uint16_t *val) {
return _i2c_transmit(i2c, &reg, sizeof(reg), (uint8_t*)val, sizeof(val));
};
static inline msg_t
_i2c_reg_recv16_le(I2CHelper *i2c, uint8_t reg, uint16_t *val) {
int msg = _i2c_reg_recv16(i2c, reg, val);
if (msg >= 0) *val = le16_to_cpu(*val);
return msg;
};
static inline msg_t
_i2c_reg_recv16_be(I2CHelper *i2c, uint8_t reg, uint16_t *val) {
int msg = _i2c_reg_recv16(i2c, reg, val);
if (msg >= 0) *val = be16_to_cpu(*val);
return msg;
};
static inline msg_t
_i2c_reg_recv32(I2CHelper *i2c, uint8_t reg, uint32_t *val) {
return _i2c_transmit(i2c, &reg, sizeof(reg), (uint8_t*)val, sizeof(val));
};
static inline msg_t
_i2c_reg_recv32_le(I2CHelper *i2c, uint8_t reg, uint32_t *val) {
int msg = _i2c_reg_recv32(i2c, reg, val);
if (msg >= 0) *val = le32_to_cpu(*val);
return msg;
};
static inline msg_t
_i2c_reg_recv32_be(I2CHelper *i2c, uint8_t reg, uint32_t *val) {
int msg = _i2c_reg_recv32(i2c, reg, val);
if (msg >= 0) *val = be32_to_cpu(*val);
return msg;
};
/*======================================================================*/
static inline msg_t
_i2c_recv8(I2CHelper *i2c, uint8_t *val) {
return _i2c_receive(i2c, (uint8_t*)val, sizeof(val));
};
static inline msg_t
_i2c_recv16(I2CHelper *i2c, uint16_t *val) {
return _i2c_receive(i2c, (uint8_t*)val, sizeof(val));
};
static inline msg_t
_i2c_recv16_le(I2CHelper *i2c, uint16_t *val) {
int msg = _i2c_recv16(i2c, val);
if (msg >= 0) *val = le16_to_cpu(*val);
return msg;
};
static inline msg_t
_i2c_recv16_be(I2CHelper *i2c, uint16_t *val) {
int msg = _i2c_recv16(i2c, val);
if (msg >= 0) *val = be16_to_cpu(*val);
return msg;
};
static inline msg_t
_i2c_recv32(I2CHelper *i2c, uint32_t *val) {
return _i2c_receive(i2c, (uint8_t*)val, sizeof(val));
};
static inline msg_t
_i2c_recv32_le(I2CHelper *i2c, uint32_t *val) {
int msg = _i2c_recv32(i2c, val);
if (msg >= 0) *val = le32_to_cpu(*val);
return msg;
};
static inline msg_t
_i2c_recv32_be(I2CHelper *i2c, uint32_t *val) {
int msg = _i2c_recv32(i2c, val);
if (msg >= 0) *val = be32_to_cpu(*val);
return msg;
};
#endif