• TI Thinks Resolved

ADS131A04: ADS131A04: Synchronous Slave Mode configuration unable to get ADC data.

Part Number: ADS131A04

Hi,

I am using ADS131A04 ADC in synchronous slave mode with the following configuration.

M0: Floating, sync slave mode.

M1: Gnd, 24 bit configuration.

M2: Gnd, Hamming code off.

I am able to configure and read response of each command and register as specified in the data sheet. But after enabling the all four ADC, I am not getting the ADC data.

During configuration my D_SYS_CFG[0]=0 (CRC disabled)_CFG[1] = 0 (Dynamic frame size), and all four ADC are enabled. Hence, while reading ADC data I am reading 20 bytes of data (4 byte Status Response and 4*4 bytes for Channel Data).

On Power on reset the registers are getting configured, but the Status response read takes time to settle to 0x22000000 shown below in the data log.

The logged ADC configuration and ADC data is shown below:-

* All responses are 32 bit hex.
ADC First Test Program!!!!

Reset Register Response: ff0400ff

Unlock Command Respone: 65500ff

STAT_1 Register Response: 220000ff

STAT_N Register Response: 240000ff

STAT_S Register Response: 250000ff

STAT_M2 Register Response: 270200ff

A_SYS_CFG Register Response: 2b6000ff

D_SYS_CFG Register Response: 2c3c00ff

CLK1 Register Response: 2d0800ff

CLK1 Register Response: 2d0200ff

CLK2 Register Response: 2e2600ff

ADC_ENA Register Response: 2f0f0000

Wakeup Command Respone: 330000

Lock Command Respone: 5550000

