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

drivers/lis2dh12: added I2C mode

This commit is contained in:
Hauke Petersen 2018-01-23 16:37:34 +01:00 committed by Benjamin Valentin
parent a7cb0a4b77
commit 8a69e4ac69
4 changed files with 105 additions and 15 deletions

View File

@ -36,17 +36,26 @@
#ifndef LIS2DH12_H
#define LIS2DH12_H
#include <stdint.h>
#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;

View File

@ -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

View File

@ -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;
}

View File

@ -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