Mario Poneder / ADC_AD7190
Revision:
0:49fe1d7a6628
Child:
1:00d6e45e037a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/AD7190.cpp	Tue Jan 28 09:42:48 2014 +0000
@@ -0,0 +1,196 @@
+/***************************************************************************//**
+ * @file   AD7190.cpp
+ * @brief  Implementation of the AD7190 driver.
+ * @author Mario Poneder
+ * @date   28/01/2013
+ *
+ * This class is based on the implementation from Dan Nechita (Analog Devices).
+*******************************************************************************/
+
+/******************************************************************************/
+/***************************** Include Files **********************************/
+/******************************************************************************/
+#include "AD7190.h"
+
+/***************************************************************************//**
+ * @brief Constructs the AD7190 class. This library 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, which has to to take the
+ *        parameters 'data' and 'channel', 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,
+ *                                  which has to to take the parameters 'data'
+ *                                  and 'channel'.
+ *
+ * @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;);
+}