ADS131A04_data_log.txt

  • Anshul,

    Welcome to the E2E forum. We are looking through your response and should have a follow-up reply by tomorrow.

    Regards,
    Collin Wells
    Precision ADC Applications

  • Hello Anshul,

    Welcome to our forum and thank you for your post!

    Anshul Basra
    while reading ADC data I am reading 20 bytes of data (4 byte Status Response and 4*4 bytes for Channel Data).

    Are you really using 24-bit mode? You only need to send 3 bytes per SPI word when M1 = GND. Therefore, in order to read the data from all four channels, you will need a total of 15 bytes: one word for STATUS and another word for each channel.

    Anshul Basra
    the Status response read takes time to settle to 0x22000000 shown below in the data log.

    Are you sending the NULL command in the frame prior to each of the STATUS responses shown in your data log? Please review the STAT_1 register contents when you send the NULL command. Some of the error messages indicated by the STATUS responses in your data log indicate that you had an SPI fault, which would be explained by my previous comments. Other responses do not make sense, which may indicate that there was an SPI transmission error due to an incorrect number of SCLKs per frame.

    Best Regards,


    Ryan Andrews

    Precision ΔΣ ADCs

  • In reply to Ryan Andrews:

    Yes I am using Null Command to read back status response of each register setting and command sent for configuration of ADC.

    I have made the function definition such that I send 32 bit Commands to the ADC. And as mentioned the status of the present command is available on the next frame I read the response using the Null Command.

    As told by you now I am reading the 15 bytes of data (3 bytes status response, 3 bytes * 4 Channel data = 12 bytes). Still I am not getting the data from the ADC. All Channel data is zero and status response is 0x2200.

    I am sharing how I am configuring my ADC and Reading my data on microcontroller.

    /* USER CODE BEGIN 2 */
    printf("ADC First Test Program!!!!\n");

    ResetCommand(GPIOA, GPIO_PIN_4);
    printf("Reset Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    DevIdCommand(GPIOA, GPIO_PIN_4);

    //printf("Ready Command Respone: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    //Wait Until Device Ready............
    while(((NullCommand(GPIOA, GPIO_PIN_4)) & 0xFFFF0000) != 0xFF040000){}

    UnlockCommand(GPIOA, GPIO_PIN_4);
    printf("Unlock Command Respone: %x\n",NullCommand(GPIOA, GPIO_PIN_4));

    readRegisterCommand(GPIOA, GPIO_PIN_4, STAT_1);
    printf("STAT_1 Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    readRegisterCommand(GPIOA, GPIO_PIN_4, STAT_N);
    printf("STAT_N Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    readRegisterCommand(GPIOA, GPIO_PIN_4, STAT_S);
    printf("STAT_S Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    readRegisterCommand(GPIOA, GPIO_PIN_4, STAT_M2);
    printf("STAT_M2 Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    readRegisterCommand(GPIOA, GPIO_PIN_4, A_SYS_CFG);
    printf("A_SYS_CFG Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    //writeRegisterCommand(GPIOA, GPIO_PIN_4, D_SYS_CFG, 0x3F);
    readRegisterCommand(GPIOA, GPIO_PIN_4, D_SYS_CFG);
    printf("D_SYS_CFG Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    readRegisterCommand(GPIOA, GPIO_PIN_4, CLK1);
    printf("CLK1 Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    writeRegisterCommand(GPIOA, GPIO_PIN_4, CLK1, 0x02);
    printf("CLK1 Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));
    writeRegisterCommand(GPIOA, GPIO_PIN_4, CLK2, 0x26);
    printf("CLK2 Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));

    writeRegisterCommand(GPIOA, GPIO_PIN_4, ADC_ENA, 0x0F);
    printf("ADC_ENA Register Response: %x\n", NullCommand(GPIOA, GPIO_PIN_4));

    WakeupCommand(GPIOA, GPIO_PIN_4);

    printf("Wakeup Command Respone: %x\n",NullCommand(GPIOA, GPIO_PIN_4));
    LockCommand(GPIOA, GPIO_PIN_4);
    printf("Lock Command Respone: %x\n",NullCommand(GPIOA, GPIO_PIN_4));

    /* USER CODE BEGIN WHILE */

    while (1)
    {
    /* USER CODE END WHILE */
    printf("\n************Loop Start***********\n");
    DRDY_status = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0);
    DONE_status = HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_1);
    printf("DRDY Status: %x\n", DRDY_status);

    // Read Data

    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS Low
    HAL_SPI_Receive(&hspi1, rx_data, 15, 200);
    // HAL_Delay(500);
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET); // CS HIGH

    uint32_t status_response = rx_data[0]<<16 | rx_data[1]<<8 | rx_data[2];
    uint32_t ch0 = rx_data[3]<<16 | rx_data[4]<<8 | rx_data[5];
    uint32_t ch1 = rx_data[6]<<16 | rx_data[7]<<8 | rx_data[8];
    uint32_t ch2 = rx_data[9]<<16 | rx_data[10]<<8 | rx_data[11];
    uint32_t ch3 = rx_data[12]<<16 | rx_data[13]<<8 | rx_data[14];
    // uint32_t crc = rx_data[20]<<24 | rx_data[21]<<16 | rx_data[22]<<8 | rx_data[23];
    printf("Status Response: %x\n", status_response);
    printf("CH0: %x\n", ch0);
    printf("CH1: %x\n", ch1);
    printf("CH2: %x\n", ch2);
    printf("CH3: %x\n", ch3);
    //printf("CRC: %x\n", crc);

    HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);

    printf("\n**********Loop End*************\n");

    /* USER CODE BEGIN 3 */
    }

    Snapshots of DSO waveforms:-

    Yellow: CS

    Blue: SCLK

    Magenta: MISO

    Green: MOSI

  • In reply to Anshul Basra:

    Hello Anshul,

    You must send the correct number of bits for each word in the SPI frame. If the device is configured for 24-bit mode, and you send 32 bits per word, the communication will not work.

    Please configure the ADS131A04 in 32-bit mode by connecting M1 to IOVDD.

    Best Regards,


    Ryan Andrews

    Precision ΔΣ ADCs

  • In reply to Ryan Andrews:

    Hi, I connected the M1 to IOVDD.

    Now I am reading 20 bytes of channel data (CRC disabled), still  I am getting the same status response 0x22000000 and all channel data as 0.

    In Synchronous Slave mode i have connected the DRDY and CS to my Microcontroller CS, and while reading the data I set CS to Low read 20 bytes and set it back to High. Is is right or i have to send Null command to read channel data.

            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET); // CS Low
            HAL_SPI_Receive(&hspi1, rx_data, 20, 200); // Read 20 bytes of data
            HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);  // CS HIGH


            //  HAL_Delay(5);
            uint32_t status_response = rx_data[0]<<24 | rx_data[1]<<16 | rx_data[2]<<8 | rx_data[3];
            uint32_t ch0 = rx_data[4]<<24 |rx_data[5]<<16 | rx_data[6]<<8 | rx_data[7];
            uint32_t ch1 = rx_data[8]<<24 |rx_data[9]<<16 | rx_data[10]<<8 | rx_data[11];
            uint32_t ch2 = rx_data[12]<<24 |rx_data[13]<<16 | rx_data[14]<<8 | rx_data[15];
            uint32_t ch3 = rx_data[16]<<24 |rx_data[17]<<16 | rx_data[18]<<8 | rx_data[19];

  • In reply to Anshul Basra:

    Hi Anshul,

    Thank you for the update.

    Your schematic connections sound correct. When you hold /CS low and send 20 bytes of SCLK, and DIN is also low, you are effectively sending the NULL command already. You do not need to send anything but 00h's on DIN while you are reading data.

    Have you reviewed your communication timing on a scope to verify that you are meeting all timings specs? Remember that Synchronous Slave Mode expects a fixed data rate period, which is set by the time between your /DRDY falling edges. Since /DRDY and /CS are tied together in your setup, then the data rate period also establishes the period of the communication frame. In Figure 66 below, notice how /DRDY and /CS set the communication frame size within which DIN and DOUT are transmitted simultaneously. 

    If this is not the way you intend to communicate with the ADS131A04, perhaps the Asynchronous Slave Mode would be more appropriate for your application.

    Best Regards,


    Ryan Andrews

    Precision ΔΣ ADCs