Hi,
I interfaced ADS8681 with PIC32MX processor but it's not working.
READ_HWORD is not returning proper register value. it never worked. I get 32-bit reading. As per datasheet, I should get 16 bit reading followed by 0's.
Even WRITE_HWORD is also not working. It seemed like it worked one time. I set RANGE_SEL[3:0] to 1001b (2.5*VREF) once.
When I send all 0's I get ADC conversion value as response and that was working as per the selection I made to RANGE_SEL[3:0] bits.
But now even as of sudden, though I gave 1.6v as input analog voltage, I get 6.2v (156.25 * 16-bit reading).
Please help me in resolving the issue.
I am attaching the code file. Please check and let me know if I'm missing anything.
#define SPI_ON_BIT (SPIFLASH_SPICON1bits.ON)
// Maximum speed of SPI Flash part in Hz
// Should theoretically operate at 25MHz, but need to account for level-shifting delays
#define SPIFLASH_MAX_SPI_FREQ (16000000ul)
#define ClearSPIDoneFlag()
static inline __attribute__((__always_inline__)) void WaitForDataByte( void )
{
while (!SPIFLASH_SPISTATbits.SPITBE || !SPIFLASH_SPISTATbits.SPIRBF);
}
#define VREF 4.09f
#define ADC_RESOLUTION 65535
#define DEVICE_ID_REG 0x00 //Device ID register
#define DEVICE_ADDR_REG 0x02 //Device ID register
#define RST_PWRCTL_REG 0x04 //Reset and power control register
#define PWRDN 0 // 1- power down mode, 0 -active mode
#define NAP_DIS (1<<0) // PUTS ADC IN NAP MODE 0-DISABLE,1- ENABLE, CS#-HIGH
#define NAP_EN (1<<1) // PUTS ADC IN NAP MODE 0-DISABLE,1- ENABLE, CS#-HIGH
#define RST_APP_HW (2<<0)
#define RST_APP_SW (2<<1)
#define IN_AL_DIS (4<<1)
#define IN_AL_EN (4<<0)
#define VDD_AL_DIS (5<<1)
#define VDD_AL_EN (5<<0)
#define WKEY_REG 0x05
#define WKEY 0x69
#define SDI_CTL_REG 0x08 //SDI data input control register
#define SDI_MODE_CPOL0_CPHASE0 0b00
#define SDI_MODE_CPOL0_CPHASE1 0b01
#define SDI_MODE_CPOL1_CPHASE0 0b10
#define SDI_MODE_CPOL1_CPHASE1 0b11
#define SDO_CTL_REG 0x0C //SDO-x data input control register
#define SDO_MODE 0b00
#define SD01_CTL_REG 0x0D //SDO-1 pin config
#define SDO1_TRISTATE 0b00
#define SDO1_ALARM 0b01
#define SDO1_GPIO 0b10
#define SDO1_QUAD 0b11
#define GPIO_VAL_0 (0<<4)
#define GPIO_VAL_1 (1<<4)
#define DATAOUT_CTL_REG 0x10 //Output data control register
#define DATA_VAL 0b000
#define PAR_EN (0<<3) // Parity-0 no parity
#define RANGE_CTL_REG 0x11
#define RANGE_INCL (0<<8) // don't include range conf. reg val
#define ALARM_NO_INCL_SD0 (11<<0|10<<0)
#define ALARM_INCL_ACT_H (11<<0|10<<1) //H FLAG IN
#define ALARM_INCL_ACT_L (11<<1|10<<0) //L FLAG IN
#define ALARM_INCL_H_L (11<<1|10<<1) //INCLUDE BOTH H AND L
#define VDD_ALARM_NO_INCL (13<<0|12<<0) //INCLUDE BOTH H AND L
#define DEVICE_ADDR_NO_INCL (14<<0)
#define RANGE_SEL_REG 0x14 //Input range selection control register
#define RANGE_1_25_VREF 0b1011
#define RANGE_1_5_VREF 0b1010
#define RANGE_2_5_VREF 0b1001
#define RANGE_3_VREF 0b1000
#define INTREF_DIS (1<<6) // INTERNAL ADC-VREF DISABLED.
#define INTREF_EN (0<<6) // INTERNAL ADC-VREF DISABLED.
#define ALARM_REG 0x20 //ALARM output register
#define OVW_ALARM 0b1
#define TRP_IN_H_FLAG (4<<1) // LOW INPUT VOLTAGE
#define TRP_IN_L_FLAG (4<<1) // HIGH INPUT VOLTAGE
#define ALARM_ACTIVE_REG 0x21
#define ACTIVE_IN_H_FLAG (2<<1) // ACTIVE ALM ON LOW INPUT VOLTAGE
#define ACTIVE_IN_L_FLAG (3<<1) // ACTIVE ALM ON HIGH INPUT VOLTAGE
#define ALARM_H_TH_REG 0x24 //ALARM high threshold and hysteresis register
#define INP_ALRM_HIGH_TH (0x0000) // HIGH THRESHOLD FOR INPUT ALARM
#define INP_ALRM_HYST_REG 0x27
#define INP_ALRM_HYST_RESERVED 0b00
//#define INP_ALRM_HYST ()
#define ALARM_L_TH_REG 0x28 //ALARM low threshold register
#define INP_ALRM_LOW_TH 0x0000 //low threshold for the input alarm.
#define CLEAR_HWORD(reg,data) (0b110000000000000000000000000000000 | (reg<<16) | data)
#define READ_HWORD(reg) (0b11001000000000000000000000000000| (reg<<16) )
#define READ_BYTE(reg) (0b01001000000000000000000000000000| (reg<<16) )
#define WRITE_HWORD(reg,data) (0b11010000000000000000000000000000| (reg<<16) |data)
#define WRITE_MSB(reg,data) (0b11010010000000000000000000000000| (reg<<16) |data)
#define WRITE_LSB(reg,data) (0b11010100000000000000000000000000| (reg<<16) |data)
#define SET_HWORD(reg,data) (0b110110000000000000000000000000000| (reg<<16) | data)
static DWORD vSPIONSave;
static DWORD SPICON1Save;
long double measurement=0.0;
static void startAGCSPI(){
enableDeviceCS(0xFF); //disable CS
// Save SPI state (clock speed)
SPICON1Save = SPIFLASH_SPICON1;
vSPIONSave = SPI_ON_BIT;
SPI_ON_BIT = 0;
SPIFLASH_SCK_TRIS = 0; // Set SCK pin as an output
SPIFLASH_SDI_TRIS = 1; // Make sure SDI pin is an input
SPIFLASH_SDO_TRIS = 0; // Set SDO pin as an output
SpiChnOpen(4, SPICON_MSTEN|SPI_OPEN_MODE32 | SPICON_ON, 80 );
SPI_ON_BIT = 1;
DelayMs(1);
enableDeviceCS(ADS);//Enable CS
}
static void stopAGCSPI(){
enableDeviceCS(0xFF);
SPI_ON_BIT = 0;
SpiChnClose(4);
SPIFLASH_SPICON1 = SPICON1Save;
SPI_ON_BIT = vSPIONSave;
}
DWORD AGCWriteArray(DWORD cmd)
{
DWORD val;
startAGCSPI();
IFS1bits.SPI4TXIF = 0;
SPIFLASH_SPI_IF = 0;
SPIFLASH_SSPBUF = cmd;
//while(!IFS1bits.SPI4TXIF); //WaitForDataByte();
while(!SPIFLASH_SPI_IF);
val = SPIFLASH_SSPBUF;
SPIFLASH_SPI_IF = 0;
// Release the chip select to begin the write
stopAGCSPI();
return val;
}
DWORD AGCReadArray(DWORD dwAddress, DWORD *vData, WORD wLength)
{
DWORD Dummy;
startAGCSPI();
SPIFLASH_SPI_IF = 0;
IFS1bits.SPI4TXIF=0;
SPIFLASH_SSPBUF = dwAddress;
//while(!IFS1bits.SPI4TXIF);
while(!SPIFLASH_SPI_IF);
Dummy = SPIFLASH_SSPBUF;
if(wLength==0){
*vData++ =Dummy;
}else{
while(wLength--)
{
SPIFLASH_SSPBUF = 0;
while(!SPIFLASH_SPI_IF);
*vData++ = SPIFLASH_SSPBUF;
SPIFLASH_SPI_IF = 0;
}
}
// Deactivate chip select
stopAGCSPI();
return Dummy;
}
static int spi_write_word_reg(BYTE reg, WORD val)
{
DWORD data = WRITE_HWORD(reg,val);
data = AGCWriteArray(data);
return 1;
}
static int spi_write_byte_reg(BYTE reg, BYTE val)
{
DWORD data = WRITE_LSB(reg,val);
data = AGCWriteArray(data);
//AGCReadArray(0x00,&data,1);
return 1;
}
static WORD spi_read_word_reg(BYTE reg)
{
DWORD read[2]={0,0},d[2]={0,0};
DWORD dwAddress = READ_HWORD(reg);
d[0]=AGCReadArray(dwAddress,&read[0],1);
d[1]=AGCReadArray(dwAddress,&read[1],1);
return read[1];
}
static WORD spi_read_byte_reg(BYTE reg)
{
DWORD read;
DWORD dwAddress = READ_BYTE(reg);
AGCReadArray(dwAddress,&read,1);
return read;
}
static int spi_set_reg(BYTE reg, WORD val)
{
DWORD data = SET_HWORD(reg,val);
data =AGCWriteArray(data);
return 1;
}
static int spi_clear_reg(BYTE reg, WORD val)
{
DWORD data = CLEAR_HWORD(reg,val);
AGCWriteArray(data);
return 1;
}
void getAGC(){
DWORD dwAddress=0;//WRITE_HWORD(0,0);//AD_HWORD(RANGE_SEL_REG);
DWORD read=0;
AGCReadArray(dwAddress,&read,0);
// read=AGCWriteArray(dwAddress);
read&=0xFFFF0000;
read>>=16;
measurement =(long double) read*156.25/1000000; //4095
}
void AGCInit(void)
{
spi_write_word_reg(RANGE_SEL_REG,RANGE_2_5_VREF|INTREF_EN);
DelayMs(5);
getAGC();
/* vSPIONSave = spi_read_word_reg(RANGE_SEL_REG);
DelayMs(500); SPI_OPEN_CKP_HIGH|
vSPIONSave = spi_read_byte_reg(DEVICE_ADDR_REG);
DelayMs(500);
spi_write_byte_reg(WKEY_REG,WKEY);
DelayMs(500);
vSPIONSave = spi_read_word_reg(RANGE_SEL_REG);
DelayMs(500);
spi_write_byte_reg(RST_PWRCTL_REG,PWRDN|NAP_EN|IN_AL_DIS|VDD_AL_DIS);
spi_write_byte_reg(SDI_CTL_REG,SDI_MODE_CPOL0_CPHASE0);
spi_write_byte_reg(SDO_CTL_REG,SDO_MODE);
spi_write_byte_reg(SD01_CTL_REG,SDO1_GPIO|GPIO_VAL_1);
spi_write_word_reg(DATAOUT_CTL_REG,DATA_VAL|PAR_EN|RANGE_INCL|ALARM_NO_INCL_SD0|VDD_ALARM_NO_INCL|DEVICE_ADDR_NO_INCL);
*/
}
#endif
Thanks,
Vikram