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.

AFE4300: AFE4300 problem in SPI read

Part Number: AFE4300
Hi,
I've been trying to make SPI communication work between Arduino Due (as master) and an AFE4300 sensor (as slave). When I write the appropriate data to the specified registers, the VLDO becomes 1.7, RDY changes correctly and IOUT pins work well. But after writing data, when I want to read data from the sensor, I only receive 0 from ADC_DATA_RESULT. Also, after writing registers and initializing the sensor, when I read data of written registers (and the rewriting in them), I receive correct data only from ADC_CONTROL_REGISTER2 and other registers are 0 (but RDY and IOUT pins work correctly).
The clock of the sensor is provided from Arduino and connections seem correct.
I was wondering if anyone could help me to solve this problem. My Arduino code and output data are at the end of this message.
Thanks
Ali Hashemi
Arduino Code:

#include <SPI.h>

// pins
#define PIN_RESET 9
#define PIN_DRDY 3
#define PIN_LED 13

#define SlaveSelectPIn 4

void resetAFE4300();
void writeRegister(uint8_t address, uint16_t data);
int readRegister(uint8_t address);
void initAFE4300();
void initWeighScale();
void initBCM();
void writeDefault();
void readAll();

int readData();

/***************************
AFE4300 register address definitions
****************************/
#define ADC_DATA_RESULT 0x00
#define ADC_CONTROL_REGISTER 0x01
#define MISC1_REGISTER 0x02
#define MISC2_REGISTER 0x03
#define DEVICE_CONTROL_1 0x09
#define ISW_MATRIX 0x0A
#define VSW_MATRIX 0x0B
#define IQ_MODE_ENABLE 0x0C
#define WEIGHT_SCALE_CONTROL 0x0D
#define BCM_DAC_FREQ 0x0E
#define DEVICE_CONTROL_2 0x0F
#define ADC_CONTROL_REGISTER_2 0x10
#define MISC3_REGISTER 0x1A

