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.

ADS1258 - Pulse Convert Cmd + Register Read Cmd

Other Parts Discussed in Thread: ADS1258

Dear TI,

I am in trouble with ADS1258 Pulse Convert CMD and Register Read Cmd. Maybe I am using the commands incorrectly.

I would like to read the Internal Values of ADS1258-EVM, so I have Enabled all relevant bits in SYSREG and disabled all MIXDIF and MUXSG bits. All these registers are read back in order to check the register values again.

To read the Channel Values here is my method:

private readonly byte[] _pulseConvertCmd = new byte[] { 0x80 };

public void Test()
{
            SpiInterface.Write(_pulseConvertCmd);
            channelData = RegisterDataRead(Status.ChannelID.OFFSET);
            Offset = channelData.GetOffset();
}

 public ChannelData RegisterDataRead(Status.ChannelID channelID)
        {

            byte maskbit = 0x80;
            byte[] readBuff = new byte[5];
            byte chID = 0;
            bool isSuccess = false;
            int i = 0;

            byte[] tries = new byte[StatusByteMaxPollInteration];
            StopWatch sw = new StopWatch();
            for (i = 0; i < StatusByteMaxPollInteration; i++)
            {

               
                SpiInterface.WriteRead(_registerDataRead, readBuff);
                
                chID = readBuff[1];
                chID <<= 3;
                chID >>= 3;
                tries[i] = readBuff[1];
Debug.Print(readBuff[1].ToString());

// True if NEW bit arrive and ChannelID is proper //if ((chID == (byte)channelID) && (((byte)(maskbit & readBuff[1])) == maskbit)) { isSuccess = true; break; } // Check only ChannelID if (chID == (byte)channelID) { isSuccess = true; break; } } if (!isSuccess) { throw new System.ArgumentException("Unable to Read proper value from SPI"); } prev = readBuff[1]; // Create response array byte[] dataCode = new byte[3]; int j = 0; for (i = 2; i < readBuff.Length; i++) { dataCode[j] = readBuff[i]; j++; } Status statusByte = new Status(readBuff[1]); Debug.Print("Power Supply: " + statusByte.SUPPLY.ToString()); ChannelData chData = new ChannelData(dataCode, statusByte); return chData; }

As you can see, after then I execute the PulseConvertCmd I am polling the NEW bit and ChannelID bits  in Status Byte to catch the incoming valid data.  Somehow the NEW bit missing and invalid values appear

Here is my stop condition:

  // Check only ChannelID
                if (chID == (byte)channelID) { isSuccess = true; break; }

instead of this one:

 

// True if NEW bit arrive and ChannelID is proper
                //if ((chID == (byte)channelID) && (((byte)(maskbit & readBuff[1])) == maskbit)) { isSuccess = true; break; }              

And here is my output (Status Byte in decimal representation): 

Reading Offset

Status Byte: 29 - Remaining StatusByte value (old val.)
Status Byte: 0  - ??? what is this?
Status Byte: 24 - Valid ChannelID for Offset
Status Byte: 24
Status Byte: 24
Status Byte: 24
Status Byte: 24
Status Byte: 24
Status Byte: 24
Status Byte: 24
Power Supply: False


Reading VCC
Status Byte: 24 - Last ChannelID (for Offset)
Status Byte: 181 - New bit OK, but Channel ID does not match
Status Byte: 26 - Valid ChannelID for VCC
Status Byte: 26
Status Byte: 26
Status Byte: 26
Status Byte: 26
Status Byte: 26
Status Byte: 26
Status Byte: 26
Power Supply: False


Reading Temp.
Status Byte: 26 - Last Value
Status Byte: 17 - ???? Unknown value
Status Byte: 27 - Valid Channel ID for Temp
Status Byte: 27
Status Byte: 27
Status Byte: 27
Status Byte: 27
Status Byte: 27
Status Byte: 27
Status Byte: 27
Power Supply: False


Reading Gain
Status Byte: 27
Status Byte: 224 - ??? what is this??
Status Byte: 56 - 
Status Byte: 28
Status Byte: 28
Status Byte: 28
Status Byte: 28
Status Byte: 28
Status Byte: 28
Status Byte: 28
Power Supply: False


Reading Ref
Status Byte: 28
Status Byte: 183
Status Byte: 29
Status Byte: 29
Status Byte: 29
Status Byte: 29
Status Byte: 29
Status Byte: 29
Status Byte: 29
Status Byte: 29
Power Supply: False
------------------------
Name: ADS1258
Offset: 0
Vcc: 4.5382410685221357
Temp: 21.835864921827724
Gain: 1.0007648468017578
Ref: 4.5664647420247393
-----------------------

My code has similar behavior if I am reading AI channels not for Internal channels. Unfortunately I don't have scope right now. Maybe I am using the ADS1258 Commands wrong?

Thank you for your kind reply.

  • Hi Daniel,

    I'd highly recommend looking at the SPI bus with an oscilloscope or logic analyzer to make sure your code is doing what you think it is. There are multiple places for problems to occur - for example in the SPI timing, data manipulation in code, and even the formatting of the display data.

    It looks like you mostly have your code working...You are getting what looks like reasonable values for the internal measurements (except for offset which is unlikely to be exactly zero). There is just something in the way that you pull the status byte that gives you invalid data for the first few reads.

    Also, I don't see where you are reading form the device registers. It looks like you are only reading data.

    A few observations about the code:

    • You don't seem to be waiting for /DRDY to go low. It would be better to wait for a /DRDY interrupt to trigger your data read operation so that you know when the conversion has completed. By polling, you don't know when the conversion completes. It is possible to get invalid data if you are reading the data when the conversion completes because the output buffer is updating while you are reading it.

    • These operations could be causing problems.
      Daniel Vamos said:
      chID <<= 3; chID >>= 3;

      Your compiler might ignore these data operations altogether. It would be better to mask the result by ANDing with 0x1F.


    • What command are you sending here?
      Daniel Vamos said:
      SpiInterface.WriteRead(_registerDataRead, readBuff);

      If this is the "channel data read direct" command then you will need to toggle chip select after reading the data, or allow the SPI interface to reset.


    Regards,
    Chris

  • Dear Chris,

    Thank you very much for your always detailed answers. Your suggestions helps me a lot, so I have made a new test to read out the proper channel values.

    • Based on your first suggestion I have connected the DRDY pin. Right now I am sending out the Pulse convert command and than start to poll the DRDY digital input pin for incoming data. In this way I can avoid the concurrency of register R/W operations. 
    • I have commented out the doubtful statement.

    And my values after spi read still unstable .

    I suppose in this way, the NEW bit must be 1 every time when I read out the data. ( And should be 'cause the DRDY pin is High.) So I have to investigate my built in SPI methods whit a scope... 

    Would you mind explain your statement a bit more: If this is the "channel data read direct" command then you will need to toggle chip select after reading the data, or allow the SPI interface to reset.

    Are you pointing the Figure 58. on the ADS1258 datasheet? So, I have to tie down the CS during the communication then tie up when I am ready?

  • Hi Daniel,

    Daniel Vamos said:
    I suppose in this way, the NEW bit must be 1 every time when I read out the data. ( And should be 'cause the DRDY pin is High.) So I have to investigate my built in SPI methods whit a scope... 

    /DRDY is active low. Therefore, you need to wait until /DRDY is low before reading the data (or use an interrupt to trigger a data read on the falling edge of /DRDY).


    In general, if /DRDY is high the conversion has not completed. /DRDY goes low when the conversion completes and returns high after you start reading data (Refer to page 25 of theADS1258 datasheet).

    Daniel Vamos said:
    Would you mind explain your statement a bit more: If this is the "channel data read direct" command then you will need to toggle chip select after reading the data, or allow the SPI interface to reset.

    This is an ADS1258 quirk. You must toggle /CS (or wait for the SPI interface to timeout after you send the "channel data read direct" command (0x00).

    Daniel Vamos said:
    Are you pointing the Figure 58. on the ADS1258 datasheet? So, I have to tie down the CS during the communication then tie up when I am ready?

    /CS should be controlled by a GPIO pin. Sometimes GPIO pins are not available and /CS is tied (permanently connected) to ground.

    If you use a GPIO pin to control /CS, then you will need to assert it (take it high for 2*tCLK), and then bring it low again (and wait 2.5*tCLK) before you can send another SPI command.

    In the case you have connected /CS to ground, you have to wait for the SPI interface to timeout before you can send another SPI command.

    I hope that helps to clarify my previous post!

    Regards,
    Chris

  • Dear Chris,

    I have updated my code again focusing on SPI configuration. I had an option in SPI to set  the ClockIdleHigh = True then everything works fine. Right now, I am polling DRDY pin for becoming low then execute the RegisterReadCommand. 

    Every time the read results valid data, and the NEW bit is always 1. It is perfect! I would say the SPI is working well for now.

    But, somehow randomly the DRDY never arrives, I mean does not go Low . I made several tests and randomly for example 43.425th iteration or 1340th iteration the DRDY doesn't arrive.

    Should I use any additional pullup resistor? I don't have any idea what the problem is. 

    I am wondering to use a TI launchpad between my Netmf device and ADS1258. I think most of this issues can be handled easily such as timing, interrupt handling and using multiple ADS1258. Could you suggest me a good one?

  • Hi Daniel,

    If you don't see /DRDY go low, it is most likely because the ADS1258 is not converting. Perhaps your pulse convert command occasionally is not being received correctly.

    I am curious why changing the SPI mode to clock idle high (CPOL = 1) would improve your communication. The ADS1258 is intended to use CPOL = 0, or clock idle low.

    Double check that the SPI clock edge is configured correctly. (The ADS1258 uses CPHA = 0, or the rising edge of SCLK). Changing CPOL may affect the clock edge your MCU uses to latch data on the SPI bus:

    Regards,
    Chris

  • Dear Chis, 

    Could you tell me what is the recommended clock speed for SPI in kHz?

    The logic analyzer is on its way, I have recently ordered one and I will post some results as it arrives. Thank you very much for your help!

  • HI Daniel,

    SCLK can be up to half the speed of the ADS1258's master clock:

    If you uses a 32.768kHz crystal oscillator, the ADS1258's PLL will generate a 15.729 MHz master clock. In this case SCLK can be 7.729 MHz.

    If you apply the external clock to the CLKIO pin, SCLK must be 1/2 the frequency of this external clock.

    As far as a minimum SCLK speed, keep in mind you want to read out the data before the next conversion completes. Most people will use the maximum SCLK frequency; however, SCLK should be at least ~50x times faster than your data rate. It should allow sufficient time to send the read command, clock out 24-bits of data, clock out 8-bits (for the status byte), and have some extra time left over for MCU delays.

    Best Regards,
    Chris

  • Dear Chris,

    This was the key for my problem. I have been using SPI 16MHz instead of the recommended speed. For now, it works very well with Active Low SPI Clock state. At night I ran a test over 40Million readout without any problem.

    Thank you so much for you kind help!!!

  • Hi Daniel,

    That's great news! I'm glad it's working for you!!

    Thanks for posting your fix!

    Best Regards,
    Chris