Example program for EVAL-AD1234.

Dependencies:   ADE120x

main.cpp

Committer:
mlambe
Date:
2019-10-15
Revision:
3:8024f7ba736c
Parent:
2:2ebdd709cec0
Child:
4:5ea2e3188584

File content as of revision 3:8024f7ba736c:

/**  
 * @file       main.cpp
 * @brief      Main file. This file uses the ADE120x drivers to configure the part
 *             Use AN-2034 in conjunction with this example 
 * @version    V0.0.1
 * @author     ADI
 * @date       October 2019
 * @par Revision History:
 * 
 * Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved.
 * 
 * This software is proprietary to Analog Devices, Inc. and its licensors.
 * By using this software you agree to the terms of the associated
 * Analog Devices Software License Agreement.
**/

/***Libraries***/
#include "ADE120x.h"
#include "mbed.h"

#define ADC_PGA ADCPGA_10   /* Choose ADCPGA_1, ADCPGA_2, ADCPGA_5, ADCPGA_10 */
#define V_Gain  0.003832    /* This is the gain of the Resistor divider network 
                               before the input to the ADE1202 */

//Platform IOs and Timers
InterruptIn DOUT1(SDP_GPIO_0);    /* Init pin connected to U0, DOUT0 on EVAL-ADE1202EBZ*/
InterruptIn DOUT2(SDP_GPIO_1);    /* Init pin connected to U0, DOUT1 on EVAL-ADE1202EBZ*/


/* ADE1202 Class defined with SPI */
ADE120x ade1202(SDP_SPI_MOSI, SDP_SPI_MISO, SDP_SPI_SCK, SDP_SPI_CS_A);    //MOSI, MISO, SCLK, /CS

/* Initialize the serial port */
Serial pc(USBTX, USBRX);

uint8_t DOUT1_Status, DOUT2_Status = 0;
float voltage = 0.0; 

/* Interrupt Handlers for DOUT1 and DOUT2 */
void DOUT1_Int()
{
    DOUT1_Status = 1;   
}

void DOUT2_Int()
{
    DOUT2_Status = 1;   
}

