Library files for AD1234.

Revision:
1:2eb9d6296ec3
Parent:
0:952a6272c495
Child:
2:f9a986799375
diff -r 952a6272c495 -r 2eb9d6296ec3 ADE120x.cpp
--- a/ADE120x.cpp	Mon Jul 29 16:38:44 2019 +0000
+++ b/ADE120x.cpp	Thu Oct 03 15:05:59 2019 +0000
@@ -0,0 +1,426 @@
+/**  
+ * @file       ADE120x.cpp
+ * @brief      ADE120x library. This file contains all ADE120x library functions. 
+ * @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.
+**/
+
+#include "ADE120x.h"
+
+/*! \mainpage ADE120x Library Introduction
+ * 
+ * # Introduction
+ *
+ * The documentation is for ADE120x library and examples.
+ *    TBD
+ */
+ 
+ 
+ /* Constructor for ADE120x; intializes the SPI interface only */
+ADE120x::ADE120x(   PinName mosi,PinName miso,PinName sclk,PinName cs) : spi_(mosi, miso, sclk), nCS_(cs) {
+                    //5MHz, allowed up to 10MHz
+                    nCS_ = 1;
+                    spi_.frequency(5000000);
+                    spi_.format(16, 3);             
+                }
+
+/**
+  @brief Write to ADE120x register through SPI. 
+  @param addr: The address of the ADE120x device.
+    @param reg_addr: register address 
+    @param data: register data
+  @return received data.
+**/
+void ADE120x::WriteReg(uint8_t addr, uint32_t reg_addr, uint32_t data)
+{
+    int cmd;
+    nCS_ = 0;
+    wait_us(1);
+    cmd = reg_addr * 0x0010 + addr;    //R/nW bit set to 0
+    spi_.write(cmd);
+    spi_.write(data);
+    wait_us(1);
+    nCS_ = 1;
+}
+/**
+  @brief Read ADE120x register through SPI. 
+  @param addr: The address of the ADE120x device.
+    @param reg_addr: register address 
+  @return received data.
+**/
+uint32_t ADE120x::ReadReg(uint8_t addr, uint32_t reg_addr)
+{
+    int cmd;
+    int resp;    
+    nCS_ = 0;
+    wait_us(1);
+    //cmd = REG*0x0020 + 0x18 + addr;    //R/nW bit set to 0
+    cmd = reg_addr*0x0010 + 0x8 + addr;      
+    spi_.write(cmd);
+    resp = spi_.write(0xFFFF);
+    wait_us(1);
+    nCS_ = 1;
+    return resp;
+}
+
+/**
+  @brief Reset ADE120x. 
+  @param addr: The address of the ADE120x device.
+  @return return none.
+**/
+uint8_t ADE120x::Reset(uint8_t addr)
+{
+    UnLock(addr);
+    WriteReg(addr, REG_CTRL, 0x0010);
+    //wait until RSTDONE bit is set
+  while ((ReadReg(addr, REG_INT_STATUS) & INTSRC_RSTDONE) == 0)
+  {  }
+    return 0;
+}
+
+/**
+  @brief Read back device ID. 
+  @param addr: The address of the ADE120x device.
+  @return device ID.
+**/
+uint16_t ADE120x::GetDevID(uint8_t addr)
+{
+    uint16_t response;
+    response = ReadReg(addr, REG_CTRL);
+    return response;
+}
+
+/**
+  @brief Lock ADE120x. When device is locked all register writes are ignored
+  @param addr: The address of the ADE120x device.
+  @return none.
+**/
+void ADE120x::Lock(uint8_t addr)
+{
+    WriteReg(addr, REG_LOCK, DEV_LOCK);
+}
+
+/**
+  @brief Unlock ADE120x. Unlock device before writing to registers
+  @param addr: The address of the ADE120x device.
+  @return none.
+**/
+void ADE120x::UnLock(uint8_t addr)
+{
+    WriteReg(addr, REG_LOCK, DEV_UNLOCK);
+    wait_us(100);
+}
+
+/**
+  @brief Configure interrupt. 
+  @param addr: the address of the ADE120x device.
+    @param IntSrcSel: Interrupt source to enable.
+  @return Status.
+**/
+void ADE120x::SetInt(uint8_t addr, uint16_t IntSrcSel)
+{
+    WriteReg(addr, REG_MASK, IntSrcSel);
+}
+/**
+  @brief Clear interrupt status. 
+  @param addr: the address of the ADE120x device.
+    @param IntSrcSel: Interrupt source to clear.
+  @return Status.
+**/
+void ADE120x::ClearIntStatus(uint8_t addr, uint16_t IntSrcSel)
+{
+    WriteReg(addr, REG_INT_STATUS, IntSrcSel);
+}
+
+/**
+  @brief Get Interrupt Status. 
+  @param addr: the address of the ADE120x device.
+  @return Status.
+**/
+uint16_t ADE120x::GetIntStatus(uint8_t addr)
+{
+    uint16_t status;
+    status = ReadReg(addr, REG_INT_STATUS);
+    return status;
+}
+
+/**
+  @brief Configure ADC PGA gain. 
+  @param addr: the address of the ADE120x device.
+    @param Gain: Select from the following
+                            ADCPGA_1, ADCPGA_2, ADCPGA_5, ADCPGA_10.
+  @return Status.
+**/
+void ADE120x::SetPgaGain(uint8_t addr, uint16_t gain)
+{
+    UnLock(addr);
+    WriteReg(addr, REG_PGA_GAIN, gain);
+    Lock(addr);
+}
+/**
+  @brief Read ADC data. 
+  @param addr: the address of the ADE120x device.
+    @param src: ADC source, ADC_DECIMATOR to select decimator output. ADC_RAW for raw output.
+  @return Status.
+**/
+uint8_t ADE120x::ReadADC(uint8_t addr, int8_t src)
+{
+    uint8_t code;
+    if(src == ADC_DECIMATOR)
+        code = ReadReg(addr, REG_ADCDEC);
+    else
+        code = ReadReg(addr, REG_ADC);
+    return code;
+}
+
+
+/**
+  @brief Convert ADC Code to voltage. 
+  @param ADCCode: ADC code.
+  @param ADCPga: the actual 1.82V reference voltage.
+  @param VOLTAGE_Gain: THe gain factor set by the external resistor divider network 
+  @return Voltage in volt.
+**/
+float ADE120x::ADCCode2Volt(uint32_t ADCCode, uint8_t ADCPga, float VOLTAGE_Gain)
+{
+    float tmp = 0.0;
+    float fVolt = 0.0;
+    tmp = (ADCCode&0xFF);
+    tmp = 1.25 * (tmp/255) / VOLTAGE_Gain;
+    switch(ADCPga)
+    {
+        case ADCPGA_1:
+        fVolt = tmp;
+        break;
+        case ADCPGA_2:
+        fVolt = tmp/2;
+        break;
+        case ADCPGA_5:
+        fVolt = tmp/5; 
+        break;
+        case ADCPGA_10:
+        fVolt = tmp/10; 
+        break;
+        default:break;
+        }
+        return fVolt;
+}
+
+/**
+  @brief Set binary Threshold. 
+  @param addr: the address of the ADE120x device.
+    @param thresh: Threshold value.
+  @return none.
+**/
+void ADE120x::SetBinaryThresh(uint8_t addr, uint16_t thresh)
+{
+    WriteReg(addr, REG_BIN_THR, thresh);
+}
+
+/**
+  @brief Calculate threshold register code. 
+    @param V_Thresh: Threshold value in volts.
+    @param ADCPga: PGA gain value
+    @param V_Gain: Gain of external voltage divider circuit
+  @return 0.
+**/
+uint8_t ADE120x::CalculateThreshCode(float V_Thresh, uint8_t ADCPga, float V_Gain)
+{
+    uint8_t code;
+    float tmp;
+    tmp = (V_Thresh * V_Gain * ADCPga * 255)/1.25 + 0.5;
+    code = (uint8_t)tmp;
+    return code;
+}
+
+/**
+  @brief Configure threshold fvoltage for BIN, WARNA, WARNB and WARNC. 
+    @param addr: the address of the ADE120x device.
+    @param pCfg: Pointer to structure
+  @return 0.
+**/
+uint8_t ADE120x::ThresholdCfg(uint8_t addr, THRESHCfg_Type *pCfg)
+{
+    uint8_t Thresh_H, Thresh_L;
+    uint16_t bin_ctrl, tmp;
+    UnLock(addr);
+    Thresh_H = CalculateThreshCode(pCfg->BIN_HighThresh, pCfg->ADCPga, pCfg->VGain);
+    Thresh_L = CalculateThreshCode(pCfg->BIN_LowThresh, pCfg->ADCPga, pCfg->VGain);
+    WriteReg(addr, REG_BIN_THR, (Thresh_L<<8)|Thresh_H);
+    
+    Thresh_H = CalculateThreshCode(pCfg->WARNA_HighThresh, pCfg->ADCPga, pCfg->VGain);
+    Thresh_L = CalculateThreshCode(pCfg->WARNA_LowThresh, pCfg->ADCPga, pCfg->VGain);
+    WriteReg(addr, REG_WARNA_THR , (Thresh_L<<8)|Thresh_H);
+    
+    Thresh_H = CalculateThreshCode(pCfg->WARNB_HighThresh, pCfg->ADCPga, pCfg->VGain);
+    Thresh_L = CalculateThreshCode(pCfg->WARNB_LowThresh, pCfg->ADCPga, pCfg->VGain);
+    WriteReg(addr, REG_WARNB_THR, (Thresh_L<<8)|Thresh_H);
+    
+    Thresh_H = CalculateThreshCode(pCfg->WARNC_HighThresh, pCfg->ADCPga, pCfg->VGain);
+    Thresh_L = CalculateThreshCode(pCfg->WARNC_LowThresh, pCfg->ADCPga, pCfg->VGain);
+    WriteReg(addr, REG_WARNC_THR, (Thresh_L<<8)|Thresh_H);
+    
+    bin_ctrl = (pCfg->BIN_Mode<<6)|(pCfg->WARNA_Mode<<8)|(pCfg->WARNB_Mode<<10)|(pCfg->WARNC_Mode<<12);
+    tmp = ReadReg(addr, REG_BIN_CTRL);
+    tmp &= 0xFFFF&~(0xFF<<6);
+    WriteReg(addr, REG_BIN_CTRL, tmp|bin_ctrl);
+    tmp = ReadReg(addr, REG_BIN_CTRL);
+    return 0;
+}
+/**
+  @brief Configure programmable load. 
+    @param addr: the address of the ADE120x device.
+    @param pCfg: Pointer to structure
+  @return 0.
+**/
+uint8_t ADE120x::ProgrammableLoadCfg(uint8_t addr, PLOADCfg_Type *pCfg)
+{
+    float tmp;
+    WriteReg(addr, REG_PL_CTRL, pCfg->mode);
+    if(pCfg->mode == LOW_IDLE)
+        WriteReg(addr, REG_PL_RISE_THR, 
+                    CalculateThreshCode(pCfg->VoltThresh, pCfg->ADCPga, pCfg->VGain));
+    
+    tmp = (pCfg->HighCurrent/0.2) + 0.5f; /* add 0.5 to round up */
+   WriteReg(addr, REG_PL_HIGH_CODE, (uint16_t)tmp);
+    
+    tmp = (pCfg->HighTime/10) + 0.5f;
+    WriteReg(addr, REG_PL_HIGH_TIME, (uint16_t)tmp);
+    
+    tmp = (pCfg->LowCurrent/0.1) + 0.5f;
+    WriteReg(addr, REG_PL_LOW_CODE, (uint16_t)tmp);
+    
+    if(pCfg->enable == CH1_Enable)
+        WriteReg(addr, REG_PL_EN, PL_CH1_ENABLE);
+    if(pCfg->enable == CH2_Enable)
+        WriteReg(addr, REG_PL_EN, PL_CH2_ENABLE);
+    if(pCfg->enable == CH1_CH2_Enable)
+        WriteReg(addr, REG_PL_EN, PL_CH2_ENABLE|PL_CH1_ENABLE);
+    if(pCfg->enable == CH1_Disable)
+       WriteReg(addr, REG_PL_EN, 0);
+    
+    return 0;
+}
+
+/**
+  @brief Configure Energy Meter. 
+    @param addr: the address of the ADE120x device.
+    @param pCfg: Pointer to structure
+  @return 0.
+**/
+uint8_t ADE120x::EnergyMtrCfg(uint8_t addr, EnergyMtrCfg_Type *pCfg)
+{
+    float pulse_enrgy, AvgADCCode, tmp;
+    uint16_t reg_val, reg_mtr_ctrl;
+    AvgADCCode = (255*pCfg->WorkingVoltage*pCfg->VGain*pCfg->ADCPga)/1.25;
+    /* Step 1: Calculate pulse energy in Jules: (Pulse time * Working Current * Voltage) / 1000 */
+    pulse_enrgy = (pCfg->PulseMagnitude * pCfg->FET_Energy * pCfg->PulseTime)/1000;
+    
+    /* Step 2: Calculate ENERGY_MTR register value:  */
+    tmp = (AvgADCCode * (pCfg->PulseTime/1000))/(128 * pCfg->SampleRate)+0.5;
+    reg_val = (uint16_t)tmp;
+    WriteReg(addr, REG_EGY_MTR_THR, reg_val);
+
+
+    reg_mtr_ctrl = (pCfg->Cooldown_Decr<<8)|pCfg->Cooldown_Sec|(pCfg->Cooldown_TimeStep<<4)|(pCfg->Ov_Scale<<6);
+    WriteReg(addr, REG_EGY_MTR_CTRL, reg_mtr_ctrl);
+    
+    return 1;
+}
+
+/**
+  @brief Read all ADE120xregisters. 
+  @param addr: the address of the ADE120x device.
+  @return 0.
+**/
+void ADE120x::GetRegisterData(uint8_t addr, RegisterData_Type *pBuff)
+{
+    uint16_t reg_addr[] = {
+        REG_CTRL, 
+        REG_BIN_CTRL,       
+        REG_BIN_THR,        
+        REG_WARNA_THR,          
+        REG_WARNB_THR,     
+        REG_WARNC_THR,      
+        REG_BIN_FILTER,     
+        REG_WARNA_FILTER,   
+        REG_WARNB_FILTER,   
+        REG_WARNC_FILTER,   
+        REG_MASK,          
+        REG_PL_CTRL,        
+        REG_PL_RISE_THR,   
+        REG_PL_LOW_CODE,    
+        REG_PL_HIGH_CODE,   
+        REG_PL_HIGH_TIME,   
+        REG_EGY_MTR_CTRL,   
+        REG_EGY_MTR_THR,    
+        REG_PL_EN, 
+        REG_PGA_GAIN};
+    
+    uint8_t reg_addr_size = sizeof(reg_addr)/sizeof(*reg_addr);
+    uint8_t i = 0;
+    while(i<reg_addr_size)
+    {
+        pBuff[i].reg_addr = reg_addr[i]; 
+        pBuff[i].reg_data = ReadReg(addr, reg_addr[i]);
+        i++;
+        wait_us(1000);     
+    }
+}
+/**
+  @brief Configure Device with default settings. 
+  @param addr: the address of the ADE120x device.
+  @return 0.
+**/
+uint8_t ADE120x::DefaultConfig(uint8_t addr)
+{
+    /** Array defined for configuration ***/   
+    uint16_t config[] = {
+        //REG_CTRL,           0x04,
+       // REG_BIN_CTRL,       0x0000,
+        REG_BIN_THR,        0x757d, // fail
+        REG_WARNA_THR,      0xcccc,     
+        REG_WARNB_THR,      0x5a88,
+        REG_WARNC_THR,      0x2d2d,
+        REG_BIN_FILTER,     BIN_FILTER_VAL, //fail using this register to validate against unintended resets in the DOUT validate
+        REG_WARNA_FILTER,   0x80fa,
+        REG_WARNB_FILTER,   0x80fa,
+        REG_WARNC_FILTER,   0x80fa,
+        REG_MASK,           0x4000,
+        REG_PL_CTRL,        0x0000,
+        REG_PL_RISE_THR,    0x007d, // fail
+        REG_PL_LOW_CODE,    0x001e,
+        REG_PL_HIGH_CODE,   0x000f, // fail
+        REG_PL_HIGH_TIME,   0x0001, // fail
+        REG_EGY_MTR_CTRL,   0x0505,
+        REG_EGY_MTR_THR,    0x9ba3,
+        REG_PL_EN,          0xC000, //fail
+        REG_PGA_GAIN,       ADCPGA_10 };  //fail
+
+    uint8_t config_size = sizeof(config)/sizeof(*config);
+    uint8_t i = 0;
+    int resp;
+    wait_us(10000);  
+    while(i<config_size-1)
+    {
+        WriteReg(addr, config[i], config[i+1]);
+        resp = ReadReg(addr, config[i]);
+        if (resp != config[i+1]) 
+        {
+            printf("Register 0x%x write failed: Expected: 0x%x , Actual: 0x%x \r\n", config[i], config[i+1], resp);
+            return 255; 
+        }
+      //  printf("Register 0x%x write passed: Expected: 0x%x , Actual: 0x%x \r\n", config[i], config[i+1], resp);
+        i+=2;
+        wait_us(1000);     
+    }
+        return 0;
+}