diff --git a/drivers/include/lis2dh12.h b/drivers/include/lis2dh12.h index 1a6abb79da..2b9c995889 100644 --- a/drivers/include/lis2dh12.h +++ b/drivers/include/lis2dh12.h @@ -36,17 +36,26 @@ #ifndef LIS2DH12_H #define LIS2DH12_H +#include + #include "saul.h" + +#ifdef MODULE_LIS2DH12_SPI #include "periph/spi.h" #include "periph/gpio.h" +#else +#include "periph/i2c.h" +#endif #ifdef __cplusplus extern "C" { #endif -/* I2C support is not implemented (yet), so throw an error when selected */ -#ifndef MODULE_LIS2DH12_SPI -#error "LIS2DH12 error: I2C mode is not supported, yet. Use module li2dh12_spi" +#if defined(MODULE_LIS2DH12) || defined(DOXYGEN) +/** + * @brief Default I2C slave address for LIS2DH12 devices + */ +#define LIS2DH12_ADDR_DEFAULT (0x19) #endif /** @@ -79,8 +88,13 @@ typedef enum { * @brief LIS2DH12 configuration parameters */ typedef struct { +#ifdef MODULE_LIS2DH12_SPI spi_t spi; /**< SPI bus the device is connected to */ gpio_t cs; /**< connected chip select pin */ +#else + i2c_t i2c; /**< I2C bus the device is connected to */ + uint8_t addr; /**< device address on the I2C bus */ +#endif lis2dh12_scale_t scale; /**< sampling sensitivity used */ lis2dh12_rate_t rate; /**< sampling rate used */ } lis2dh12_params_t; diff --git a/drivers/lis2dh12/include/lis2dh12_params.h b/drivers/lis2dh12/include/lis2dh12_params.h index 2ac1a03df0..b8e779543c 100644 --- a/drivers/lis2dh12/include/lis2dh12_params.h +++ b/drivers/lis2dh12/include/lis2dh12_params.h @@ -31,12 +31,28 @@ extern "C" { * @name Set default configuration parameters for LIS2DH12 devices * @{ */ +#ifdef MODULE_LIS2DH12_SPI /* default configuration for SPI mode */ #ifndef LIS2DH12_PARAM_SPI #define LIS2DH12_PARAM_SPI SPI_DEV(0) #endif #ifndef LIS2DH12_PARAM_CS #define LIS2DH12_PARAM_CS GPIO_PIN(0, 0) #endif +#define LIS2DH12_PARAMS_BUSCFG .spi = LIS2DH12_PARAM_SPI, \ + .cs = LIS2DH12_PARAM_CS + +#else /* default configuration for I2C mode */ +#ifndef LIS2DH12_PARAM_I2C +#define LIS2DH12_PARAM_I2C I2C_DEV(0) +#endif +#ifndef LIS2DH12_PARAM_ADDR +#define LIS2DH12_PARAM_ADDR LIS2DH12_ADDR_DEFAULT +#endif +#define LIS2DH12_PARAMS_BUSCFG .i2c = LIS2DH12_PARAM_I2C, \ + .addr = LIS2DH12_PARAM_ADDR + +#endif + #ifndef LIS2DH12_PARAM_SCALE #define LIS2DH12_PARAM_SCALE LIS2DH12_SCALE_2G #endif @@ -45,10 +61,9 @@ extern "C" { #endif #ifndef LIS2DH12_PARAMS -#define LIS2DH12_PARAMS { .spi = LIS2DH12_PARAM_SPI, \ - .cs = LIS2DH12_PARAM_CS, \ +#define LIS2DH12_PARAMS { LIS2DH12_PARAMS_BUSCFG, \ .scale = LIS2DH12_PARAM_SCALE, \ - .rate = LIS2DH12_PARAM_RATE } + .rate = LIS2DH12_PARAM_RATE, } #endif #ifndef LIS2DH12_SAULINFO diff --git a/drivers/lis2dh12/lis2dh12.c b/drivers/lis2dh12/lis2dh12.c index 9980a83f01..97ee76acce 100644 --- a/drivers/lis2dh12/lis2dh12.c +++ b/drivers/lis2dh12/lis2dh12.c @@ -25,22 +25,30 @@ #define ENABLE_DEBUG (0) #include "debug.h" +/* the following block contains the SPI mode specific adaption */ +#ifdef MODULE_LIS2DH12_SPI + /* SPI bus speed and mode */ #define BUS_CLK SPI_CLK_5MHZ #define MODE SPI_MODE_0 - #define BUS_OK SPI_OK - /* shortcuts for SPI bus parameters */ #define BUS (dev->p->spi) #define CS (dev->p->cs) - /* flag to set when reading from the device */ #define FLAG_READ (0x80) - /* flag to enable address auto incrementation on read or write */ #define FLAG_AINC (0x40) +static int _init_bus(const lis2dh12_t *dev) +{ + /* for SPI, we only need to initialize the chip select pin */ + if (spi_init_cs(BUS, CS) != SPI_OK) { + return LIS2DH12_NOBUS; + } + return LIS2DH12_OK; +} + static int _acquire(const lis2dh12_t *dev) { return spi_acquire(BUS, CS, MODE, BUS_CLK); @@ -68,6 +76,57 @@ static void _write(const lis2dh12_t *dev, uint8_t reg, uint8_t data) spi_transfer_reg(BUS, CS, reg, data); } +/* and now the I2C specific part of the driver */ +#else + +/* I2C config */ +#define BUS_OK (0) +/* I2C shortcuts */ +#define BUS (dev->p->i2c) +#define ADDR (dev->p->addr) +/* flag for enabling address auto-incrementation */ +#define FLAG_AINC (0x80) + +static int _init_bus(const lis2dh12_t *dev) +{ + (void) dev; + + /* for I2C, the bus is already set up by auto_init */ + return LIS2DH12_OK; +} + +static int _acquire(const lis2dh12_t *dev) +{ + return i2c_acquire(BUS); +} + +static void _release(const lis2dh12_t *dev) +{ + i2c_release(BUS); +} + +static uint8_t _read(const lis2dh12_t *dev, uint8_t reg) +{ + uint8_t tmp; + i2c_read_reg(BUS, ADDR, reg, &tmp, 0); + return tmp; +} + +static void _read_burst(const lis2dh12_t *dev, uint8_t reg, + void *data, size_t len) +{ + i2c_read_regs(BUS, ADDR, (FLAG_AINC | reg), data, len, 0); +} + +static void _write(const lis2dh12_t *dev, uint8_t reg, uint8_t data) +{ + DEBUG("[lis2dh12] write: reg 0x%02x, val 0x%02x\n", (int)reg, (int)data); + i2c_write_reg(BUS, ADDR, reg, data, 0); +} + +#endif /* MODULE_LIS2DH12_SPI */ + + int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params) { assert(dev && params); @@ -75,15 +134,15 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params) dev->p = params; dev->comp = (1000UL * (0x02 << (dev->p->scale >> 4))); - /* start by setting up the chip select pin */ - if (spi_init_cs(BUS, CS) != SPI_OK) { - DEBUG("[lis2dh12] error: unable to initialize CS pin\n"); + /* initialize the chip select line */ + if (_init_bus(dev) != LIS2DH12_OK) { + DEBUG("[lis2dh12] error: unable to initialize the bus\n"); return LIS2DH12_NOBUS; } - /* acquire the SPI bus and verify that our parameters are valid */ + /* acquire the bus and verify that our parameters are valid */ if (_acquire(dev) != BUS_OK) { - DEBUG("[lis2dh12] error: unable to acquire SPI bus\n"); + DEBUG("[lis2dh12] error: unable to acquire the bus\n"); return LIS2DH12_NOBUS; } @@ -100,6 +159,7 @@ int lis2dh12_init(lis2dh12_t *dev, const lis2dh12_params_t *params) _write(dev, REG_CTRL_REG1, dev->p->rate); _release(dev); + DEBUG("[lis2dh12] initialization successful\n"); return LIS2DH12_OK; } diff --git a/makefiles/pseudomodules.inc.mk b/makefiles/pseudomodules.inc.mk index e9462ecac8..cac0eea00d 100644 --- a/makefiles/pseudomodules.inc.mk +++ b/makefiles/pseudomodules.inc.mk @@ -43,6 +43,7 @@ PSEUDOMODULES += gnrc_txtsnd PSEUDOMODULES += i2c_scan PSEUDOMODULES += l2filter_blacklist PSEUDOMODULES += l2filter_whitelist +PSEUDOMODULES += lis2dh12_i2c PSEUDOMODULES += lis2dh12_spi PSEUDOMODULES += log PSEUDOMODULES += log_printfnoformat