Library for LIS2DH12 acc.

Dependents:   acnSensa_LIS aconnoCellularGnss Lizzy

Lis2dh12.cpp

Committer:
Dominik Bartolovic
Date:
2018-10-15
Revision:
7:f1ba533021b8
Parent:
6:b7e3a0c1210b

File content as of revision 7:f1ba533021b8:

/*
 *
 *  LIS2DH12 MEMS digital output motion sensor
 *  More info @ aconno.de
 *  Made by Jurica Resetar
 *  jurica_resetar@yahoo.com
 *
 */

#include "Lis2dh12.h"
#include "Lis2dh12_regs.h"

Lis2dh12::Lis2dh12(I2C *i2c_, char address) : i2c(i2c_, address),
                                              spiInterface(false){
}

Lis2dh12::Lis2dh12(SPI *_spi, DigitalOut *_cs) : i2c(NULL, 0),
                                                 spi(_spi),
                                                 cs(_cs),
                                                 spiInterface(true){
    *cs = 1;
    spi->format(8, 3);
    spi->frequency(1000000);
}

uint8_t Lis2dh12::whoIAm(){
    char regAddr = (char)WHO_AM_I;
    char regData;
    readFromReg(regAddr, (uint8_t*)&regData, 1);
    return (uint8_t)regData;
}

uint8_t Lis2dh12::setMode(Mode mode){
    char ctrl1Copy;
    char ctrl4Copy;
    uint8_t success;

    readFromReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    readFromReg((char)CTRL_REG4, (uint8_t*)&ctrl4Copy, 1);

    switch(mode){
        case HIGH_RES:
            ctrl1Copy &= 0xF7;
            ctrl4Copy |= 0x08;
            break;
        case NORMAL:
            ctrl1Copy &= 0xF7;
            ctrl4Copy &= 0xF7;
            break;
        case LOW_POWER:
            ctrl1Copy |= 0x08;
            ctrl4Copy &= 0xF7;
            break;
        default:
            return 0;
    }
    writeToReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    success = writeToReg((char)CTRL_REG4, (uint8_t*)&ctrl4Copy, 1);
    return success;
}

uint8_t Lis2dh12::enableAxes(Axis axis){
    char ctrl1Copy;
    readFromReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    ctrl1Copy |= axis;
    writeToReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    return 0;
}

uint8_t Lis2dh12::disableAxes(Axis axis){
    char ctrl1Copy;
    readFromReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    ctrl1Copy &= ~(1 << axis);
    writeToReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    return 0;
}

int16_t Lis2dh12::readXAxis(){
    int16_t rawData;
    char tempData;
    // Make sure new data is ready
    do{
        readFromReg((char)STATUS, (uint8_t*)&tempData, 1);
    }while(!(tempData & 0x08));
    do{
        readFromReg((char)STATUS, (uint8_t*)&tempData, 1);
    }while(!(tempData & 0x80));
    // Same data have been overwritten

    //readFromReg((char)OUT_X_H, (uint8_t*)&tempData, 1);
    //rawData = (int8_t)tempData << 8;
    readFromReg((char)OUT_X_L, (uint8_t*)&rawData, 1);
    readFromReg((char)OUT_X_H, ((uint8_t*)&rawData)+1, 1);

    if (rawData >= 0)
        rawData = (rawData>>4);
    else
        rawData = (rawData>>4) | 0xF000;

    return rawData;
}

int16_t Lis2dh12::readYAxis(){
    int16_t rawData;
    char tempData;
    //readFromReg((char)OUT_Y_H, (uint8_t*)&tempData, 1);
    //rawData = (int8_t)tempData << 8;
    readFromReg((char)OUT_Y_L, (uint8_t*)&rawData, 1);
    readFromReg((char)OUT_Y_H, ((uint8_t*)&rawData)+1, 1);

    if (rawData >= 0)
        rawData = (rawData>>4);
    else
        rawData = (rawData>>4) | 0xF000;

    return rawData;
}

