Post Go back to editing

ADE7913 SPI Problems

Hi,

i have an EVAL ADE7913. For my project i used a µC, (Arduino MKR Zero) it is running with 3.3 Volt. I didn't use the the DSP Front-end instead I connect the MKR Zero directly to the pin bar.
Basically the connection between the µC works,(SCKL, MOSI,CS), but the ADE7913 didn' response on the MISO line.

I need some help because i don't understand the problem?!

Below is the Source Code. It's not my own code. It's copy from evive project for testing the chip.

Is this code also ready for ADE7913?


int SPI_ADC_SS = 7;    // SPI ADC SS
int ADC_RDY = 6;      // ADC Ready pin
#define ADC_SPIMaxSpeed 5600000
#define ADC_SPIMode SPI_MODE3
#define ADC_SPIDataOrder MSBFIRST

// Command Definitions
#define ADE791X_READ    0x04
#define ADE791X_WRITE   0x00

// Register Definitions
#define ADE791X_REG_IWV            0x00    /* Instantaneous value of Current I. */
#define ADE791X_REG_V1WV           0x01    /* Instantaneous value of Voltage V1 */
#define ADE791X_REG_V2WV           0x02    /* Instantaneous value of Voltage V2 */
#define ADE791X_MUL_V1WV           0.006485
#define ADE791X_OFFSET_V1WV        362760   
#define ADE791X_MUL_VIMWV          0.0011901
#define ADE791X_OFFSET_VIMWV       349319
#define ADE791X_MUL_IWV            0.0005921
#define ADE791X_OFFSET_IWV        

#define ADE791X_REG_ADC_CRC        0x04    /* CRC value of IWV, V1WV, and V2WV registers. See the ADC Output Values CRC section for details */
#define ADE791X_REG_CTRL_CRC       0x05    /* CRC value of configuration registers. See the CRC of Configuration Registers  for details. */

#define ADE791X_REG_CNT_SNAPSHOT   0x07    /* Snapshot value of the counter used in synchronization operation. */
#define ADE791X_REG_CONFIG         0x08    /* Configuration register. See Table 15 for details */
#define ADE791X_REG_STATUS0        0x09    /* Status register */
#define ADE791X_REG_LOCK           0x0A    /* Memory protection register */
#define ADE791X_REG_SYNC_SNAP      0x0B    /* Synchronization register */
#define ADE791X_REG_COUNTER0       0x0C    /* Contains the least significant eight bits of the internal synchronization counter */
#define ADE791X_REG_COUNTER1       0x0D    /* COUNTER1[3:0] bits contain the most significant four bits of the internal synchronization counter */
#define ADE791X_REG_EMI_CTRL       0x0E    /* EMI control register. */
#define ADE791X_REG_STATUS1        0x0F    /* Status register */

#define ADE791X_REG_TEMPOS         0x18    /* Temperature sensor offset */

/* configuration register constants */
#define CLKOUT_EN                  0x01
#define PWRDWN_EN                  0x04    /* Shuts down the dc-to-dc converter. When PWRDWN_EN = 0, the default value, the */
#define TEMP_EN                    0x08    /* This bit selects the second voltage channel measurement. */
#define ADC_FREQ_8KHZ              0x00    /* These bits select the ADC output frequency to 8khz. */
#define ADC_FREQ_4KHZ              0x10    /* These bits select the ADC output frequency.4khz */
#define ADC_FREQ_2KHZ              0x20    /* These bits select the ADC output frequency.2khz */
#define ADC_FREQ_1KHZ              0x30    /* These bits select the ADC output frequency.1khz */
#define SWRST                      0x40    /* When this bit is set to 1, a software reset is initiated. This bit clears itself to 0 after */
#define BW                         0x80    /* Selects the bandwidth of the digital low-pass filter of the ADC. When BW = 0, the */

/*Status0 registers (address 0x9*/
#define RESET_ON                  0x00
#define CRC_STAT                  0x01
#define IC_PROT                   0x02

/* lock register constants(address 0xA */
#define LOCKED                    0xCA    /*locks configuration register writing */
#define UNLOCKED                  0x9C    /*unlocks configuration register writing */

SPISettings ADCSetting(ADC_SPIMaxSpeed,ADC_SPIDataOrder,ADC_SPIMode);

// the setup routine runs once when you press reset:
void setup() {
 
  Serial.begin (250000);
  ade791x_init();
    delay (100);
}

// the loop routine runs over and over again forever
void loop() {
  ade7912_read(ADE791X_REG_V1WV);
  ade791x_read_v1 ();
//  ade791x_read_v2();
//  ade791x_read_vim ();
//  ade791x_read_i ();
// ade791x_read_temperature ();
//Serial.println(millis());
//  Serial.println();
    
//  delay (100);  

}


void ade791x_init(void)
{
  pinMode(SPI_ADC_SS, OUTPUT);
  pinMode(ADC_RDY, INPUT);
  // take the SS pin high to de-select the chip:
  digitalWrite(SPI_ADC_SS, HIGH);
  // initialize SPI:
  SPI.begin();
//  delay(1);
//  delayMicroseconds(16);
  //SPI.setClockDivider(SPI_ADC_SS, 64);  // default is 4MHz clock
//  SPI.setBitOrder(MSBFIRST);        // default is MSBFIRST
//  SPI.setDataMode(SPI_MODE3);       // ADE791x chip uses SPI_MODE3

//DS: MAKE  THIS WORKING
  //  ade791x_write(ADE791X_REG_LOCK,UNLOCKED);
//  ade791x_write(ADE791X_REG_CONFIG, ADC_FREQ_4KHZ | TEMP_EN);  // configures adc sampling frequency and enables temperature on V2WV register
 
}


