This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

nRF52840 - ADS1292

Hi,

I want to read register 0x00 (chip ID) of ads1292. i do following...

=============================================================================================================================

///// init spi /////

spi_config.ss_pin = ARDUINO_7_PIN;
spi_config.miso_pin = ARDUINO_12_PIN;
spi_config.mosi_pin = ARDUINO_11_PIN;
spi_config.sck_pin = ARDUINO_13_PIN;
spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
spi_config.mode = NRF_DRV_SPI_MODE_0;
spi_config.frequency = NRF_DRV_SPI_FREQ_4M;
spi_config.orc = 0x00;
APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
NRF_LOG_INFO("SPI example started.");NRF_LOG_FLUSH();

///// reset the board by pulling low hardware pin /////

nrf_gpio_pin_write(ADS1292_PWDN_PIN, action);

delay(100);

nrf_gpio_pin_write(ADS1292_PWDN_PIN, action);

delay(100);

nrf_gpio_pin_write(ADS1292_PWDN_PIN, action);

delay(100);

/////// stop continues data receive mode ///////

spi_xfer_done=false;memset(m_rx_buf,0,sizeof(m_rx_buf));
spiDataTx[0]=0x11;
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, spiDataTx, 1, m_rx_buf, sizeof(m_rx_buf)));
while (!spi_xfer_done){__WFE();}
NRF_LOG_FLUSH();

//////// read chip id register (0x00) ///////////

char tempData[3];
tempData[0]=0x20;
tempData[1]=0x00;
tempData[2]=0x00;
spi_xfer_done=false;memset(m_rx_buf,0,sizeof(m_rx_buf));
APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, tempData, 3, m_rx_buf, sizeof(m_rx_buf)));
while (!spi_xfer_done){__WFE();}
NRF_LOG_FLUSH();

=============================================================================================================================

but i always get garbage value. It should come as 0x73 but every time receiving garbage values.

i did exactly same as described in datasheet of ads1292.

Did i anything wrong as far as nRF52 board concern ? Waiting for better solution.

