Helo,
I'd like to ask some help for properly setting up the ADS1248. I use a PIC18F4685 micro with Microchip C18 compiler and I'm able to succesfully communice with the ADS via SPI (I can write and read back the registers, retrieve data, etc.)
I'd like to interface only with the 4 SPI lines, thus I tried to use DOUT/DRDY functionality to be able to poll the DRDY signal and to get a signal similar to datasheet figure 68 on page 37 (SBAS426E – AUGUST 2008 – REVISED DECEMBER 2010). I don't want to use continous data output function and interrupts, but I want to be shure that I have valid conversion result after channel and PGA setting.
I tied START pin high & hold CS continously low. I set the DOUT MODE bit in IDAC0 register, and send RDATA and 4 NOP command to force the DOUT/DRDY pin high. Until this point it works. But DOUT/DRDY never goes low however the DRDY pin sends pulses regularly as can be seen on the scope.
See the screenshot, green: DOUT/DRDY, yellow: DRDY. The low pulses on the green trace are the result bits when they are read out.
What am I doing wrong?
Here is my initialization sequence:
//configure SPI module & ADS registers
void ADSopen( void )
{
unsigned char var; //putcSPI return value, 0 if no write collision occurred, -1 if a write collision occurred
ADS_CS_TRIS = 0; //CS is output
ADS_CS = 1; //ensure CS is reset
OpenSPI(SPI_FOSC_64, MODE_01, SMPEND); //configure SPI module
ADS_CS = 0; //assert chip select
var = putcSPI( ADS_RESET ); //RESET command holds the registers and thes decimation filter
// in a reset state for 0.6 ms when the system clock frequency is 4.096MHz,
ADS_CS = 1; //deassert chip select
Wait(1); //wait 1 ms
ADS_CS = 0;
var = putcSPI( ADS_SDATAC ); //SDATAC Stop reading data continously (after reset this is the default state)
//configuration:
var = putcSPI( ADS_WREG | MUX0 ); //start at MUX0 register
var = putcSPI( 0x03 ); //write 4 bytes (number of bytes – 1)
var = putcSPI( BCS_off | MUX_SP0 | MUX_SN1 ); //MUX0: BCS_off=0b00000000,
// MUX_SP0=0b00000000, MUX_SN1=0b00000001
var = putcSPI( 0x00 ); //VBIAS
var = putcSPI( VREF_on | REFSELT_int | MUXCAL_off ); //MUX1: VREF_on=0b00100000,
// REFSELT_int=0b00010000, MUXCAL_off=0b00000000
var = putcSPI( PGA_1 | DOR_2000 ); //SYS0: PGA_1=0b00000000, DOR_2000=0b00001001
var = putcSPI( ADS_WREG | IDAC0 ); //start at IDAC0 register
var = putcSPI( 0x04 ); //write 5 bytes (number of bytes – 1)
var = putcSPI( DRDY_DRDO | IMAG_off ); //IDAC0: DRDY_DRDO=0b00001000, IMAG_off=0b00000000
var = putcSPI( I1DIR_off | I2DIR_off ); //IDAC1: I1DIR_off=0b11000000, I2DIR_off=0b00001100
var = putcSPI( 0b00000011 ); //GPIOCFG
var = putcSPI( 0b11111100 ); //GPIODIR
var = putcSPI( 0b00000001 ); //GPIODAT
var = putcSPI( ADS_NOP ); //a NOP can be sent to force DOUT/DRDY high if no other command is pending
ADS_CS = 1;
}
If I read back these regiters, I get the values what I wrote in.
Then in a loop I send RDATA command, read the result, send one additional NOP and keep the CS low:
//read conversion result
short long ADSreaddata( void )
{
unsigned char var;
short long result;
char res[3];
ADS_CS = 0; //assert chip select
var = putcSPI( ADS_RDATA ); //Read data once
res[0] = rwSPI( ADS_NOP );
res[1] = rwSPI( ADS_NOP );
res[2] = rwSPI( ADS_NOP );
var = putcSPI( ADS_NOP ); //a NOP can be sent to force DOUT/DRDY high if no other command is pending
//ADS_CS = 1; //deassert chip select ---> THIS IS COMMENTED OUT TO KEEP CS LOW
result = 0x00;
result = res[0] & 0xFF; //must & 0xFF otherwise random errors occure
result = result << 8;
result = result | ( res[1] & 0xFF );
result = result << 8;
result = result | ( res[2] & 0xFF );
return( result );
}
Any suggestion is very welcome!
Thanks,
Attila