unsigned char ade791x_read(unsigned char addr)
{
  unsigned char value;  // stores value to return
  unsigned char opcode; // stores opcode
 
  addr = addr << 3;  // left shift address by 3 bits
  opcode = (addr | ADE791X_READ); // forms opcode byte
  Serial.print ("opcode: ");    // for debug only
  Serial.println(opcode, BIN);  // for debug only

  // take the SS pin low to select the chip:
  SPI.beginTransaction(ADCSetting);  
  digitalWrite(SPI_ADC_SS, LOW);  // bring SS2 pin low
  SPI.transfer(opcode);           // send out opcode
  value = SPI.transfer(0xFF);     // send out dummy byte to read register
  // take the SS pin high to de-select the chip:
  digitalWrite(SPI_ADC_SS, HIGH);
  SPI.endTransaction();  
  return value;
}

long ade7912_read(unsigned char addr)
{
  long value;  // stores value to return
  unsigned char opcode; // stores opcode
  long tempValue1 = 0, tempValue2 = 0 , tempValue3 = 0;   
 
  addr = addr << 3;  // left shift address by 3 bits
  opcode = (addr | ADE791X_READ);     // forms opcode byte
//  Serial.print ("opcode: ");    // for debug only
//  Serial.println(opcode, BIN);  // for debug only

  SPI.beginTransaction(ADCSetting);
  // take the SS pin low to select the chip:
  digitalWrite(SPI_ADC_SS, LOW);  // bring SS2 pin low
//  PORTC &= ~_BV(PC2);
  SPI.transfer(opcode);        // send out opcode
//  value  = SPI.transfer(0xFF) * 0x10000;  // read MS Byte
////  tempValue1=value;  
//  value |= SPI.transfer(0xFF) * 0x100;  // read mid Byte
////  tempValue2=value;  
//  value |= SPI.transfer(0xFF);  // LS Byte

  tempValue1 = SPI.transfer(0xFF);  // read MS Byte
//  tempValue1=value;  
  tempValue2 = SPI.transfer(0xFF);  // read mid Byte
//  tempValue2=value;  
  tempValue3 = SPI.transfer(0xFF);  // LS Byte

  // take the SS pin high to de-select the chip:
  digitalWrite(SPI_ADC_SS, HIGH);  
  //PORTC |= _BV(PC2);
 
  SPI.endTransaction();  

  tempValue1  = tempValue1 * 0x10000;
  tempValue2 = tempValue1 | tempValue2 * 0x100;
  value = tempValue2 | tempValue3;
    
  value = value <<8;        // sign extends value to 32 bit
  value = value / 0x100;    // converts back value to 24 bit but now sign extended


 

  value = (value - ADE791X_OFFSET_V1WV)*ADE791X_MUL_V1WV; //ADE791X_MUL_V1WV;
 
 Serial.print ("V1: ");
 Serial.println (value);
//    Serial.print ("V1: ");
//  Serial.println (value,BIN);
  #endif  
  //Serial.println(micros()-st);
  return value;  
}

  • Do you have any scope captures of the spi port coms? 

    here is my setup that works

    I am using a blue pill

    SPI.begin (); // set io12,13,14 as sp SPI.setHwCs(false); //dissable io15 as csb
    SPI.setBitOrder(MSBFIRST); // Set the SPI_1 bit order
    SPI.setDataMode(SPI_MODE3); //Set the SPI_2 data mode 0
    SPI.setClockDivider(SPI_CLOCK_DIV16); // Slow speed (72 / 16 = 4.5 MHz SPI_1 speed)

     pinMode(CS_A, OUTPUT);

     pinMode(CLK_RDYB_C,INPUT);

    Serial.println( ADE7913_SPI_READ(CONFIG, 0x1,CS_A));

      attachInterrupt(digitalPinToInterrupt(CLK_RDYB_C),dready_irq,FALLING); // response about 5.2us

    uint32_t ADE7913_SPI_READ (uint16_t Address, uint8_t Number_of_bytes,uint8_t CSB_x)
    {
    uint8_t mhb=0,hb = 0,mb = 0,lb = 0;
    uint16_t temp_address;
    uint32_t j;


    digitalWrite(CSB_x, LOW);

    temp_address = ((Address << 3) & 0xf8); //shift address to align with cmd packet

    SPI.transfer(temp_address + 4); // send address + read

    switch(Number_of_bytes){
    case 4:
    mhb = SPI.transfer(0x0); // dummy write
    case 3:
    hb = SPI.transfer(0x0);
    case 2:
    mb = SPI.transfer(0x0);
    case 1:
    lb = SPI.transfer(0x0);
    default:
    break;
    }


    digitalWrite(CSB_x, HIGH); //set csb high

    j= mhb << 24;
    j= j + (hb << 16);
    j= j + (mb << 8);
    j= j + lb;
    return j;
    }


    void dready_irq(){

    ADC[0] = ADE7913_SPI_READ(IWV , 3,CS_A);
    ADC[1] = ADE7913_SPI_READ(V1WV, 3,CS_A);
    ADC[2] = ADE7913_SPI_READ(V2WV, 3,CS_A);
    ADC[3] = ADE7913_SPI_READ(IWV , 3,CS_B);
    ADC[4] = ADE7913_SPI_READ(V1WV, 3,CS_B);
    ADC[5] = ADE7913_SPI_READ(V2WV, 3,CS_B);
    ADC[6] = ADE7913_SPI_READ(IWV , 3,CS_C);
    ADC[7] = ADE7913_SPI_READ(V1WV, 3,CS_C);
    ADC[8] = ADE7913_SPI_READ(V2WV, 3,CS_C);
    }

Before You Switch


Switching languages will make ADI Explorer unavailable. Resume your session by switching back to English and reopening ADI Explorer.