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