Tool/software: Linux
/*---------------------------------------------------------------------------- Function : ADCChannelValue Inputs : i2c string- i2c device address to open /dev/i2c-2 highbuff - higher value from datasheet lowbuff - lower register value from datasheet pin_no - Processing : Read value from specified ADC pin by taking ADC channel parameters as input. Outputs : ADC channel voltage value (0V-12.5V) Returns : float Notes : None ----------------------------------------------------------------------------*/ float ADCChannelValue(int highbuff,int lowbuff, int pin_no) { int SPIfd=0; int SPIreturn=0; float ADCvalue=0.0; uint8_t upperByte_ADC; uint8_t lowerByte_ADC; struct spi_ioc_transfer transferspi = { .tx_buf = (unsigned long)txspi, .rx_buf = (unsigned long)rxspi, .len = ARRAY_SIZE(txspi), .delay_usecs = delaysec, .speed_hz = speed, .bits_per_word = bits, }; // Open and setup SPI 0.0 SPIfd =SPIsetup("/dev/spidev0.0"); // Write ADC mux configuration reg-0 txspi[0]=0x00; txspi[1]=0x13; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } usleep(2000); // Write ADC mux configuration reg-1 txspi[0]=0x00; txspi[1]=0x14; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } usleep(2000); // Write ADC mux configuration reg-2 txspi[0]=0x00; txspi[1]=0x15; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } usleep(2000); // Write ADC configuration registor // ADC conversion mode : direct mode (0) // conversion rate (00) // ADC reference buffers enabled txspi[0]=0x00; txspi[1]=0x10; txspi[2]=0x10; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } usleep(2000); // Power Down Mode Registor configuration txspi[0]=0x00; txspi[1]=0xB4; txspi[2]=0x03; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } usleep(2000); // ADC trigger Registor set bit 0 to start ADC conversion Internally txspi[0]=0x00; txspi[1]=0xC0; txspi[2]=0x01; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } usleep(2000); // status register read which indicate ADC idle and ADC Data available flag txspi[0]=0x80; txspi[1]=0x72; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); usleep(2000); // status register read which indicate ADC idle and ADC Data available flag txspi[0]=0x80; txspi[1]=0x72; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); usleep(2000); // status register read which indicate ADC idle and ADC Data available flag txspi[0]=0x80; txspi[1]=0x72; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); usleep(2000); // Read value from ADC Data Registor // Registor contains Higher Byte code of ADC channel txspi[0]=0x80; txspi[1]=highbuff; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } else { upperByte_ADC=rxspi[2]; printf(" Upper byte=%d\n",upperByte_ADC); } //printf("Sent to adc - 0x%02X. 0x%02X. 0x%02X.\n",txspi[0],txspi[1],txspi[2]); //printf("Read from adc - 0x%02X. 0x%02X. 0x%02X.\n",rxspi[0],rxspi[1],rxspi[2]); usleep(2000); // Registor contains Lower Byte code of ADC channel txspi[0]=0x80; txspi[1]=lowbuff; txspi[2]=0xFF; SPIreturn = ioctl(SPIfd, SPI_IOC_MESSAGE(1), &transferspi); if (SPIreturn < 1) { pabort("can't send spi message"); } else { lowerByte_ADC=rxspi[2]; //printf(" Lower byte=%d\n",lowerByte_ADC); } //printf("Sent to adc - 0x%02X. 0x%02X. 0x%02X.\n",txspi[0],txspi[1],txspi[2]); //printf("Read from adc - 0x%02X. 0x%02X. 0x%02X.\n",rxspi[0],rxspi[1],rxspi[2]); if(pin_no<=15) { // ADCconversiontoFloat defined in amc7836.h ADCvalue=ADCconversiontoFloat(upperByte_ADC, lowerByte_ADC); } else if(pin_no<=20) { // ADCconversiontoFloat defined in amc7836.h ADCvalue=LVADCconversiontoFloat(upperByte_ADC, lowerByte_ADC); } else if(pin_no==21) { // ADCconversiontoFloat defined in amc7836.h ADCvalue=TempADCconversiontoFloat(upperByte_ADC, lowerByte_ADC); } SPIclose(SPIfd); return (ADCvalue); }
Please find code and schematic that we have on our custom board above.
The Same piece of code function is working with SPI and returning Results of ADC data very nicely on AMC7836EVM.
But when we run same function call on our custom board with ADC 7836 chip on it, always returns 0F(Higher ADC code ) FF(Lower ADC code) which equivalent to 12.5V for Bipolar and 5V for unipolar.
We have debugged the every possibility but not able to find any difference that leads to these wrong ADC readings on AMC7836 chip.
Please suggest if We have to set any other registers or we have to make certain hardware configurations that will results in the same results as on AMC7836EVM
Note: High buffer and low buffer bytes are Buffer register to pass on SPI..for e.g ADC channel 0 high=0x21 Low =0x20