void setup()
{
/************* Timer Counter 0 Channel 0 to generate PWM pulses thru TIOA0 ************/
PMC->PMC_PCER0 |= PMC_PCER0_PID27; // Timer Counter 0 channel 0 IS TC0, TCO power ON
PMC->PMC_PCER0 |= PMC_PCER0_PID12; // PIOB power ON, page 38

PIOB->PIO_PDR |= PIO_PDR_P25;
PIOB->PIO_ABSR |= PIO_ABSR_P25; // PB25 is driven by the TC, peripheral type B, page 858

TC0->TC_CHANNEL[0].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 // MCK/2, clk on rising edge
| TC_CMR_WAVE // Waveform mode
| TC_CMR_WAVSEL_UP_RC // UP mode with automatic trigger on RC Compare
| TC_CMR_ACPA_CLEAR // Clear TIOA0 on RA compare match
| TC_CMR_ACPC_SET; // Set TIOA0 on RC compare match


TC0->TC_CHANNEL[0].TC_RC = 42; //<********************* Frequency = (Mck/2)/TC_RC = 1 MHz
TC0->TC_CHANNEL[0].TC_RA = 21; //<******************** Duty cycle = (TC_RA/TC_RC) * 100 = 50 %

TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC0 counter and enable
///////////////

pinMode(PIN_LED, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
pinMode(SlaveSelectPIn, OUTPUT);
pinMode(PIN_DRDY, INPUT);

digitalWrite(SlaveSelectPIn, HIGH);

Serial.begin(115200);
Serial.flush();

SPI.begin(SlaveSelectPIn); // SPI CS for slave
SPI.setBitOrder(MSBFIRST);
SPI.setClockDivider(SlaveSelectPIn,84); // 1MHz clock generation
SPI.setDataMode(SlaveSelectPIn, SPI_MODE1);

resetAFE4300();
writeDefault();
delay(1000);
readAll();
delay(10);
}
void loop()
{
readData();
}
/**
* @brief Resets the AFE4300 device
*/
void resetAFE4300()
{
digitalWrite(PIN_RESET ,LOW);
delay(100);
digitalWrite(PIN_RESET ,HIGH);
delay(5);
}

void writeRegister(uint8_t address, uint16_t data)
{
uint8_t firstByte = (uint8_t)(data >> 8);
uint8_t secondByte = (uint8_t)data & 0xFF;

digitalWrite(SlaveSelectPIn, LOW);

SPI.transfer(SlaveSelectPIn,address,SPI_CONTINUE);
delayMicroseconds(10);
SPI.transfer(SlaveSelectPIn,firstByte,SPI_CONTINUE);
delayMicroseconds(10);
SPI.transfer(SlaveSelectPIn,secondByte,SPI_LAST);
delayMicroseconds(10);

digitalWrite(SlaveSelectPIn, HIGH);
}

int readRegister(uint8_t address)
{
SPI.begin(SlaveSelectPIn);
uint16_t spiReceive = 0;
uint8_t spiReceiveFirst = 0;
uint8_t spiReceiveSecond = 0;

address = address & 0x1F;
address = address | 0x20; //First 3 bits need to be 001 for read opcode

digitalWrite(SlaveSelectPIn, LOW);
SPI.transfer(SlaveSelectPIn,address,SPI_CONTINUE );
spiReceiveFirst = SPI.transfer(SlaveSelectPIn,0x00,SPI_CONTINUE);
delayMicroseconds(10);
spiReceiveSecond = SPI.transfer(SlaveSelectPIn,0x00, SPI_LAST);
delayMicroseconds(10);
digitalWrite(SlaveSelectPIn,HIGH);

//Combine the two received bytes into a signed int
spiReceive = (spiReceiveFirst << 8);
spiReceive |= spiReceiveSecond;

if(address != 0)
writeRegister(address, spiReceive);

Serial.print("spi Receive: ");
Serial.println(spiReceive, HEX);
return spiReceive;

}

int readData()
{
return readRegister(ADC_DATA_RESULT);
}
void writeDefault()
{
writeRegister(ADC_CONTROL_REGISTER, 0x4133);
writeRegister(MISC1_REGISTER, 0x0000);
writeRegister(MISC2_REGISTER, 0xFFFF);
writeRegister(DEVICE_CONTROL_1, 0x6006);
writeRegister(ISW_MATRIX , 0x0408);
writeRegister(VSW_MATRIX , 0x0408);
writeRegister(IQ_MODE_ENABLE, 0x0000);
writeRegister(WEIGHT_SCALE_CONTROL, 0x0000);
writeRegister(BCM_DAC_FREQ, 0x0040);
writeRegister(DEVICE_CONTROL_2, 0x0000);
writeRegister(ADC_CONTROL_REGISTER_2, 0x0063);
writeRegister(MISC3_REGISTER, 0x00C0);
}

void readAll()
{
Serial.println("*******************************");
Serial.print("ADC_CONTROL_REGISTER1: ");
readRegister(ADC_CONTROL_REGISTER);
Serial.print("MISC_REGISTER1: ");
readRegister(MISC1_REGISTER);
Serial.print("MISC_REGISTER2: ");
readRegister(MISC2_REGISTER);
Serial.print("DEVICE_CONTROL1: ");
readRegister(DEVICE_CONTROL_1);
Serial.print("ISW_MUX: ");
readRegister(ISW_MATRIX);
Serial.print("VSENSE_MUX: ");
readRegister(VSW_MATRIX);
Serial.print("IQ_MODE_ENABLE: ");
readRegister(IQ_MODE_ENABLE);
Serial.print("WEIGHT_SCALE_CONTROL: ");
readRegister(WEIGHT_SCALE_CONTROL);
Serial.print("BCM_DAC_FREQ: ");
readRegister(BCM_DAC_FREQ);
Serial.print("DEVICE_CONTROL2: ");
readRegister(DEVICE_CONTROL_2);
Serial.print("ADC_CONTROL_REGISTER2: ");
readRegister(ADC_CONTROL_REGISTER_2);
Serial.print("MISC_REGISTER3: ");
readRegister(MISC3_REGISTER);
Serial.println("*******************************");
}

-------------------------------------------------------------------------------

And a part of output is:

******************************

ADC CONTROL REGISTER1: spi Receive: 0

MISC REGISTER1: spi Receive: 0

MISC_REGISTER2: spi Receive: 0

DEVICE_CONTROL1: spi Receive: 0

ISW MUX: spi Receive: 0

VSENSE MUX: spi Receive: 0

IQ_MODE_ENABLE: spi Receive: 0

WEIGHT SCALE CONTROL: spi Receive: 0

BCM DAC FREQ: spi Receive: 0

DEVICE CONTROL2: spi Receive: 0

ADC CONTROL REGISTER2: spi Receive: 4130

MISC REGISTER3: spi Receive: 101

*******************************

spi Receive: 0

spi Receive: 0

spi Receive: 0

spi Receive: 0

spi Receive: 0

spi Receive: 0

  • Hello MohammadHadi,

    It seems like there is something inherently wrong with the SPI communication.

    I would suggest that you verify writing to and reading from 1 register at a time (for eg., register address 0x01 or 0x02 or 0x03 since the register has a default value after reset).

  • Hello Praveen,

    Yes as you said it seems there is a problem with the SPI communication.
    I tried to write and read from one register that has default value after reset, but again I didn't receive expected data from the sensor.

    Thanks
    MohammadHadi

  • Hi Mohammad,

    I have sent you an email on this issue.

    You may first want to check if the SPI writes work. You can verify this by checking the VREF voltage.

    To verify VREF voltage (assuming device is out of reset), you will only need to write to DEVICE_CONTROL1 register address (0x09) value of 0x6006 after power-up and reset.

     

    Check the SPI timing diagram and see the timing edges conform to the datasheet description.

    For example, the device latches data on SDIN on the falling edge of SCLK. During read, data is shifted out on the SDOUT pin on the rising edge of SCLK.

    Also note that every time a register is read, the register must be rewritten except when reading the data output register.

  • Hi Praveen,

    It seems that my SPI write is Ok. Because VREF and VLDO voltage work properly and also IOUT pins work as expected. I checked the SPI bus with a logic analyzer, SCLK and MOSI data work as expected but there is no data transfer on the MISO line. 

    In addition, I rewrite the registers when I try to read them (except ADC_DATA_RESULT).
    Is it possible that my sensor has been damaged?

    Thanks
    MohammadHadi

  • Hello MohammadHadi,

    From what you say, it seems like the SPI writes are working. Please confirm.

    Can you share the timing waveforms of writing and reading from 1 register (DEVICE_CONTROL1 register address (0x09))

    Please share the timing waveforms captured on a scope instead of logic analyzer.