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.

ADS8689: Understanding SPI Commands

Part Number: ADS8689

Hi! First, greetings to everyone!

It's probably simple but I'm having a bit of trouble understanding the notation used by TI in the ADS8689 datasheet.

1) OPCODE should be 32-bit long [31:0] but the NOP example shows a stream of 33 zeroes because of the 9 bit address, so how does it work?

I suppose we don't have to send an extra byte for that one bit. I've read the note about it below the table but still didn't get it.

2)What do the X and the underscore mean? For example, the READ_HWORD command:

11001_xx_<9-bit address>_00000000_00000000

I suppose the X means "don't care".

The 3 last underscores just separate the bytes, but what about the first one (_xx)? Is it a delay, should we pull CS high, another "don't care"?

  • Hi Victor,

    Thanks for your query on E2E forum.

    1) 33 zeros for NOP is the table 5 is an error in the datasheet, the NOP should be 32 zeros, this should be fixed when the datasheet is updated next time.

    2) Your understanding about the "x" is correct, it can be either "0" or "1".

    Also, all "x" in the OPCODE can be either "0" or "1". All "_" underscores are just used to make the OPCODE clear to understand, there is no delay when you send the command fro your controller to the ADC. The /CS should be kept low during the whole frame.

    Best regards

    Dale

  • Can you shed some light on how I should be invoking these commands work? Should I be sending the 5 bit command then the address and 2 chunks of 0's? I'm also not sure what 9 bit addresses to use? To target the range select would it just be 0x14?  

  • Hi!

    It's a bit confusing, but I managed to get it to work properly thanks to this library https://github.com/Helmuthn/ads8689_Arduino/blob/master/ADC_ads8689.cpp

    You send 4 bytes. 7-bit command <<1  & 0 in the 1st, 8-bit register address from Table 10 in 2nd byte and 16-bit data in 3rd and 4th. The leading 0 and the 8-bits form the 9 bit address.

    This test was suggested by a TI engineer in another thread: to change the ADC's input range to +/-0.625*Vref, use the code D0 14 0004

    If you use Helmuthn's library, the command is:
    adc->transmit(ADS8689_WRITE_FULL,ADS8689_RANGE_SEL_REG,0x0004);

    With input floating and default range you should get a reading of about 36000 and with +-0.625Vref you will get about 53000.

    Hope this helps,

    Vitor.

  • I've actually been trying to use that library. I'm sure that everything is powered correctly. I don't get those readings on my setup. Below is my code and my connections are as follows :

    uC        <>       ADC

    SCLK              SCLK (PIN 12)

    MOSI              SDI(PIN 10)

    MISO              SDO(PIN 13) *I also have a pullup on this*

    CS                  CS(PIN 11)

    #include <ADC_ads8689.h>
    
    const int CS_PIN = 10;
    
    ADC_ads8689 adc = ADC_ads8689(32, 10);
    
    void setup() {
      Serial.begin(9600);
    
      adc.transmit(ADS8689_WRITE_FULL  , ADS8689_RANGE_SEL_REG , 0x0004);
      
      uint8_t  bufferItems = adc.inputAvailable();
      
      Serial.print("Buffer items = ");
      Serial.println(bufferItems,DEC);
      
      uint32_t result = adc.readBuffer();
      
      Serial.print("Results in DEC IS : ");
      Serial.println(result,DEC);
      Serial.print("Results in BINARY IS : ");
      Serial.println(result,BIN);
    }

    The outputs from that code after running it a couple of times is below which each value being a new run and read.

    Buffer items = 1
    Results in DEC IS : 0
    Results in BINARY IS : 0


    Buffer items = 1
    Results in DEC IS : 447741962


    Results in BINARY IS : 11010101100000000000000001010
    Buffer items = 1
    Results in DEC IS : 447741962
    Results in BINARY IS : 11010101100000000000000001010


    Buffer items = 1
    Results in DEC IS : 16777220
    Results in BINARY IS : 1000000000000000000000100


    Buffer items = 1
    Results in DEC IS : 176160784
    Results in BINARY IS : 1010100000000000000000010000


    Buffer items = 1
    Results in DEC IS : 41943048
    Results in BINARY IS : 10100000000000000000001000


    Buffer items = 1
    Results in DEC IS : 16777220
    Results in BINARY IS : 1000000000000000000000100

  • Hi David, Victor,

    There are detailed description on TI.com, please refer to the previous queries and answers on the E2E forum:

    ADS8691:  how to read register value of bit[0:15]

    ADS8689: 32 bits register reading command sequence

    After you determine which register you want to read or write, you can confirm the register address, then you can combine the commands and register address together to form a 32-bit opcode, thus you can send two 16-bit opcodes or four 8-bit opcodes to the ADC to implement the operation.

    Here is an example to use READ_HWORD command to read the 16-bit of ALARM_H_TH_REG Register:

    (Byte 0 Address for bits 7-0 = 24h, Byte 1 Address for bits 15-8 = 25h, Byte 2 Address for bits 23-16 = 26h, Byte 3 Address for bits 31-24 = 27h)

    1. Use Read_HWORD command to read the 16-bit (0~15 bit) of register:          <11001_xx> <0_0010_0100><00000000><00000000>
    2. Use Read_HWORD command to read the 16-bit (16~31 bit) of register:        <11001_xx> <0_0010_0110><00000000><00000000>

    Hence, when you configure the ADC's input range to +/-2.5Vref and also enable internal reference, you can program the Range_SEL_REG register by using the Half-word WRITE command with address=14h:

    <11010_00> <0_0001_0100><00000000><00000001> 

    I hope this is helpful for you to understand.

     

    Best regards,

    Dale

  • But if I use READ_HWORD and look at that register it keeps changing every read even if I am not writing any new values to that register.

  • Let me explain a little bit more. Here is the series of things i'm doing.

    1. Pulling the CS pin LOW
    2. Sending the  Read_HWORD to the ALARM_H_TH_REG Register - <11001_00> <0_0010_0100><00000000><00000000>
    3. Setting the CS pin HIGH
    4. Setting the CS pin LOW
    5. Sending the  Read_HWORD to the ALARM_H_TH_REG Register 2nd byte address - <11001_00> <0_0010_0110><00000000><00000000>
    6. Storing the SDO result
    7. Setting the CS pin HIGH
    8. Printing out that result

    I'm getting different results every run. Below are a few.

    10000000010000000000000000001000


    10000101000100000000000000000010


    10010000100011000000000000000011


    10000110000010000000000000000100


    10011010000000000000000000001000


    10000011001000000000000000000100

  • Hi David,

    Can you please provide the timing plots for SPI bus captured by an oscilloscope? thanks.

    Best regards,

    Dale