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.

ADS8638: channel sequencing in manual mode

Part Number: ADS8638

Hi again,

I am using the ADS8638 in "manual" channel sequencing mode, i.e. I send SPI commands to the chip to manually select a particular ADC input channel. From my microcontroller, for testing I have a continuous loop which sends commands to read particular channels. This works fine for reading 1 or 2 channels, but when I add a 3rd channel, the data that is coming back seems to be shifted. All of the SPI timing looks fine on a scope, and if I read any of the channels individually on its own, then all is fine. I only see this issue when I have sequential reads to 3 or more channels.

For example, if my code loop looks like this:

AdcData1 = Ads8638TxRx(ADS8368_SELECT_CHANNEL_1);
sprintf( buffer, "ADC ADDRESS = %x hex\tADC DATA = %x hex\n", (AdcData1 & 0xf000), (AdcData1 & 0x0fff) );
HAL_UART_Transmit(&huart3, (uint8_t *)buffer, strlen(buffer), 0xFFFF);

AdcData3 = Ads8638TxRx(ADS8368_SELECT_CHANNEL_3);
sprintf( buffer, "ADC ADDRESS = %x hex\tADC DATA = %x hex\n", (AdcData3 & 0xf000), (AdcData3 & 0x0fff) );
HAL_UART_Transmit(&huart3, (uint8_t *)buffer, strlen(buffer), 0xFFFF);

AdcData4 = Ads8638TxRx(ADS8368_SELECT_CHANNEL_4);
sprintf( buffer, "ADC ADDRESS = %x hex\tADC DATA = %x hex\n", (AdcData4 & 0xf000), (AdcData4 & 0x0fff) );
HAL_UART_Transmit(&huart3, (uint8_t *)buffer, strlen(buffer), 0xFFFF);

i.e. a read from channel 1, followed by channel 3, followed by channel 4.

What I actually get back from the chip is this:

ADC ADDRESS = 3000 hex ADC DATA = 5c4 hex
ADC ADDRESS = 4000 hex ADC DATA = a8d hex
ADC ADDRESS = 1000 hex ADC DATA = ff2 hex

ADC ADDRESS = 3000 hex ADC DATA = 5c5 hex
ADC ADDRESS = 4000 hex ADC DATA = a8d hex
ADC ADDRESS = 1000 hex ADC DATA = ff1 hex

ADC ADDRESS = 3000 hex ADC DATA = 5c5 hex
ADC ADDRESS = 4000 hex ADC DATA = a8d hex
ADC ADDRESS = 1000 hex ADC DATA = ff2 hex

So the first SPI transaction which is a read from channel 1, the return data is actually for channel 3.

And the second SPI transaction which is a read from channel 3, the return data is actually for channel 4.

And the third SPI transaction which is a read from channel 4, the return data is actually for channel 1.

Note that each address and data "pair" is correct, i.e. each ADC channel has the correct data.

Just that the order they are coming back in is not what I expect.

Here are my defines for the SPI commands I am sending:

// ADC channel manual selection, register address 0x04

#define ADS8368_SELECT_CHANNEL_0 0x800
#define ADS8368_SELECT_CHANNEL_1 0x810
#define ADS8368_SELECT_CHANNEL_2 0x820
#define ADS8368_SELECT_CHANNEL_3 0x830
#define ADS8368_SELECT_CHANNEL_4 0x840
#define ADS8368_SELECT_CHANNEL_5 0x850
#define ADS8368_SELECT_CHANNEL_6 0x860
#define ADS8368_SELECT_CHANNEL_7 0x870
#define ADS8368_SELECT_CHANNEL_TEMP_SENSE 0x801

Any suggestions please?