/* main() runs in its own thread in the OS */
int main()
{
    uint8_t addr = 0x0;                /* address of ADE120x device from 0x0 to 0xF*/
    uint16_t filter_val;
    uint16_t device_id;
    THRESHCfg_Type thresh_cfg;
    PLOADCfg_Type plload_cfg;
    EnergyMtrCfg_Type enrgymtr_cfg;
    RegisterData_Type reg_data[20];     /* Buffer to read back register settings 
                                          after configuration to confirm values */
    
    /* Intialize interrupts to fire on rising edge*/
    DOUT1.rise(&DOUT1_Int);
    DOUT2.rise(&DOUT2_Int);
    
    /* Initialize Uart with baud rate of 230400*/
    pc.baud(230400);
    pc.printf("ADE1202 Demo Application \n\r");
    
    /* Reset the ADE1202 */
    ade1202.Reset(addr);
    wait_us(100000);

    /* Read back device ID */
    device_id = ade1202.GetDevID(addr);
    if((device_id & DEV_ADE1202) == DEV_ADE1202)
        pc.printf("Device is ADE1202\n");
    else
        pc.printf("Device is ADE1201\n");

    /* Print silicon revision and device address */
    pc.printf("Rev ID is: %d * Device Address is %d \n", ADE120x_RevId(device_id), ADE120x_ChipAddr(device_id));

    /* Unlock the device for programming */
    ade1202.UnLock(addr);
    
    /* Wait some time after unlocking device */
    wait_us(1000);
    
    /* Configure threshold registers and Modes using library function */
    thresh_cfg.BIN_HighThresh = 21.7;         /* 22V */
    thresh_cfg.BIN_LowThresh = 11.5;          /* 12V */
    thresh_cfg.WARNA_HighThresh = 26.1;       /* 26V */
    thresh_cfg.WARNA_LowThresh = 26.1;        /* 26V */
    thresh_cfg.WARNB_HighThresh = 17.4;       /* 17V */
    thresh_cfg.WARNB_LowThresh = 11.5;        /* 11V */
    thresh_cfg.WARNC_HighThresh = 5.8;        /* 5V */
    thresh_cfg.WARNC_LowThresh = 5.8;         /* 5V */
    thresh_cfg.BIN_Mode = Mode_Hysteretic;
    thresh_cfg.WARNA_Mode = Mode_Greater;
    thresh_cfg.WARNB_Mode = Mode_Inbetween;
    thresh_cfg.WARNC_Mode = Mode_LessEqual;
    thresh_cfg.ADCPga = 10;
    thresh_cfg.VGain = V_Gain;
    ade1202.ThresholdCfg(addr, &thresh_cfg);

    /* Step 3: Configure filter values for 3 ms*/
    /* FilterLength = GlitchWidth(us)/(20us)*/
    ade1202.WriteReg(addr, REG_BIN_FILTER, 0x8096);
    /* 5ms filter for WARNx */
    ade1202.WriteReg(addr, REG_WARNA_FILTER, 0x80FA);
    ade1202.WriteReg(addr, REG_WARNB_FILTER, 0x80FA);
    ade1202.WriteReg(addr, REG_WARNC_FILTER, 0x80FA);
    
    /* Step 4: Configure programmable load */
    plload_cfg.ADCPga = 10;
    plload_cfg.enable = CH1_Enable|CH2_Enable; /*Enable for both channels */
    plload_cfg.HighCurrent = 30;    /* 16mA */
    plload_cfg.HighTime = 1000;     /* in us */
    plload_cfg.LowCurrent = 1;      /* 3 mA */
    plload_cfg.mode = LOW_IDLE;
    plload_cfg.VGain = V_Gain;
    plload_cfg.VoltThresh = 3.84;
    ade1202.ProgrammableLoadCfg(addr, &plload_cfg);
    
    /* Step 5: Configure Energy Monitor */
    enrgymtr_cfg.ADCPga = 10;
    enrgymtr_cfg.enable = 0;
    enrgymtr_cfg.VGain = V_Gain;
    enrgymtr_cfg.SampleRate = 20e-6;        /* 10us on ADE1201, 20us on ADE1202 */
    enrgymtr_cfg.WorkingVoltage = 250;
    enrgymtr_cfg.PulseMagnitude = 16;       /* 16mA */
    enrgymtr_cfg.PulseTime = 3;             /* 3ms */
    enrgymtr_cfg.Cooldown_Decr = 5;
    enrgymtr_cfg.Cooldown_TimeStep = COOLDOWN_TS_10us;
    enrgymtr_cfg.Ov_Scale = OV_SCALE_1;
    enrgymtr_cfg.Cooldown_Sec = 5;
    ade1202.EnergyMtrCfg(addr, &enrgymtr_cfg);
    
    /* Set ADC PGA */
    ade1202.SetPgaGain(addr, ADCPGA_10);
    
    /* Lock device after configuring registers */
    ade1202.Lock(addr);//add 100us delay
    wait_us(100);
    ade1202.ClearIntStatus(addr, INTSRC_ALL);
    
    /* Read back and print all register settings after configuration to confirm they are correct*/
    ade1202.GetRegisterData(addr, (RegisterData_Type*)reg_data);
    for(int i = 0; i<20;i++)
        printf("0x%x , 0x%x \n", reg_data[i].reg_addr, reg_data[i].reg_data);
    
    
    /* Enter main program loop and wait for threshold events */
    while(1) {
        uint32_t reg_data, status = 0;
        status = ade1202.GetIntStatus(addr); /* Check status register */
        if(DOUT1_Status)
        {
            /* Interrupt detected on DOUT1 */
            DOUT1_Status = 0;
            reg_data = ade1202.ReadADC(addr, ADC_RAW);
            pc.printf("DOUT1 Interrupt detected! ");
            pc.printf("Status: 0x%x , Voltage: %f \n", status, ade1202.ADCCode2Volt(reg_data, ADC_PGA, V_Gain));
        }
        if(DOUT2_Status)
        {
            /* Interrupt detected on DOUT2 */
            DOUT2_Status = 0;
            reg_data = ade1202.ReadADC(addr, ADC_RAW);
            pc.printf("DOUT2 Interrupt detected! ");
            pc.printf("Status: 0x%x , Voltage: %f \n", status, ade1202.ADCCode2Volt(reg_data, ADC_PGA, V_Gain));
        }
        if(status != 0)
        {
            if((status & INTSRC_WARNA1) == INTSRC_WARNA1)
            {
                reg_data = ade1202.ReadADC(addr, ADC_RAW);
                pc.printf("WARNA Interrupt detected! Voltage > 22V ");
                pc.printf("Status: 0x%x , Voltage: %f \n", status, ade1202.ADCCode2Volt(reg_data, ADC_PGA, V_Gain));
            }
            if((status & INTSRC_WARNB1) == INTSRC_WARNB1)
            {
                reg_data = ade1202.ReadADC(addr, ADC_RAW);
                pc.printf("WARNB Interrupt detected! Voltage in between 11V and 15V ");
                pc.printf("Status: 0x%x , Voltage: %f \n", status, ade1202.ADCCode2Volt(reg_data, ADC_PGA, V_Gain));
            }
            if((status & INTSRC_WARNC1) == INTSRC_WARNC1)
            {
                reg_data = ade1202.ReadADC(addr, ADC_RAW);
                pc.printf("WARNC Interrupt detected! Voltage below 5V");
                pc.printf("Status: 0x%x , Voltage: %f \n", status, ade1202.ADCCode2Volt(reg_data, ADC_PGA, V_Gain));
            }
            ade1202.ClearIntStatus(addr, INTSRC_ALL);
        }
    }
    return 0;
}