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.

ADS1213 SPI communication problem

Other Parts Discussed in Thread: ADS1213

Hello!

I need your help about my new Data Converter ADS1213.


I'm trying to start a communication with it through my SPI channel (I'm using an ATMega32).

/* Initialization Pin part */

DDRB = (1<<SCK)|(1<<MOSI); // define my cpu as the Master with SCK and MOSI as output
PORTB = 0x00;

/* SPI: Interrupt disable - SPI enable - MSB first - Master - fosc/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);

/***************************************/
/* INITIALIZE MY ADS */
/* Clear SPCI */
SPSR;
SPDR;

ADS_ON; // write 0 to my SELADS pin 
//t24 not needed 33.8us without break

SPDR = 0x04;
loop_until_bit_is_set(SPSR,SPIF); // wait the end of the transmit
_delay_us(100);	//t19 for the debug
SPDR = 0x43;   // Use SDOUT for the output
loop_until_bit_is_set(SPSR,SPIF);

ADS_OFF;	//t20 not needed 4.98us without break


/***************************************/
/* TRY TO READ SOMTH */

/* Clear SPI */
SPSR;
SPDR;
	
ADS_ON;
	
/* Read SPI */
SPDR = 0x84; // try to read the Command Register Byte 3
loop_until_bit_is_set(SPSR,SPIF);
_delay_us(100);	//t19 for the debug
SPDR = 0xFF; // wrote 0xFF to get time to read into SDOUT
loop_until_bit_is_set(SPSR,SPIF);
test = SPDR;

ADS_OFF;	//t20 not needed 4.98us without break

And now my diagramm of the ADS:

From the TOP to the BOTTOM:

DRDY

CS

SCK

SDIO

SDOUT

The init sequence with the 2 bytes 0x04 and 0x43

My reading sequence:

Has you can see there is nothing transmit in SDOUT.

Thanks a lot for your futur help.


Do not hesitate if you need more details.

Best,

Bastien

  • Hi Bastien,

    In the second scope shot (reading sequence) notice that the command is incorrect.  What is shown is a write sequence and not a read (0x64 instead of 0x84).  Notice that the first falling edge of SCLK the SDIO is low, so the INSR is given as write 4 bytes starting at Command Register Byte 3 and write 0xFF.  As this is a write sequence, SDOUT will not change.

    Best regards,

    Bob B

  • Hi Bob,

    Thanks for your answer and it was helping me a lot! I will confirm your answer again after this question.
    Now I have some problem to get the response of the ADS. I configure it well because I get the answer througt SDOUT. But Impossible to save it.


    I thing the problem is about my Atmega but just in case you see something, I created a small project and test = 0 all the time:

    /* Includes */
    #include <avr/io.h>
    #include <util/delay.h>
    
    /* Define */
    typedef unsigned char  u08;
    #define TXIN 0.542
    
    /* Macro */
    #define set_bit(port, bit)	(port |= (1<<bit))
    #define clear_bit(port, bit)	(port &= ~(1<<bit))
    #define check_bit(var, pos) ((var) & (1<<(pos)))
    
    /* Variables */
    u08 volatile test;
    
    /* Functions */
    void ResetADS(void);
    void InitADS(void);
    
    int main(void)
    {
    	/* Init port */
    	DDRB = (1<<PINB7)|(1<<PINB5)|(1<<PINB4);
    	
    	/* Reset the ADS */
    	ResetADS();
    	
    	/* SPI: Interrupt disable - SPI enable - MSB first - Master - fosc/64 */
    	SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPHA)|(1<<SPR1);
    	
    	/* Init the ADS */
    	InitADS();
    	
    	while(1)
    	{
    		/* Read the configuration */
    		/* Clear SPI */
    		SPSR;
    		SPDR;
    	
    		loop_until_bit_is_set(PINA, PINA7);
    		loop_until_bit_is_clear(PINA, PINA7);
    	
    		clear_bit(PORTB, PINB4);
    	
    		/* Read SPI */
    		SPDR = 0x87; // read request
    		loop_until_bit_is_set(SPSR,SPIF);
    		_delay_us(10*TXIN);
    		SPDR = 0xFF; // SCK sequence to get the answer
    		loop_until_bit_is_set(SPSR,SPIF);
    		test = SPDR;
    	
    		set_bit(PORTB, PINB4);	//t20 not needed 4.98us without break
    	}
    }
    
    /* Needed when using the ADS as a Slave */
    void ResetADS(void)
    {
    	clear_bit(PORTB, PINB4);
    	
    	set_bit(PORTB, PINB7);
    	_delay_us(1024*TXIN);
    	clear_bit(PORTB, PINB7);
    	_delay_us(10*TXIN);
    	set_bit(PORTB, PINB7);
    	_delay_us(512*TXIN);
    	clear_bit(PORTB, PINB7);
    	_delay_us(10*TXIN);
    	set_bit(PORTB, PINB7);
    	_delay_us(1024*TXIN);
    	clear_bit(PORTB, PINB7);
    	_delay_us(10*TXIN);
    	set_bit(PORTB, PINB7);
    	_delay_us(2048*TXIN);
    	clear_bit(PORTB, PINB7);
    	
    	set_bit(PORTB, PINB4);
    }
    
    /* Configure the MISO as the ADS output */
    void InitADS(void)
    {
    	/* Clear SPI */
    	SPSR;
    	SPDR;
    	
    	loop_until_bit_is_set(PINA, PINA7);
    	loop_until_bit_is_clear(PINA, PINA7);
    	
    	clear_bit(PORTB, PINB4);	// t24 not needed 33.8us without break
    
    	/* Read SPI */
    	SPDR = 0x04;	// Write CMR Byte 3
    	loop_until_bit_is_set(SPSR,SPIF);
    	SPDR = 0x42;	// SDOUT for the output
    	loop_until_bit_is_set(SPSR,SPIF);
    
    	set_bit(PORTB, PINB4);	// t20 not needed 4.98us without break
    }

    I also made a measure:

    Signals in order: 3: DRDY, 4: SELADS, 0: SCK, 1: MOSI, 2: MISO from the ADS

    and the Yellow PINB6 MISO from the Atmega

     Thn

    Thanks again,


    Best,


    Bastien

  • Hi Bastien,

    I don't see anything wrong with your code unless it is in the function loop_until_bit_is_set().  If you are using a debugger to check the value of the test variable, it is possible that the debugger is not handling the values/locations properly depending on where you set the breakpoint.  The breakpoint should come after the completion of the command to set test to SPDR.

    Best regards,

    Bob B

  • Hi!


    Good news, I received another experimental board today, I tested the same out with it... and suprise everything works fine!


    So I think my Atmega pin should be dead :(.


    Best and thanks again for your help!