int16_t Lis2dh12::readZAxis(){
    int16_t rawData = 0;
    char tempData;
    //readFromReg((char)OUT_Z_H, (uint8_t*)&tempData, 1);
    //rawData = (int8_t)tempData << 8;
    readFromReg((char)OUT_Z_L, (uint8_t*)&rawData, 1);
    readFromReg((char)OUT_Z_H, ((uint8_t*)&rawData)+1, 1);

    if (rawData >= 0)
        rawData = (rawData>>4);
    else
        rawData = (rawData>>4) | 0xF000;

    return rawData;
}

uint8_t Lis2dh12::setODR(Odr odr){
    char ctrl1Copy;
    readFromReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    ctrl1Copy |= (odr << 4);
    writeToReg((char)CTRL_REG1, (uint8_t*)&ctrl1Copy, 1);
    return 0;
}

uint8_t Lis2dh12::setScale(Scale scale){
    char ctrl4Copy;
    readFromReg((char)CTRL_REG4, (uint8_t*)&ctrl4Copy, 1);
    ctrl4Copy |= (scale << 4);
    writeToReg((char)CTRL_REG4, (uint8_t*)&ctrl4Copy, 1);
    return 0;
}

/* Interrupt activity 1 driven to INT1 pad */
// TODO: Napraviti tako da postoji samo jedna metoda int1Setup koja prima gro
// parametara: THS, DUR, Latch...
uint8_t Lis2dh12::int1Setup(uint8_t setup){
    char data = setup;
    writeToReg((char)CTRL_REG3, (uint8_t*)&data, 1);
    return 0;
}

uint8_t Lis2dh12::int1Latch(uint8_t enable){
    char ctrl5Copy;
    readFromReg((char)CTRL_REG5, (uint8_t*)&ctrl5Copy, 1);
    ctrl5Copy |= enable;
    writeToReg((char)CTRL_REG5, (uint8_t*)&ctrl5Copy, 1);
    return 0;
}

uint8_t Lis2dh12::int1Duration(uint8_t duration){
    char copy = duration;
    writeToReg((char)INT1_DURATION, (uint8_t*)&copy, 1);
    return 0;
}

uint8_t Lis2dh12::int1Threshold(uint8_t threshold){
    char copy = threshold;
    writeToReg((char)INT1_THS, (uint8_t*)&copy, 1);
    return 0;
}

uint8_t Lis2dh12::int1Config(uint8_t config){
    char copy = config;
    writeToReg((char)INT1_CFG, (uint8_t*)&copy, 1);
    return 0;
}

void Lis2dh12::clearIntFlag(){
    char data;
    readFromReg((char)INT1_SRC, (uint8_t*)&data, 1);
}

uint8_t Lis2dh12::readFromReg(uint8_t regAddr, uint8_t *buff, size_t buffSize)
{
    // Most significant bit represents read from register, bit after it
    // represents address increment if multiple read, which is enabled.
    const uint8_t spiSetup = 0xC0;

    uint8_t retVal = 0;

    if( spiInterface )
    {
        *cs = 0;

        spi->write(spiSetup | regAddr);

        while(buffSize--)
        {
            *buff = spi->write(0x00);
            buff++;
        }

        *cs = 1;
    }
    else
    {
         retVal = i2c.readFromReg((char)regAddr, (char*)buff, buffSize);
    }

    return retVal;
}

uint8_t Lis2dh12::writeToReg(uint8_t regAddr, uint8_t *buff, size_t buffSize)
{
    // Most significant bit represents write from register, bit after it
    // represents address increment if multiple write, which is enabled.
    const uint8_t spiSetup = 0x40;

    uint8_t retVal = 0;

    if( spiInterface )
    {
        *cs = 0;

        spi->write(spiSetup | regAddr);

        while(buffSize--)
        {
            spi->write(*buff);
            buff++;
        }

        *cs = 1;
    }
    else
    {
        retVal = i2c.writeToReg((char)regAddr, (char*)buff, buffSize);
    }

    return retVal;
}