This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

ads7866idbvt ADC

Other Parts Discussed in Thread: ADS7866

Hi,

We have got ads7866 idbvt adc which we have connected to freescale's imx6Q processor through SPI. Now we are trying to get voltage(analog) value and display it. But it is giving Result is: 0 when we have connected 3.6V to respective Vin. Why is this so????? Please find our programs as attached

####ads7866Spi.h

#ifndef ADS7866SPI_H
    #define ADS7866SPI_H
#include <unistd.h>
#include <stdint.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/spi/spidev.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string>
#include <iostream>

class ads7866Spi{

public:
    ads7866Spi();
    ads7866Spi(std::string devspi, unsigned char spiMode, unsigned int spiSpeed, unsigned char spibitsPerWord);
    ~ads7866Spi();
    int spiWriteRead( unsigned char *data, int length);

private:
    unsigned char mode;
    unsigned char bitsPerWord;
    unsigned int speed;
    int spifd;

    int spiOpen(std::string devspi);
    int spiClose();

};

#endif

###ads7866Spi.c

#include "ads7866Spi.h"
using namespace std;
/**********************************************************
 * spiOpen() :function is called by the constructor.
 * It is responsible for opening the spidev device
 * "devspi" and then setting up the spidev interface.
 * private member variables are used to configure spidev.
 * They must be set appropriately by constructor before calling
 * this function.
 * *********************************************************/
int ads7866Spi::spiOpen(std::string devspi){
    int statusVal = -1;
    this->spifd = open(devspi.c_str(), O_RDWR);
    if(this->spifd < 0){
        perror("could not open SPI device");
        exit(1);
    }

    statusVal = ioctl (this->spifd, SPI_IOC_WR_MODE, &(this->mode));
    if(statusVal < 0){
        perror("Could not set SPIMode (WR)...ioctl fail");
        exit(1);
    }

    statusVal = ioctl (this->spifd, SPI_IOC_RD_MODE, &(this->mode));
    if(statusVal < 0) {
      perror("Could not set SPIMode (RD)...ioctl fail");
      exit(1);
    }

    statusVal = ioctl (this->spifd, SPI_IOC_WR_BITS_PER_WORD, &(this->bitsPerWord));
    if(statusVal < 0) {
      perror("Could not set SPI bitsPerWord (WR)...ioctl fail");
      exit(1);
    }

    statusVal = ioctl (this->spifd, SPI_IOC_RD_BITS_PER_WORD, &(this->bitsPerWord));
    if(statusVal < 0) {
      perror("Could not set SPI bitsPerWord(RD)...ioctl fail");
      exit(1);
    }

    statusVal = ioctl (this->spifd, SPI_IOC_WR_MAX_SPEED_HZ, &(this->speed));
    if(statusVal < 0) {
      perror("Could not set SPI speed (WR)...ioctl fail");
      exit(1);
    }

    statusVal = ioctl (this->spifd, SPI_IOC_RD_MAX_SPEED_HZ, &(this->speed));
    if(statusVal < 0) {
      perror("Could not set SPI speed (RD)...ioctl fail");
      exit(1);
    }
    return statusVal;
}

/***********************************************************
 * spiClose(): Responsible for closing the spidev interface.
 * Called in destructor
 * *********************************************************/

int ads7866Spi::spiClose(){
    int statusVal = -1;
    statusVal = close(this->spifd);
        if(statusVal < 0) {
      perror("Could not close SPI device");
      exit(1);
    }
    return statusVal;
}

/********************************************************************
 * This function writes data "data" of length "length" to the spidev
 * device. Data shifted in from the spidev device is saved back into
 * "data".
 * ******************************************************************/
