Mario Poneder / ADC_AD7190

AD7190.cpp

Committer:
MarioPoneder
Date:
2014-01-28
Revision:
2:dc4217ca1fff
Parent:
1:00d6e45e037a

File content as of revision 2:dc4217ca1fff:

#include "AD7190.h"

/***************************************************************************//**
 * @brief Creates an instance of the AD7190 class. This class is designed
 *        for single slave operation. Therefore no chip-select pin is required.
 *
 * @param rdy   RDY (DOUT/RDY)
 * @param mosi  DIN
 * @param miso  DOUT (DOUT/RDY), must be a different pin than rdy.
 * @param sclk  SCLK
*******************************************************************************/
AD7190::AD7190(PinName rdy, PinName mosi, PinName miso, PinName sclk)
    : _rdy(rdy), _rdyInt(rdy), _spi(mosi, miso, sclk)
{
    ;
}

/***************************************************************************//**
 * @brief This interrupt routine gets called after every finished conversion
 *        in continous read mode. It reads 4 bytes of data, the sample takes
 *        3 bytes and the status register 1 byte.
 *        Moreover the sample callback function gets called.
 *
 * @return None, because this is an interrupt routine.
*******************************************************************************/
void AD7190::SampleInterrupt(void)
{
    static unsigned long buffer;
    static unsigned char i;
    this->_rdyInt.fall(NULL);
    for(i = 1; i <= 4; i++) {
        buffer = (buffer << 8) + _spi.write(0x00);
    }
    this->sampleCallbackFunction(buffer >> 8, buffer & 0x07);
    this->_rdyInt.fall(this, &AD7190::SampleInterrupt);
}

/***************************************************************************//**
 * @brief Starts the interrupt-driven sampling process and sets the AD7190's
 *        continuous read mode flag.
 *
 * @param sampleCallbackFunction    Pointer to the sample callback function.
 *                                  Example prototype:
 * @code void SampleCallback(unsigned long data, unsigned char channel); @endcode
 *
 * @return None.
*******************************************************************************/
void AD7190::StartContinuousRead(pSampleCallback_t sampleCallbackFunction)
{
    this->sampleCallbackFunction = sampleCallbackFunction;
    this->WaitRdyGoLow();
    this->_spi.write(COMM_READ | COMM_CREAD | COMM_ADDR(REG_DATA));
    this->_rdyInt.fall(this, &AD7190::SampleInterrupt);
}

/***************************************************************************//**
 * @brief Stops the interrupt-driven sampling process and disables the AD7190's
 *        continuous read mode.
 *
 * @return None.
*******************************************************************************/
void AD7190::StopContinuousRead(void)
{
    this->_rdyInt.fall(NULL);
    this->WaitRdyGoLow();
    this->_spi.write(COMM_READ | COMM_ADDR(REG_DATA));
}

/***************************************************************************//**
 * @brief Writes the specified contents to the specified on-chip register.
 *
 * @param registerAddress   Address of the register.
 * @param registerValue     Contents to write.
 *
 * @return None.
*******************************************************************************/
void AD7190::SetRegisterValue(unsigned char registerAddress, unsigned long registerValue)
{
    static unsigned char *dataPointer, bytesNr;
    dataPointer = (unsigned char*)&registerValue;
    
    switch(registerAddress) {
        case REG_ID:
        case REG_GPOCON:
            bytesNr = 1;
            break;
        case REG_MODE:
            dataPointer += 2;
        case REG_CONF:
            registerValue |= (1 << 19);
        case REG_OFFSET:
        case REG_FULLSCALE:
            bytesNr = 3;
            break;
        default:
            bytesNr = 0;
    }

    this->_spi.write(COMM_WRITE | COMM_ADDR(registerAddress));
    for(; bytesNr > 0; bytesNr--) {
        this->_spi.write(*dataPointer);
        registerAddress == REG_MODE ? dataPointer -- : dataPointer ++;
    }
}

/***************************************************************************//**
 * @brief Reads the contents of the specified on-chip register.
 *
 * @param registerAddress   Address of the register.
 *
 * @return Contents of the register.
*******************************************************************************/
unsigned long AD7190::GetRegisterValue(unsigned char registerAddress)
{
    static unsigned long buffer = 0;
    static unsigned char bytesNr, i;

    switch (registerAddress) {
        case REG_STAT:
        case REG_ID:
        case REG_GPOCON:
            bytesNr = 1;
            break;
        case REG_MODE:
        case REG_CONF:
        case REG_DATA:
        case REG_OFFSET:
        case REG_FULLSCALE:
            bytesNr = 3;
            break;
        default:
            bytesNr = 0;
    }

    this->_spi.write(COMM_READ | COMM_ADDR(registerAddress));
    for(i = 1; i <= bytesNr; i++) {
        buffer = (buffer << 8) + _spi.write(0x00);
    }
    return buffer;
}

/***************************************************************************//**
 * @brief Initialises the SPI bus, resets the AD7190 and checks if it is
 *        responding.
 *
 * @return True, if the ADC is respondig
*******************************************************************************/
bool AD7190::Init(void)
{
    unsigned char regVal;

    this->_spi.format(8, 3);
    this->_spi.frequency(10000000);
    this->Reset();
    wait_ms(1);
    regVal = this->GetRegisterValue(REG_ID);

    return (regVal & ID_MASK) == ID_AD7190 ;
}

/***************************************************************************//**
 * @brief Resets the AD7190.
 *
 * @return None.
*******************************************************************************/
void AD7190::Reset(void)
{
    static unsigned char i;
    this->_spi.write(0x01);
    for(i = 0; i < 6; i++) {
        this->_spi.write(0xFF);
    }
}

/***************************************************************************//**
 * @brief Waits for the RDY (DOUT/RDY) pin to go low.
 *
 * @return None.
*******************************************************************************/
void AD7190::WaitRdyGoLow(void)
{
    for(; this->_rdy;);
}