L3GD20 Library using FIFO and Interrupt

Fork of L3GD20_SPI by Tatsuki Fukuda

L3GD20.cpp

Committer:
lelect
Date:
2014-05-13
Revision:
3:6e935e7cec72
Parent:
2:be6daa938101

File content as of revision 3:6e935e7cec72:

#include "mbed.h"
#include "L3GD20.h"

L3GD20::L3GD20(PinName mosi, PinName miso, PinName scl, PinName cs,PinName interrupt2)
    :_spi(mosi,miso,scl)
    ,_cs(cs)
    ,_int2(interrupt2)
{
    _spi.format(8,3);
    _spi.frequency(10000000);
    int val;
    read(null,&val);
    read(WhoAmI,&val);
    if(val==0x0F) { //Discover L3GD20
    }
    configReadOut();
    statusReadOut();

}
void L3GD20::write(RESISTER reg,int val)
{
    _cs=0;
    _spi.write(reg);
    _spi.write(val);
    _cs=1;
}
void L3GD20::read(RESISTER reg,int* val)
{
    _cs=0;
    _spi.write(READ|reg);
    (*val)=_spi.write(0x00);
    _cs=1;
}

void L3GD20::start(DIRECTION enable)
{
    _config.CTRL_REG1.B.Enable=enable;
    _config.CTRL_REG1.b.PD=1;
    write(CtrlReg1,_config.CTRL_REG1.word);
    allReadOut();
}
void L3GD20::resetFIFO()
{
    enableFIFO(L3GD20::BYPASSmode,L3GD20::none,20);
    enableFIFO(L3GD20::STREAMmode,L3GD20::none);
}
void L3GD20::start(DIRECTION enable,void (*func)(anglerrates*))
{
    reboot();
    userFunction=func;
    _int2.rise(this,(&L3GD20::interrupt));
    start(enable);
    resetFIFO();
    enableFIFO(L3GD20::BYPASSmode,L3GD20::none,20);
    enableFIFO(L3GD20::STREAMmode,L3GD20::none);
}
void L3GD20::interrupt(void)
{
    read(&value,XYZ);
    if(NULL!=userFunction) {
        userFunction(&value);
    }
}
void L3GD20::stop()
{
    _config.CTRL_REG1.word=_config.CTRL_REG1.word&0xF0;
    write(CtrlReg1,_config.CTRL_REG1.word);
}
void L3GD20::sleep()
{
    _config.CTRL_REG1.word=_config.CTRL_REG1.word&0xF8;
    write(CtrlReg1,_config.CTRL_REG1.word);
}
void L3GD20::reboot()
{
    _config.CTRL_REG5.b.BOOT=1;
    write(CtrlReg5,_config.CTRL_REG5.word);
}
void L3GD20::read(anglerrates* val,DIRECTION direction)
{
    if(direction&X) {
        int x_l,x_h;
        read(OutXL,&x_l);
        read(OutXH,&x_h);
        val->X=(x_l)|(x_h<<8);
    }
    if(direction&Y) {
        int y_l,y_h;
        read(OutYL,&y_l);
        read(OutYH,&y_h);
        val->Y=(y_l)|(y_h<<8);
    }
    if(direction&Z) {
        int z_l,z_h;
        read(OutZL,&z_l);
        read(OutZH,&z_h);
        val->Z=(z_l)|(z_h<<8);
    }
    if(_config.CTRL_REG4.B.FS==0x00) {
        val->x=8.75*(float)val->X;
        val->y=8.75*(float)val->Y;
        val->z=8.75*(float)val->Z;
    } else if(_config.CTRL_REG4.B.FS==0x01) {
        val->x=17.5*(float)val->X;
        val->y=17.5*(float)val->Y;
        val->z=17.5*(float)val->Z;
    } else if((_config.CTRL_REG4.B.FS==0x10)|(_config.CTRL_REG4.B.FS==0x11)) {
        val->x=70.0*(float)val->X;
        val->y=70.0*(float)val->Y;
        val->z=70.0*(float)val->Z;
    }
}
int L3GD20::readTemperature()
{
    read(OutTemp,&_status.OUT_TEMP);
    return _status.OUT_TEMP;
}
void L3GD20::enableFIFO(FIFO_mode mode,FIFOstatus interrupt,const int threshold)
{
    _config.CTRL_REG5.b.FIFO_EN=1;
    if(interrupt==empty) {
        _config.CTRL_REG3.b.I2_Empty=1;
    } else if(interrupt==watermark) {
        _config.CTRL_REG3.b.I2_WTM=1;
    } else if(interrupt==overrun) {
        _config.CTRL_REG3.b.I2_ORun=1;
    } else if(interrupt==none) {
        _config.CTRL_REG3.b.I2_DRDY=1;
    }
    _config.FIFO_CTRL_REG.B.FM=mode;
    if(threshold>0) {
        if(threshold<30) {
            _config.FIFO_CTRL_REG.B.WTM=31;
        } else {
            _config.FIFO_CTRL_REG.B.WTM=threshold;
        }
    }
    write(CtrlReg3,_config.CTRL_REG3.word);
    write(CtrlReg5,_config.CTRL_REG5.word);
    write(FIFOCtrlReg,_config.FIFO_CTRL_REG.word);
}
int L3GD20::updateFIFO(void)
{
    read(FIFOSrcReg,&_status.FIFO_SRC_REG.word);
    read(FIFOCtrlReg,&_config.FIFO_CTRL_REG.word);
    if(_status.FIFO_SRC_REG.b.WTM) {
        FIFO.status=watermark;
    } else if(_status.FIFO_SRC_REG.b.EMPTY) {
        FIFO.status=empty;
    } else if(_status.FIFO_SRC_REG.b.OVR) {
        FIFO.status=overrun;
    } else {
        FIFO.status=none;
    }
    FIFO.level=_status.FIFO_SRC_REG.B.FSS;
    return FIFO.level;
}
void L3GD20::allReadOut()
{
    configReadOut();
    statusReadOut();
}
void L3GD20::configReadOut(void)
{
    read(CtrlReg1,&_config.CTRL_REG1.word);
    read(CtrlReg2,&_config.CTRL_REG2.word);
    read(CtrlReg3,&_config.CTRL_REG3.word);
    read(CtrlReg4,&_config.CTRL_REG4.word);
    read(CtrlReg5,&_config.CTRL_REG5.word);
    read(Reference,&_config.REF_DATACAP.word);
    read(FIFOCtrlReg,&_config.FIFO_CTRL_REG.word);
    read(INT1Cfg,&_config.INT1_CFG.word);
    read(INT1ThsXH,&_config.INT1_TSH_XH.word);
    read(INT1ThsXL,&_config.INT1_TSH_XL.word);
    read(INT1ThsYH,&_config.INT1_TSH_YH.word);
    read(INT1ThsYL,&_config.INT1_TSH_YL.word);
    read(INT1ThsZH,&_config.INT1_TSH_ZH.word);
    read(INT1ThsZL,&_config.INT1_TSH_ZL.word);
    read(INT1Duration,&_config.INT1_DURATION.word);
}

void L3GD20::statusReadOut(void)
{
    read(OutTemp,&_status.OUT_TEMP);
    read(StatusReg,&_status.STATUS_REG);
    read(FIFOSrcReg,&_status.FIFO_SRC_REG.word);
    read(INT1Src,&_status.INT1_SRC);
}