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

Reading from slave chip (ADS1293) through SPI

Hi everyone!

I'm trying to read a register from the ADS1293 chip by using SPI but have been stuck for a good two days. The very basic code I have is right below:

#define SPI_INSTANCE   0

static uint8_t tx;
static uint8_t rx;

static const nrf_drv_spi_t m_spi_master_0 = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);

void ADS_init( void )
{
    nrf_drv_spi_config_t const spi_config =
    {
        .sck_pin        = 27,
        .mosi_pin       = 6,
        .miso_pin       = 42,
        .ss_pin         = 44,
        .irq_priority   = APP_IRQ_PRIORITY_LOW,
        .orc            = 0xFF,
        .frequency      = NRF_DRV_SPI_FREQ_4M,
        .mode           = NRF_DRV_SPI_MODE_0,
        .bit_order      = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST, 
    };
    ret_code_t err_code = nrf_drv_spi_init(&m_spi_master_0, &spi_config, NULL, NULL);
    //SEGGER_RTT_printf(0, nrf_strerror_get(err_code));
     
}

uint8_t Read_reg(uint8_t addr)
{ 
  tx = ADS1293_READ_BIT | addr;
  ret_code_t err_code = nrf_drv_spi_transfer(&m_spi_master_0, &tx, 1, &rx, 1);
  SEGGER_RTT_printf(0, nrf_strerror_get(err_code));
  return rx;
}

There are two things I'm not 100% sure about:

1) If the pins I'm using are correct. Is there any way to make sure that the pins I'm using are correct that is simpler than managing to read the register on the ADS? Here's how they are connected:

 NRF      ADS
P0.19 -> SDO
P0.20 -> SDI
P0.04 -> SCLK
P0.03 -> CSB

2) If the way I'm using nrf_drv_spi_transfer is correct for the ADS. If I understand correctly what's on page 37 in their documentation I should send in 8 bits and will receive 8 bits and I do this by sending in the uint8_t tx (address but set the first bit to 1) and uint8_t rx. 

When I do this I get the NRF_SUCCESS code but the data received is 0x00 and is supposed to be 0x02 for the register I'm trying. I'm really new to this so I have really no idea what I should be doing right now.

Parents
  • Edit: Looks like the ADS1293 is quite different (upgraded) from the ADS1291/2/8 so some of these comments may not apply.

    There are a number of other issues with your settings. Start with a slower clock and SPI Mode 1:

    // SPI INTERFACE
    // The SPI-compatible serial interface consists of four signals: CS, SCLK, DIN, and DOUT. The interface reads
    // conversion data, reads and writes registers, and controls ADS1291, ADS1292, and ADS1292R operation. The
    // DRDY output is used as a status signal to indicate when data are ready. DRDY goes low when new data are
    // available.
    // Chip Select (CS)
    // CS selects the ADS1291, ADS1292, and ADS1292R for SPI communication. CS must remain low for the entire
    // duration of the serial communication. After the serial communication is finished, always wait four or more tCLK
    // cycles before taking CS high. When CS is taken high, the serial interface is reset, SCLK and DIN are ignored,
    // and DOUT enters a high-impedance state. DRDY asserts when data conversion is complete, regardless of
    // whether CS is high or low
    
    // Sending Multi-Byte Commands
    // The ADS1291, ADS1292, and ADS1292R serial interface decodes commands in bytes and requires 4 tCLK cycles
    // to decode and execute. Therefore, when sending multi-byte commands, a 4 tCLK period must separate the end of
    // one byte (or opcode) and the next.
    // Assume CLK is 512 kHz, then tSDECODE (4 tCLK) is 7.8125 us. When SCLK is 16 MHz, one byte can be
    // transferred in 500 ns. This byte-transfer time does not meet the tSDECODE specification; therefore, a delay must be
    // inserted so the end of the second byte arrives 7.3125 us later. If SCLK is 1 MHz, one byte is transferred in 8 �s.
    // Because this transfer time exceeds the tSDECODE specification, the processor can send subsequent bytes without
    // delay. In this later scenario, the serial port can be programmed to move from single-byte transfer per cycle to
    // multiple bytes.
      
      spi_config.frequency = NRF_DRV_SPI_FREQ_500K;  // Ensure less than 4 clk cycles for ADS1291/2/8
      spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
      spi_config.mode      = NRF_DRV_SPI_MODE_1;
    

    Note you need to stop continuous read mode before accessing registers by sending command ADS_CMND_SDATAC:

    /****************************************************************/
    /* 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;
    

    Have a look at the answers we provided in this link: interface-an-ads1298-via-spi

Reply
  • Edit: Looks like the ADS1293 is quite different (upgraded) from the ADS1291/2/8 so some of these comments may not apply.

    There are a number of other issues with your settings. Start with a slower clock and SPI Mode 1:

    // SPI INTERFACE
    // The SPI-compatible serial interface consists of four signals: CS, SCLK, DIN, and DOUT. The interface reads
    // conversion data, reads and writes registers, and controls ADS1291, ADS1292, and ADS1292R operation. The
    // DRDY output is used as a status signal to indicate when data are ready. DRDY goes low when new data are
    // available.
    // Chip Select (CS)
    // CS selects the ADS1291, ADS1292, and ADS1292R for SPI communication. CS must remain low for the entire
    // duration of the serial communication. After the serial communication is finished, always wait four or more tCLK
    // cycles before taking CS high. When CS is taken high, the serial interface is reset, SCLK and DIN are ignored,
    // and DOUT enters a high-impedance state. DRDY asserts when data conversion is complete, regardless of
    // whether CS is high or low
    
    // Sending Multi-Byte Commands
    // The ADS1291, ADS1292, and ADS1292R serial interface decodes commands in bytes and requires 4 tCLK cycles
    // to decode and execute. Therefore, when sending multi-byte commands, a 4 tCLK period must separate the end of
    // one byte (or opcode) and the next.
    // Assume CLK is 512 kHz, then tSDECODE (4 tCLK) is 7.8125 us. When SCLK is 16 MHz, one byte can be
    // transferred in 500 ns. This byte-transfer time does not meet the tSDECODE specification; therefore, a delay must be
    // inserted so the end of the second byte arrives 7.3125 us later. If SCLK is 1 MHz, one byte is transferred in 8 �s.
    // Because this transfer time exceeds the tSDECODE specification, the processor can send subsequent bytes without
    // delay. In this later scenario, the serial port can be programmed to move from single-byte transfer per cycle to
    // multiple bytes.
      
      spi_config.frequency = NRF_DRV_SPI_FREQ_500K;  // Ensure less than 4 clk cycles for ADS1291/2/8
      spi_config.bit_order = NRF_DRV_SPI_BIT_ORDER_MSB_FIRST;
      spi_config.mode      = NRF_DRV_SPI_MODE_1;
    

    Note you need to stop continuous read mode before accessing registers by sending command ADS_CMND_SDATAC:

    /****************************************************************/
    /* 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;
    

    Have a look at the answers we provided in this link: interface-an-ads1298-via-spi

Children
Related