|
|
|
@ -1,54 +1,59 @@
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (C) 2015 Eistec AB
|
|
|
|
|
* 2016 Freie Universität Berlin
|
|
|
|
|
*
|
|
|
|
|
* 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.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include "periph/gpio.h"
|
|
|
|
|
#include "periph/spi.h"
|
|
|
|
|
#include "lis3dh.h"
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @ingroup drivers_lis3dh
|
|
|
|
|
* @{
|
|
|
|
|
*
|
|
|
|
|
* @file
|
|
|
|
|
* @brief Implementation of LIS3DH SPI driver
|
|
|
|
|
* @brief Implementation of LIS3DH SPI driver
|
|
|
|
|
*
|
|
|
|
|
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
|
|
|
|
|
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
|
|
|
|
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <stddef.h>
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#include "periph/gpio.h"
|
|
|
|
|
#include "periph/spi.h"
|
|
|
|
|
#include "lis3dh.h"
|
|
|
|
|
|
|
|
|
|
static inline int lis3dh_write_bits(const lis3dh_t *dev, const lis3dh_reg_t reg, const uint8_t mask,
|
|
|
|
|
const uint8_t values);
|
|
|
|
|
static int lis3dh_write_reg(const lis3dh_t *dev, const lis3dh_reg_t reg, const uint8_t value);
|
|
|
|
|
static int lis3dh_read_regs(const lis3dh_t *dev, const lis3dh_reg_t reg, const uint8_t len,
|
|
|
|
|
uint8_t *buf);
|
|
|
|
|
#define SPI_MODE SPI_MODE_0
|
|
|
|
|
|
|
|
|
|
static inline int lis3dh_write_bits(const lis3dh_t *dev, const lis3dh_reg_t reg,
|
|
|
|
|
const uint8_t mask, const uint8_t values);
|
|
|
|
|
static int lis3dh_write_reg(const lis3dh_t *dev, const lis3dh_reg_t reg,
|
|
|
|
|
const uint8_t value);
|
|
|
|
|
static int lis3dh_read_regs(const lis3dh_t *dev, const lis3dh_reg_t reg,
|
|
|
|
|
const uint8_t len, uint8_t *buf);
|
|
|
|
|
|
|
|
|
|
int lis3dh_init(lis3dh_t *dev, spi_t spi, gpio_t cs_pin, uint8_t scale)
|
|
|
|
|
int lis3dh_init(lis3dh_t *dev, spi_t spi, spi_clk_t clk,
|
|
|
|
|
gpio_t cs_pin, uint8_t scale)
|
|
|
|
|
{
|
|
|
|
|
uint8_t in;
|
|
|
|
|
uint8_t test;
|
|
|
|
|
|
|
|
|
|
dev->spi = spi;
|
|
|
|
|
dev->clk = clk;
|
|
|
|
|
dev->cs = cs_pin;
|
|
|
|
|
dev->scale = 0;
|
|
|
|
|
|
|
|
|
|
/* CS */
|
|
|
|
|
gpio_init(dev->cs, GPIO_OUT);
|
|
|
|
|
gpio_set(dev->cs);
|
|
|
|
|
|
|
|
|
|
if (lis3dh_read_regs(dev, LIS3DH_REG_WHO_AM_I, 1, &in) < 0) {
|
|
|
|
|
/* Communication error */
|
|
|
|
|
/* initialize the chip select line */
|
|
|
|
|
if (spi_init_cs(dev->spi, dev->cs) != SPI_OK) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (in != LIS3DH_WHO_AM_I_RESPONSE) {
|
|
|
|
|
/* Chip is not responding correctly */
|
|
|
|
|
/* test connection to the device */
|
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, dev->clk);
|
|
|
|
|
test = spi_transfer_reg(dev->spi, dev->cs, LIS3DH_REG_WHO_AM_I, 0);
|
|
|
|
|
spi_release(dev->spi);
|
|
|
|
|
if (test != LIS3DH_WHO_AM_I_RESPONSE) {
|
|
|
|
|
/* chip is not responding correctly */
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -78,23 +83,14 @@ int lis3dh_read_xyz(const lis3dh_t *dev, lis3dh_data_t *acc_data)
|
|
|
|
|
{
|
|
|
|
|
uint8_t i;
|
|
|
|
|
/* Set READ MULTIPLE mode */
|
|
|
|
|
static const uint8_t addr = (LIS3DH_REG_OUT_X_L | LIS3DH_SPI_READ_MASK | LIS3DH_SPI_MULTI_MASK);
|
|
|
|
|
static const uint8_t addr = (LIS3DH_REG_OUT_X_L | LIS3DH_SPI_READ_MASK |
|
|
|
|
|
LIS3DH_SPI_MULTI_MASK);
|
|
|
|
|
|
|
|
|
|
/* Acquire exclusive access to the bus. */
|
|
|
|
|
spi_acquire(dev->spi);
|
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, dev->clk);
|
|
|
|
|
/* Perform the transaction */
|
|
|
|
|
gpio_clear(dev->cs);
|
|
|
|
|
|
|
|
|
|
if (spi_transfer_regs(dev->spi, addr, NULL, (char *)acc_data,
|
|
|
|
|
sizeof(lis3dh_data_t)) != sizeof(lis3dh_data_t)) {
|
|
|
|
|
/* Transfer error */
|
|
|
|
|
gpio_set(dev->cs);
|
|
|
|
|
/* Release the bus for other threads. */
|
|
|
|
|
spi_release(dev->spi);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gpio_set(dev->cs);
|
|
|
|
|
spi_transfer_regs(dev->spi, dev->cs, addr,
|
|
|
|
|
NULL, acc_data, sizeof(lis3dh_data_t));
|
|
|
|
|
/* Release the bus for other threads. */
|
|
|
|
|
spi_release(dev->spi);
|
|
|
|
|
|
|
|
|
@ -111,29 +107,35 @@ int lis3dh_read_xyz(const lis3dh_t *dev, lis3dh_data_t *acc_data)
|
|
|
|
|
|
|
|
|
|
int lis3dh_read_aux_adc1(const lis3dh_t *dev, int16_t *out)
|
|
|
|
|
{
|
|
|
|
|
return lis3dh_read_regs(dev, LIS3DH_REG_OUT_AUX_ADC1_L, LIS3DH_ADC_DATA_SIZE, (uint8_t *)out);
|
|
|
|
|
return lis3dh_read_regs(dev, LIS3DH_REG_OUT_AUX_ADC1_L,
|
|
|
|
|
LIS3DH_ADC_DATA_SIZE, (uint8_t *)out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int lis3dh_read_aux_adc2(const lis3dh_t *dev, int16_t *out)
|
|
|
|
|
{
|
|
|
|
|
return lis3dh_read_regs(dev, LIS3DH_REG_OUT_AUX_ADC2_L, LIS3DH_ADC_DATA_SIZE, (uint8_t *)out);
|
|
|
|
|
return lis3dh_read_regs(dev, LIS3DH_REG_OUT_AUX_ADC2_L,
|
|
|
|
|
LIS3DH_ADC_DATA_SIZE, (uint8_t *)out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int lis3dh_read_aux_adc3(const lis3dh_t *dev, int16_t *out)
|
|
|
|
|
{
|
|
|
|
|
return lis3dh_read_regs(dev, LIS3DH_REG_OUT_AUX_ADC3_L, LIS3DH_ADC_DATA_SIZE, (uint8_t *)out);
|
|
|
|
|
return lis3dh_read_regs(dev, LIS3DH_REG_OUT_AUX_ADC3_L,
|
|
|
|
|
LIS3DH_ADC_DATA_SIZE, (uint8_t *)out);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int lis3dh_set_aux_adc(lis3dh_t *dev, const uint8_t enable, const uint8_t temperature)
|
|
|
|
|
int lis3dh_set_aux_adc(lis3dh_t *dev, const uint8_t enable,
|
|
|
|
|
const uint8_t temperature)
|
|
|
|
|
{
|
|
|
|
|
return lis3dh_write_bits(dev, LIS3DH_REG_TEMP_CFG_REG, LIS3DH_TEMP_CFG_REG_ADC_PD_MASK,
|
|
|
|
|
return lis3dh_write_bits(dev, LIS3DH_REG_TEMP_CFG_REG,
|
|
|
|
|
LIS3DH_TEMP_CFG_REG_ADC_PD_MASK,
|
|
|
|
|
(enable ? LIS3DH_TEMP_CFG_REG_ADC_PD_MASK : 0) |
|
|
|
|
|
(temperature ? LIS3DH_TEMP_CFG_REG_TEMP_EN_MASK : 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int lis3dh_set_axes(lis3dh_t *dev, const uint8_t axes)
|
|
|
|
|
{
|
|
|
|
|
return lis3dh_write_bits(dev, LIS3DH_REG_CTRL_REG1, LIS3DH_CTRL_REG1_XYZEN_MASK, axes);
|
|
|
|
|
return lis3dh_write_bits(dev, LIS3DH_REG_CTRL_REG1,
|
|
|
|
|
LIS3DH_CTRL_REG1_XYZEN_MASK, axes);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int lis3dh_set_fifo(lis3dh_t *dev, const uint8_t mode, const uint8_t watermark)
|
|
|
|
@ -190,8 +192,8 @@ int lis3dh_set_scale(lis3dh_t *dev, const uint8_t scale)
|
|
|
|
|
default:
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return lis3dh_write_bits(dev, LIS3DH_REG_CTRL_REG4, LIS3DH_CTRL_REG4_FS_MASK,
|
|
|
|
|
scale_reg);
|
|
|
|
|
return lis3dh_write_bits(dev, LIS3DH_REG_CTRL_REG4,
|
|
|
|
|
LIS3DH_CTRL_REG4_FS_MASK, scale_reg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int lis3dh_set_int1(lis3dh_t *dev, const uint8_t mode)
|
|
|
|
@ -218,31 +220,23 @@ int lis3dh_get_fifo_level(lis3dh_t *dev)
|
|
|
|
|
* @param[in] dev Device descriptor
|
|
|
|
|
* @param[in] reg The source register starting address
|
|
|
|
|
* @param[in] len Number of bytes to read
|
|
|
|
|
* @param[out] buf The values of the source registers will be written here
|
|
|
|
|
* @param[out] buf The values of the source registers will be written
|
|
|
|
|
* here
|
|
|
|
|
*
|
|
|
|
|
* @return 0 on success
|
|
|
|
|
* @return -1 on error
|
|
|
|
|
*/
|
|
|
|
|
static int lis3dh_read_regs(const lis3dh_t *dev, const lis3dh_reg_t reg, const uint8_t len,
|
|
|
|
|
uint8_t *buf)
|
|
|
|
|
static int lis3dh_read_regs(const lis3dh_t *dev, const lis3dh_reg_t reg,
|
|
|
|
|
const uint8_t len, uint8_t *buf)
|
|
|
|
|
{
|
|
|
|
|
/* Set READ MULTIPLE mode */
|
|
|
|
|
uint8_t addr = (reg & LIS3DH_SPI_ADDRESS_MASK) | LIS3DH_SPI_READ_MASK | LIS3DH_SPI_MULTI_MASK;
|
|
|
|
|
uint8_t addr = (reg & LIS3DH_SPI_ADDRESS_MASK) | LIS3DH_SPI_READ_MASK |
|
|
|
|
|
LIS3DH_SPI_MULTI_MASK;
|
|
|
|
|
|
|
|
|
|
/* Acquire exclusive access to the bus. */
|
|
|
|
|
spi_acquire(dev->spi);
|
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, dev->clk);
|
|
|
|
|
/* Perform the transaction */
|
|
|
|
|
gpio_clear(dev->cs);
|
|
|
|
|
|
|
|
|
|
if (spi_transfer_regs(dev->spi, addr, NULL, (char *)buf, len) < 0) {
|
|
|
|
|
/* Transfer error */
|
|
|
|
|
gpio_set(dev->cs);
|
|
|
|
|
/* Release the bus for other threads. */
|
|
|
|
|
spi_release(dev->spi);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gpio_set(dev->cs);
|
|
|
|
|
spi_transfer_regs(dev->spi, dev->cs, addr, NULL, buf, (size_t)len);
|
|
|
|
|
/* Release the bus for other threads. */
|
|
|
|
|
spi_release(dev->spi);
|
|
|
|
|
|
|
|
|
@ -258,27 +252,20 @@ static int lis3dh_read_regs(const lis3dh_t *dev, const lis3dh_reg_t reg, const u
|
|
|
|
|
* @return 0 on success
|
|
|
|
|
* @return -1 on error
|
|
|
|
|
*/
|
|
|
|
|
static int lis3dh_write_reg(const lis3dh_t *dev, const lis3dh_reg_t reg, const uint8_t value)
|
|
|
|
|
static int lis3dh_write_reg(const lis3dh_t *dev, const lis3dh_reg_t reg,
|
|
|
|
|
const uint8_t value)
|
|
|
|
|
{
|
|
|
|
|
/* Set WRITE SINGLE mode */
|
|
|
|
|
uint8_t addr = (reg & LIS3DH_SPI_ADDRESS_MASK) | LIS3DH_SPI_WRITE_MASK | LIS3DH_SPI_SINGLE_MASK;
|
|
|
|
|
uint8_t addr = ((reg & LIS3DH_SPI_ADDRESS_MASK) | LIS3DH_SPI_WRITE_MASK |
|
|
|
|
|
LIS3DH_SPI_SINGLE_MASK);
|
|
|
|
|
|
|
|
|
|
/* Acquire exclusive access to the bus. */
|
|
|
|
|
spi_acquire(dev->spi);
|
|
|
|
|
spi_acquire(dev->spi, dev->cs, SPI_MODE, dev->clk);
|
|
|
|
|
/* Perform the transaction */
|
|
|
|
|
gpio_clear(dev->cs);
|
|
|
|
|
|
|
|
|
|
if (spi_transfer_reg(dev->spi, addr, value, NULL) < 0) {
|
|
|
|
|
/* Transfer error */
|
|
|
|
|
gpio_set(dev->cs);
|
|
|
|
|
/* Release the bus for other threads. */
|
|
|
|
|
spi_release(dev->spi);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
gpio_set(dev->cs);
|
|
|
|
|
spi_transfer_reg(dev->spi, dev->cs, addr, value);
|
|
|
|
|
/* Release the bus for other threads. */
|
|
|
|
|
spi_release(dev->spi);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -292,9 +279,8 @@ static int lis3dh_write_reg(const lis3dh_t *dev, const lis3dh_reg_t reg, const u
|
|
|
|
|
* @return 0 on success
|
|
|
|
|
* @return -1 on error
|
|
|
|
|
*/
|
|
|
|
|
static inline int
|
|
|
|
|
lis3dh_write_bits(const lis3dh_t *dev, const lis3dh_reg_t reg, const uint8_t mask,
|
|
|
|
|
const uint8_t values)
|
|
|
|
|
static inline int lis3dh_write_bits(const lis3dh_t *dev, const lis3dh_reg_t reg,
|
|
|
|
|
const uint8_t mask, const uint8_t values)
|
|
|
|
|
{
|
|
|
|
|
uint8_t tmp;
|
|
|
|
|
|
|
|
|
|