thanks, Nick

  • Hi Nick,
    I will look into the detail and get back to you soon, thanks.

    Best regards
    Dale
  • Hi Nick,
    Your "ADS8368_SELECT_CHANNEL_1 0x8x0" is the right address and data to write Manual Mode Register(address=04h) to select channel(e.g. 0x810 for Channel 1), but you did not show the detail about your Ads8638TxRx( ) function and I do not know how your function combine/create the final operation code and output on SDI, also I do not know what your ADC ADDRESS = 1000 is, please help to explain on these, thanks.
    Also, a timing plot (/CS,SCLK,DIN and DOUT) for a command writing will be very helpful to address the issue, thanks.

    Best regards
    Dale

  • Hi Dale,

    Thank you for your reply.

    The Ads8638TxRx( ) function is very simple, it uses the stm32 HAL library SPI function to transmit a 16-bit word over the SPI interface (on MOSI), and at the same time it reads in 16-bit receive data (on MISO, on the other clock edge).

    // ADC read/write function
    // Sends a 16-bit command to the ADC over the SPI interface
    // at the same time 16-bit data is received
    // The ADC chip select is driven manually from a GPIO, rather than from the hardware SPI peripheral

    uint16_t Ads8638TxRx(uint16_t ChannelNumber)
    {

    uint16_t SpiRxData=0;

    WRITE_REG(ADC_CS_GPIO_Port->ODR, READ_REG(ADC_CS_GPIO_Port->ODR) & ~ADC_CS_Pin); // ADC CS pin PF6 low

    if(HAL_SPI_TransmitReceive(&hspi5, (uint8_t *)&ChannelNumber, (uint8_t *)&SpiRxData, 1, SPI_TIMEOUT) != HAL_OK)
    {
    Error_Handler();
    }

    WRITE_REG(ADC_CS_GPIO_Port->ODR, READ_REG(ADC_CS_GPIO_Port->ODR) | ADC_CS_Pin); // ADC CS pin PF6 high

    return(SpiRxData);

    };

    "ADC ADDRESS = 1000 hex ADC DATA = ff2 hex" is serial debug text output that I am using to test this.
    "ADC ADDRESS" is the top 4 bits of the data that the ADC sends back (bits 15-12)
    "ADC DATA" is the lower 12 bits of the data that the ADC sends back (bits 11-0)

    You can see this is the code snippet that I already posted:

    AdcData1 = Ads8638TxRx(ADS8368_SELECT_CHANNEL_1);
    sprintf( buffer, "ADC ADDRESS = %x hex\tADC DATA = %x hex\n", (AdcData1 & 0xf000), (AdcData1 & 0x0fff) );
    HAL_UART_Transmit(&huart3, (uint8_t *)buffer, strlen(buffer), 0xFFFF);

    The 1st line is the SPI tx/rx command
    The 2nd line builds a C string that masks off the returned address and the returned data
    The 3rd line sends this C string over the serial UART for debugging.

    I will send you a timing plot tomorrow.

    regards, Nick
  • Hi Dale,

    OK, here are some scope plots.

    My control software is sending 3 commands, one after each other in this sequence (with a 1 second delay in between each one).

    AdcData1 = Ads8638TxRx(ADS8368_SELECT_CHANNEL_1); // 0x810

    AdcData3 = Ads8638TxRx(ADS8368_SELECT_CHANNEL_3); // 0x830

    AdcData4 = Ads8638TxRx(ADS8368_SELECT_CHANNEL_4); // 0x840

    You can see in the scope plots below, the read data for one channel is interleaved with the write data for another channel.

  • Hi Nick,
    I noticed that you have similar question about the same device ADS8638 in your another post on E2E which has been verified and solved, do you still have the issue with this ADC?
    e2e.ti.com/.../2845639
    Thanks&regards
    Dale
  • Hi Dale,

    The one question remains from my previous post:

    "am I correct in thinking that if we want to change from one channel to another, then we need to perform 2 cycles until we get the correct data?"

    Lets suppose we have some psuedo code that looks like this:

    SEND_COMMAND_TO_SELECT_CHANNEL_1

    SEND_COMMAND_TO_SELECT_CHANNEL_3

    SEND_COMMAND_TO_SELECT_CHANNEL_5 << WE GET CHANNEL 1 DATA HERE

    SEND_COMMAND_TO_SELECT_CHANNEL_7 << WE GET CHANNEL 3 DATA HERE

    Based on what you have said before, I believe that there is a 2 cycle delay between sending a command to change to a different channel, and the actual conversion data for that channel being available.

    Is this correct please?

    So, our pseudo code might be rewritten to look like this:



    SEND_COMMAND_TO_SELECT_CHANNEL_1

    <DUMMY SPI CYCLE 16 SCLKS>

    <DUMMY SPI CYCLE 16 SCLKS>

    READ_DATA_FOR_CHANNEL_1



    thanks, Nick
  • Hi Nick,

    Please check the timing graph I highlighted in your another query as below, your understanding is correct.

    You can use DUMMY command but it will reduce your maximum sampling rate, actually it isn't necessary because you have known the conversion data's position for each channel so your software can process these data directly or adjust them if you want.

    e2e.ti.com/.../2845808

    Regards,

    Dale

  • Thanks Dale

    I now understand the latency involved with using this converter.

    I think the datasheet could make this clearer though (it makes it clear for transitioning between manual <> auto mode, but even when you just change channels in manual mode, the same latency exists.)

    regards, Nick