Thanks in advance.

  • I looked over the code but there is too much for the time available. However in addition to my comments above I would (strongly) suggest that you remove all manual /CS code and instead allow the spi driver to do this:

      spi_config.ss_pin   = ADS1292_CS_PIN;
    

    I also have a question: the ADS1292 will not function unless the internal oscillator is enabled, if the internal oscillator is not enabled then an external oscillator must be present before you can perform any read-write commands. As an illustration, an ADS1292 output port was fed back to the osc select port so the oscillator could be changed from internal to external by SPI command for better synchronous operation; however, a write cannot be made to any register - including to set the output port - unless either the internal oscillator is selected or if not the external oscillator is running. The default in that case would be to the external oscillator, and so the ADS1292 would not start until the external oscillator was enable thus allowing the internal oscillator to be selected via the i/o pins and the external could be turned off. Which oscillator are you using?

  • Hi,

    I made change in my code and make it very simple to just read chip ID. So as of now i am using below main.c code to read chip id.

    /**
     * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    #include "nrf_drv_spi.h"
    #include "app_util_platform.h"
    #include "nrf_gpio.h"
    #include "nrf_delay.h"
    #include "boards.h"
    #include "app_error.h"
    #include <string.h>
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define LOW       0
    #define HIGH      1
    #define ON        0
    #define OFF       1
    #define OUTPUT    0
    #define INPUT     1
    #define BUTTON_PULLUP     NRF_GPIO_PIN_PULLUP
    
    #define ADS1292_DRDY_PIN            ARDUINO_6_PIN
    #define ADS1292_CS_PIN              ARDUINO_7_PIN
    #define ADS1292_START_PIN           ARDUINO_5_PIN
    #define ADS1292_PWDN_PIN            ARDUINO_4_PIN
    
    void ads1292_SPI_Command_Data(unsigned char data_in);
    
    #define SPI_INSTANCE  0 /**< SPI instance index. */
    static const nrf_drv_spi_t spi = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);  /**< SPI instance. */
    static volatile bool spi_xfer_done;  /**< Flag used to indicate that SPI instance completed the transfer. */
    
    static uint8_t       m_rx_buf[10];    /**< RX buffer. */
    static uint8_t m_length;        /**< Transfer length. */
    static uint8_t       ChipId[] = {0x20, 0x00, 0x00};           /**< TX buffer. */
    char data[50];
    
    /**
     * @brief SPI user event handler.
     * @param event
     */
    void spi_event_handler(nrf_drv_spi_evt_t const * p_event,
                           void *                    p_context)
    {
        //NRF_LOG_INFO("Transfer completed.");
        //nrf_delay_ms(1000);
        //if (m_rx_buf[0] != 0)
        {
            //NRF_LOG_INFO(" Received:");
            memset(data,0,sizeof(data));
            //sprintf(data,"%X - %X - %X - %X - %X - %X - %X - %X - %X - %X",
            //              m_rx_buf[0], m_rx_buf[1], m_rx_buf[2], m_rx_buf[3], m_rx_buf[4], m_rx_buf[5], m_rx_buf[6], m_rx_buf[7], m_rx_buf[8], m_rx_buf[9]);
            //sprintf(data,"%X - %X - %X",
            //              m_rx_buf[0], m_rx_buf[1], m_rx_buf[2]);
            int x=0;
            for(x=0;x<m_length;x++)
            {
              sprintf(data,"%s%X ",data,m_rx_buf[x]);
            }
            NRF_LOG_HEXDUMP_INFO(data, strlen((const char *)data));
        }
        spi_xfer_done = true;
    }
    
    int main(void)
    {
        bsp_board_init(BSP_INIT_LEDS);
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        nrf_gpio_cfg_input(ADS1292_DRDY_PIN, BUTTON_PULLUP);  //6
        //nrf_gpio_cfg_output(ADS1292_CS_PIN);    //7
        nrf_gpio_cfg_output(ADS1292_START_PIN);  //5
        nrf_gpio_cfg_output(ADS1292_PWDN_PIN);  //4
    
    
        nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin   = ADS1292_CS_PIN;
        spi_config.miso_pin = ARDUINO_12_PIN;
        spi_config.mosi_pin = ARDUINO_11_PIN;
        spi_config.sck_pin  = ARDUINO_13_PIN;
        spi_config.irq_priority = APP_IRQ_PRIORITY_HIGH;
        spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
        spi_config.mode = NRF_DRV_SPI_MODE_1;
        spi_config.frequency = NRF_DRV_SPI_FREQ_500K;
        spi_config.orc = 0x00;
        APP_ERROR_CHECK(nrf_drv_spi_init(&spi, &spi_config, spi_event_handler, NULL));
        NRF_LOG_INFO("SPI example started.");NRF_LOG_FLUSH();
    
        // reset chip //
        nrf_gpio_pin_write(ADS1292_PWDN_PIN, HIGH);
        nrf_delay_ms(100);					// Wait 100 mSec
        nrf_gpio_pin_write(ADS1292_PWDN_PIN, LOW);
        nrf_delay_ms(100);
        nrf_gpio_pin_write(ADS1292_PWDN_PIN, HIGH);
        nrf_delay_ms(100);
    
        
        nrf_gpio_pin_write(ADS1292_START_PIN, LOW);
        nrf_delay_ms(20);
        nrf_gpio_pin_write(ADS1292_START_PIN, HIGH);
        nrf_delay_ms(20);
        nrf_gpio_pin_write(ADS1292_START_PIN, LOW);
        nrf_delay_ms(20);
    
        //ads1292_SPI_Command_Data(0x08);					// Send 0x08 to the ADS1x9x
        //ads1292_SPI_Command_Data(0x0A);					// Send 0x10 to the ADS1x9x
        ads1292_SPI_Command_Data(0x11);					// Send 0x11 to the ADS1x9x
    
        // read chip ID //
        m_length=3;
        NRF_LOG_INFO("=========== 1 =============");NRF_LOG_FLUSH();
        memset(m_rx_buf, 0, sizeof(m_rx_buf)); spi_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, ChipId, 3, m_rx_buf, 3)); // MOSI
        while (!spi_xfer_done){__WFE();} NRF_LOG_FLUSH();
        NRF_LOG_INFO("=========== 1 =============");NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 2 ============");NRF_LOG_FLUSH();
        memset(m_rx_buf, 0, sizeof(m_rx_buf)); spi_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, ChipId, 3, m_rx_buf, 3)); // MOSI
        while (!spi_xfer_done){__WFE();} NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 2 ============");NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 3 ============");NRF_LOG_FLUSH();
        memset(m_rx_buf, 0, sizeof(m_rx_buf)); spi_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, ChipId, 3, m_rx_buf, 3)); // MOSI
        while (!spi_xfer_done){__WFE();} NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 3 ============");NRF_LOG_FLUSH();
    
    
        NRF_LOG_INFO("============ 4 ============");NRF_LOG_FLUSH();
        memset(m_rx_buf, 0, sizeof(m_rx_buf)); spi_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, ChipId, 3, m_rx_buf, 3)); // MOSI
        while (!spi_xfer_done){__WFE();} NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 4 ============");NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 5 ============");NRF_LOG_FLUSH();
        memset(m_rx_buf, 0, sizeof(m_rx_buf)); spi_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, ChipId, 3, m_rx_buf, 3)); // MOSI
        while (!spi_xfer_done){__WFE();} NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 5 ============");NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 6 ============");NRF_LOG_FLUSH();
        memset(m_rx_buf, 0, sizeof(m_rx_buf)); spi_xfer_done = false;
        APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, ChipId, 3, m_rx_buf, 3)); // MOSI
        while (!spi_xfer_done){__WFE();} NRF_LOG_FLUSH();
        NRF_LOG_INFO("============ 6 ============");NRF_LOG_FLUSH();
    
        bool temp1=true;
        bool temp2=false;
    
        while (1)
        {
            /*
            // to check drdy is toggeling or not (here its toggeling) //
            if(nrf_gpio_pin_read(ADS1292_DRDY_PIN)==LOW)
            {
              NRF_LOG_INFO("LOW");NRF_LOG_FLUSH();
              //if(!temp1)
              {
                temp1=true;
                ads1292_SPI_Command_Data(0x0A);					// Send 0x10 to the ADS1x9x
              }
            }
            else if(nrf_gpio_pin_read(ADS1292_DRDY_PIN)==HIGH)
            {
              NRF_LOG_INFO("HIGH");NRF_LOG_FLUSH();
              if(temp1)
              {
                temp1=false;
                ads1292_SPI_Command_Data(0x08);					// Send 0x08 to the ADS1x9x
              }
            }*/
    
            bsp_board_led_invert(BSP_BOARD_LED_0);
            nrf_delay_ms(1000);
        }
    }
    
    void ads1292_SPI_Command_Data(unsigned char data_in)
    {
      m_length=1;
      //if(DEBUG){NRF_LOG_INFO("1.0");NRF_LOG_FLUSH();}
      char spiDataTx[1];
      spiDataTx[0]=data_in;
      spi_xfer_done=false;memset(m_rx_buf,0,sizeof(m_rx_buf));
      APP_ERROR_CHECK(nrf_drv_spi_transfer(&spi, spiDataTx, 1, m_rx_buf, 1));
      while (!spi_xfer_done){__WFE();}
      NRF_LOG_FLUSH();
    }

    And by running this above code i am getting below result....

    <info> app: SPI example started.
    <info> app:  43 30 20               |C0      
    <info> app: =========== 1 =============
    <info> app:  30 20 30 20 38 30 20   |0 0 80  
    <info> app: =========== 1 =============
    <info> app: ============ 2 ============
    <info> app:  30 20 30 20 37 46 20   |0 0 7F  
    <info> app: ============ 2 ============
    <info> app: ============ 3 ============
    <info> app:  46 46 20 46 46 20 43 30|FF FF C0
    <info> app:  20                     |        
    <info> app: ============ 3 ============
    <info> app: ============ 4 ============
    <info> app:  30 20 30 20 38 30 20   |0 0 80  
    <info> app: ============ 4 ============
    <info> app: ============ 5 ============
    <info> app:  30 20 30 20 37 46 20   |0 0 7F  
    <info> app: ============ 5 ============
    <info> app: ============ 6 ============
    <info> app:  46 46 20 46 46 20 43 30|FF FF C0
    <info> app:  20                     |        
    <info> app: ============ 6 ============

    If you can see then i am reading chip id 6 times. And each time result is changing. One more thing is result is keep repeating at every 3 times.

    I did as you suggest. And i am using internal oscillator which is running at default 512KHz frequency.

    Still not getting exact chip ID (it should be 0x73 as i am using ADS1292R).

    Correct me still if i am doing anything wrong. Suggest better solution just to read chip ID then ill update my application accordingly.

    Thanks.

  • It would be helpful if you post a small section of the schematic of the digital and power side of the ADS1292; I would like to see the two supply voltages (analogue and digital), the ADS i/o pins and the nRF52 i/o pins connecting to the ADS. In particular does the digital supply match the nRF digital i/o levels and how does the power pin turn on/off the ADS supply?

    I will have a look at the code later today, but meanwhile note that you are specifying a transmit of 3 bytes but for the read register command you are only asking for 0+1 bytes=1. Was that your intention?

    // Read command to get 1 register:
    static uint8_t       ChipId[] = {0x20, 0x00, 0x00};           /**< TX buffer. */
    
    // Read command to get 3 registers
    static uint8_t       ChipId[] = {0x20, 0x02, 0x00};           /**< TX buffer. */
    

  • I also note you do not stop continuous mode before reading; I believe that is required as the ADS1292 defaults to continuous mode on startup:

        AdsSendCmd(ADS_CMND_SDATAC);                     // Stop continuous mode
    
    /****************************************************************/
    /* ADS1x9x COMMAND DESCRIPTION and definitions */
    /****************************************************************/
    typedef enum {
      // System Commands
      ADS_CMND_WAKEUP    = 0x02,   // Wake-up from standby mode
      ADS_CMND_STANDBY   = 0x04,   // Enter standby mode
      ADS_CMND_RESET_CMD = 0x06,   // Reset the device registers
      ADS_CMND_START     = 0x08,   // Start/restart (synchronize) conversions
      ADS_CMND_STOP      = 0x0A,   // Stop conversion
      ADS_CMND_OFFSETCAL = 0x1A,   // Channel offset calibration - needs to be sent every time there is a change to the PGA gain
      // Data Read Commands
      ADS_CMND_RDATAC    = 0x10,   // Enable Read Data Continuous mode.
                                   // - This mode is the default mode at power-up.
      ADS_CMND_SDATAC    = 0x11,   // Stop Read Data Continuously mode
      ADS_CMND_RDATA     = 0x12,   // Read data by command; supports multiple read back.
      // Register Read/Write Commands
      ADS_CMND_RREG      = 0x20,   // Read n nnnn registers starting at address r rrrr
                                   //  - first byte 001r rrrr (2xh)(2) - second byte 000n nnnn(2)
      ADS_CMND_WREG      = 0x40    // Write n nnnn registers starting at address r rrrr
                                   //  - first byte 010r rrrr (2xh)(2) - second byte 000n nnnn(2)
    } ADS1x9xCommand_t;
    

    Following programming then restart sampling with ADS_CMND_RDATAC

  • Hi,

    Now i am able to read register by selecting spi_config.frequency = NRF_DRV_SPI_FREQ_250K.

    I have another issue that i am unable to write registers.

    i am using below code to write 0x03 register.

    char dataToSend[3];
    dataToSend[0] = 0x03 | WREG;
    ads1292_SPICommand(dataToSend[0]);
    delayMicroSeconds(5);
    dataToSend[1] = 0x00;
    ads1292_SPICommand(dataToSend[1]);
    delayMicroSeconds(5);
    dataToSend[2] = 0x10;
    ads1292_SPICommand(dataToSend[2]);m_length=3;
    //ads1292_SPICommandString(dataToSend,3);

    what i did is...

    first i read 0x03 register and i got 0x10 (default) value then i write 0x03 register using above code and after writing it when i read 0x03 it will return 0x00 value (it should be 0x10).

    Thanks in advanced

Related