int ads7866Spi::spiWriteRead( unsigned char *data, int length){

  struct spi_ioc_transfer spi[length];
  int i = 0;
  int retVal = -1;

// one spi transfer for each byte

  for (i = 0 ; i < length ; i++){

    spi[i].tx_buf        = (unsigned long)(data + i); // transmit from "data"
    spi[i].rx_buf        = (unsigned long)(data + i) ; // receive into "data"
    spi[i].len           = sizeof(*(data + i)) ;
    spi[i].delay_usecs   = 0 ;
    spi[i].speed_hz      = this->speed ;
    spi[i].bits_per_word = this->bitsPerWord ;
    spi[i].cs_change = 0;
}

 retVal = ioctl (this->spifd, SPI_IOC_MESSAGE(length), &spi) ;

 if(retVal < 0){
    perror("Problem transmitting spi data..ioctl");
    exit(1);
 }

return retVal;

}

/*************************************************
 * Default constructor. Set member variables to
 * default values and then call spiOpen()
 * ***********************************************/

ads7866Spi::ads7866Spi(){
    this->mode = SPI_MODE_0 ;
    this->bitsPerWord = 8;
    this->speed = 1000000;
    this->spifd = -1;

    this->spiOpen(std::string("/dev/spidev2.0"));

    }

/*************************************************
 * overloaded constructor. let user set member variables to
 * and then call spiOpen()
 * ***********************************************/
ads7866Spi::ads7866Spi(std::string devspi, unsigned char spiMode, unsigned int spiSpeed, unsigned char spibitsPerWord){
    this->mode = spiMode ;
    this->bitsPerWord = spibitsPerWord;
    this->speed = spiSpeed;
    this->spifd = -1;

    this->spiOpen(devspi);

}

/**********************************************
 * Destructor: calls spiClose()
 * ********************************************/
ads7866Spi::~ads7866Spi(){
    this->spiClose();
}

###main.c

#include "ads7866Spi.h"

using namespace std;

int main(void)
{
    ads7866Spi a2d("/dev/spidev2.0", SPI_MODE_0, 1000000, 8);
    int i = 20;
        int a2dVal = 0;
    int a2dChannel = 0;
        unsigned char data[3];

    while(i > 0)
    {
        data[0] = 1;  //  first byte transmitted -> start bit
        data[1] = 0b10000000 |( ((a2dChannel & 7) << 4)); // second byte transmitted -> (SGL/DIF = 1, D2=D1=D0=0)
        data[2] = 0; // third byte transmitted....don't care

        a2d.spiWriteRead(data, sizeof(data) );

        a2dVal = 0;
                a2dVal = (data[1]<< 8) & 0b1100000000; //merge data[1] & data[2] to get result
                a2dVal |=  (data[2] & 0xff);
        sleep(1);
        cout << "The Result is: " << a2dVal << endl;
        i--;
    }
    return 0;
}

###Makefile 

CC = g++
INCLUDES = -I ../..

all:
    $(CC) $(INCLUDES) ads7866SpiTest.cpp ads7866Spi.cpp -o ads7866SpiTest

clean:
    rm ads7866SpiTest

  • Hi SrinivasaRao,
    Thank you for your post. Can you please upload your screenshot by scope for SCLK/SDO and /CS signals here? It will be helpful to upload your schematic together, thanks.

    Regards
    Dale
  • Hi,

    Thanks for the reply...I have attached schemtic and will attach signals later  (once probing is done)... By the way is the programs and logic used is correct or not... 

    I would like to the know the validity of programs (whether logic used is correct or not)????

  • Hi SrinivasaRao,
     Sorry modified, after checked your schematic and program:
    1. It needs 16 clocks to get the data, not 8 in the program.
    2. SPI should work at CPOL = 1, CPHA = 1 mode.

    3. ADS7866 can only support 200ksps sampling rate,I'm not sure 1MHz speed is your SCLK frequency or sampling rate in program, please check.
    4. VIN input should be driven with a low impedance source, if not, a buffer would help to achieve the rated performance of the converter.
    5. Because reference voltage is derived from the supply voltage internally, so a low noise/ripple and low impedance supply source is expected. A reference or buffered output can be used for power supply(more details can be refered to datasheet for this device or the family).

    It will be better to check the timing with screenshot for these SPI signals. Thanks.

      
    Regards
    Dale