ADE120x Library Files
Embed:
(wiki syntax)
Show/hide line numbers
ADE120x.cpp
Go to the documentation of this file.
00001 /** 00002 @file ADE120x.cpp 00003 @brief ADE120x library. This file contains all ADE120x library functions. 00004 @version V0.0.1 00005 @author ADI 00006 @date October 2019 00007 @par Revision History: 00008 00009 Copyright (c) 2017-2019 Analog Devices, Inc. All Rights Reserved. 00010 00011 This software is proprietary to Analog Devices, Inc. and its licensors. 00012 By using this software you agree to the terms of the associated 00013 Analog Devices Software License Agreement. 00014 *****************************************************************************/ 00015 00016 #include "ADE120x.h" 00017 00018 /* Constructor for ADE120x; intializes the SPI interface only */ 00019 ADE120x::ADE120x( PinName mosi,PinName miso,PinName sclk,PinName cs) : spi_(mosi, miso, sclk), nCS_(cs) { 00020 //5MHz, allowed up to 10MHz 00021 nCS_ = 1; 00022 spi_.frequency(5000000); 00023 spi_.format(16, 3); 00024 } 00025 00026 /** 00027 @brief Write to ADE120x register through SPI. 00028 @param addr: The address of the ADE120x device. 00029 @param reg_addr: register address 00030 @param data: register data 00031 @return received data. 00032 **/ 00033 void ADE120x::WriteReg(uint8_t addr, uint32_t reg_addr, uint32_t data) 00034 { 00035 int cmd; 00036 nCS_ = 0; 00037 wait_us(1); 00038 cmd = reg_addr * 0x0010 + addr; //R/nW bit set to 0 00039 spi_.write(cmd); 00040 spi_.write(data); 00041 wait_us(1); 00042 nCS_ = 1; 00043 } 00044 /** 00045 @brief Read ADE120x register through SPI. 00046 @param addr: The address of the ADE120x device. 00047 @param reg_addr: register address 00048 @return received data. 00049 **/ 00050 uint32_t ADE120x::ReadReg(uint8_t addr, uint32_t reg_addr) 00051 { 00052 int cmd; 00053 int resp; 00054 nCS_ = 0; 00055 wait_us(1); 00056 //cmd = REG*0x0020 + 0x18 + addr; //R/nW bit set to 0 00057 cmd = reg_addr*0x0010 + 0x8 + addr; 00058 spi_.write(cmd); 00059 resp = spi_.write(0xFFFF); 00060 wait_us(1); 00061 nCS_ = 1; 00062 return resp; 00063 } 00064 00065 /** 00066 @brief Reset ADE120x. 00067 @param addr: The address of the ADE120x device. 00068 @return return none. 00069 **/ 00070 uint8_t ADE120x::Reset(uint8_t addr) 00071 { 00072 UnLock(addr); 00073 WriteReg(addr, REG_CTRL, 0x0010); 00074 //wait until RSTDONE bit is set 00075 while ((ReadReg(addr, REG_INT_STATUS) & INTSRC_RSTDONE) == 0) 00076 { } 00077 return 0; 00078 } 00079 00080 /** 00081 @brief Read back device ID. 00082 @param addr: The address of the ADE120x device. 00083 @return device ID. 00084 **/ 00085 uint16_t ADE120x::GetDevID(uint8_t addr) 00086 { 00087 uint16_t response; 00088 response = ReadReg(addr, REG_CTRL); 00089 return response; 00090 } 00091 00092 /** 00093 @brief Lock ADE120x. When device is locked all register writes are ignored 00094 @param addr: The address of the ADE120x device. 00095 @return none. 00096 **/ 00097 void ADE120x::Lock(uint8_t addr) 00098 { 00099 WriteReg(addr, REG_LOCK, DEV_LOCK); 00100 } 00101 00102 /** 00103 @brief Unlock ADE120x. Unlock device before writing to registers 00104 @param addr: The address of the ADE120x device. 00105 @return none. 00106 **/ 00107 void ADE120x::UnLock(uint8_t addr) 00108 { 00109 WriteReg(addr, REG_LOCK, DEV_UNLOCK); 00110 wait_us(100); 00111 } 00112 00113 /** 00114 @brief Configure interrupt. 00115 @param addr: the address of the ADE120x device. 00116 @param IntSrcSel: Interrupt source to enable. 00117 @return Status. 00118 **/ 00119 void ADE120x::SetInt(uint8_t addr, uint16_t IntSrcSel) 00120 { 00121 WriteReg(addr, REG_MASK, IntSrcSel); 00122 } 00123 00124 /** 00125 @brief Clear interrupt status. 00126 @param addr: the address of the ADE120x device. 00127 @param IntSrcSel: Interrupt source to clear. 00128 @return Status. 00129 **/ 00130 void ADE120x::ClearIntStatus(uint8_t addr, uint16_t IntSrcSel) 00131 { 00132 WriteReg(addr, REG_INT_STATUS, IntSrcSel); 00133 } 00134 00135 /** 00136 @brief Get Interrupt Status. 00137 @param addr: the address of the ADE120x device. 00138 @return Status. 00139 **/ 00140 uint16_t ADE120x::GetIntStatus(uint8_t addr) 00141 { 00142 uint16_t status; 00143 status = ReadReg(addr, REG_INT_STATUS); 00144 return status; 00145 } 00146 00147 /** 00148 @brief Configure ADC PGA gain. 00149 @param addr: the address of the ADE120x device. 00150 @param Gain: Select from the following 00151 ADCPGA_1, ADCPGA_2, ADCPGA_5, ADCPGA_10. 00152 @return Status. 00153 **/ 00154 void ADE120x::SetPgaGain(uint8_t addr, uint16_t gain) 00155 { 00156 UnLock(addr); 00157 WriteReg(addr, REG_PGA_GAIN, gain); 00158 Lock(addr); 00159 } 00160 00161 /** 00162 @brief Read ADC data. 00163 @param addr: the address of the ADE120x device. 00164 @param src: ADC source, ADC_DECIMATOR to select decimator output. ADC_RAW for raw output. 00165 @return Status. 00166 **/ 00167 uint8_t ADE120x::ReadADC(uint8_t addr, int8_t src) 00168 { 00169 uint8_t code; 00170 if(src == ADC_DECIMATOR) 00171 code = ReadReg(addr, REG_ADCDEC); 00172 else 00173 code = ReadReg(addr, REG_ADC); 00174 return code; 00175 } 00176 00177 /** 00178 @brief Set binary Threshold. 00179 @param addr: the address of the ADE120x device. 00180 @param thresh: Threshold value. 00181 @return none. 00182 **/ 00183 void ADE120x::SetBinaryThresh(uint8_t addr, uint16_t thresh) 00184 { 00185 WriteReg(addr, REG_BIN_THR, thresh); 00186 } 00187 00188 /** 00189 @brief Calculate threshold register code. 00190 @param V_Thresh: Threshold value in volts. 00191 @param ADCPga: PGA gain value 00192 @param V_Gain: Gain of external voltage divider circuit 00193 @return 0. 00194 **/ 00195 uint8_t ADE120x::CalculateThreshCode(float V_Thresh, uint8_t ADCPga, float V_Gain) 00196 { 00197 uint8_t code; 00198 float tmp; 00199 tmp = (V_Thresh * V_Gain * ADCPga * 255)/1.25 + 0.5; 00200 code = (uint8_t)tmp; 00201 return code; 00202 } 00203 00204 /** 00205 @brief Configure threshold voltage for BIN, WARNA, WARNB and WARNC. 00206 @param addr: the address of the ADE120x device. 00207 @param pCfg: Pointer to structure 00208 @return 0. 00209 **/ 00210 uint8_t ADE120x::ThresholdCfg(uint8_t addr, THRESHCfg_Type *pCfg) 00211 { 00212 uint8_t Thresh_H, Thresh_L; 00213 uint16_t bin_ctrl, tmp; 00214 UnLock(addr); 00215 Thresh_H = CalculateThreshCode(pCfg->BIN_HighThresh, pCfg->ADCPga, pCfg->VGain); 00216 Thresh_L = CalculateThreshCode(pCfg->BIN_LowThresh, pCfg->ADCPga, pCfg->VGain); 00217 WriteReg(addr, REG_BIN_THR, (Thresh_L<<8)|Thresh_H); 00218 00219 Thresh_H = CalculateThreshCode(pCfg->WARNA_HighThresh, pCfg->ADCPga, pCfg->VGain); 00220 Thresh_L = CalculateThreshCode(pCfg->WARNA_LowThresh, pCfg->ADCPga, pCfg->VGain); 00221 WriteReg(addr, REG_WARNA_THR , (Thresh_L<<8)|Thresh_H); 00222 00223 Thresh_H = CalculateThreshCode(pCfg->WARNB_HighThresh, pCfg->ADCPga, pCfg->VGain); 00224 Thresh_L = CalculateThreshCode(pCfg->WARNB_LowThresh, pCfg->ADCPga, pCfg->VGain); 00225 WriteReg(addr, REG_WARNB_THR, (Thresh_L<<8)|Thresh_H); 00226 00227 Thresh_H = CalculateThreshCode(pCfg->WARNC_HighThresh, pCfg->ADCPga, pCfg->VGain); 00228 Thresh_L = CalculateThreshCode(pCfg->WARNC_LowThresh, pCfg->ADCPga, pCfg->VGain); 00229 WriteReg(addr, REG_WARNC_THR, (Thresh_L<<8)|Thresh_H); 00230 00231 bin_ctrl = (pCfg->BIN_Mode<<6)|(pCfg->WARNA_Mode<<8)|(pCfg->WARNB_Mode<<10)|(pCfg->WARNC_Mode<<12); 00232 tmp = ReadReg(addr, REG_BIN_CTRL); 00233 tmp &= 0xFFFF&~(0xFF<<6); 00234 WriteReg(addr, REG_BIN_CTRL, tmp|bin_ctrl); 00235 tmp = ReadReg(addr, REG_BIN_CTRL); 00236 return 0; 00237 } 00238 00239 /** 00240 @brief Configure programmable load. 00241 @param addr: the address of the ADE120x device. 00242 @param pCfg: Pointer to structure 00243 @return 0. 00244 **/ 00245 uint8_t ADE120x::ProgrammableLoadCfg(uint8_t addr, PLOADCfg_Type *pCfg) 00246 { 00247 float tmp; 00248 WriteReg(addr, REG_PL_CTRL, pCfg->mode); 00249 if(pCfg->mode == LOW_IDLE) 00250 WriteReg(addr, REG_PL_RISE_THR, 00251 CalculateThreshCode(pCfg->VoltThresh, pCfg->ADCPga, pCfg->VGain)); 00252 00253 tmp = (pCfg->HighCurrent/0.2) + 0.5f; /* add 0.5 to round up */ 00254 WriteReg(addr, REG_PL_HIGH_CODE, (uint16_t)tmp); 00255 00256 tmp = (pCfg->HighTime/10) + 0.5f; 00257 WriteReg(addr, REG_PL_HIGH_TIME, (uint16_t)tmp); 00258 00259 tmp = (pCfg->LowCurrent/0.1) + 0.5f; 00260 WriteReg(addr, REG_PL_LOW_CODE, (uint16_t)tmp); 00261 00262 if(pCfg->enable == CH1_Enable) 00263 WriteReg(addr, REG_PL_EN, PL_CH1_ENABLE); 00264 if(pCfg->enable == CH2_Enable) 00265 WriteReg(addr, REG_PL_EN, PL_CH2_ENABLE); 00266 if(pCfg->enable == CH1_CH2_Enable) 00267 WriteReg(addr, REG_PL_EN, PL_CH2_ENABLE|PL_CH1_ENABLE); 00268 if(pCfg->enable == CH1_Disable) 00269 WriteReg(addr, REG_PL_EN, 0); 00270 00271 return 0; 00272 } 00273 00274 /** 00275 @brief Configure Energy Meter. 00276 @param addr: the address of the ADE120x device. 00277 @param pCfg: Pointer to structure 00278 @return 0. 00279 **/ 00280 uint8_t ADE120x::EnergyMtrCfg(uint8_t addr, EnergyMtrCfg_Type *pCfg) 00281 { 00282 float pulse_enrgy, AvgADCCode, tmp; 00283 uint16_t reg_val, reg_mtr_ctrl; 00284 AvgADCCode = (255*pCfg->WorkingVoltage*pCfg->VGain*pCfg->ADCPga)/1.25; 00285 /* Step 1: Calculate pulse energy in Jules: (Pulse time * Working Current * Voltage) / 1000 */ 00286 pulse_enrgy = (pCfg->PulseMagnitude * pCfg->FET_Energy * pCfg->PulseTime)/1000; 00287 00288 /* Step 2: Calculate ENERGY_MTR register value: */ 00289 tmp = (AvgADCCode * (pCfg->PulseTime/1000))/(128 * pCfg->SampleRate)+0.5; 00290 reg_val = (uint16_t)tmp; 00291 WriteReg(addr, REG_EGY_MTR_THR, reg_val); 00292 00293 00294 reg_mtr_ctrl = (pCfg->Cooldown_Decr<<8)|pCfg->Cooldown_Sec|(pCfg->Cooldown_TimeStep<<4)|(pCfg->Ov_Scale<<6); 00295 WriteReg(addr, REG_EGY_MTR_CTRL, reg_mtr_ctrl); 00296 00297 return 1; 00298 } 00299 00300 /** 00301 @brief Read all ADE120xregisters. 00302 @param addr: the address of the ADE120x device. 00303 @return 0. 00304 **/ 00305 void ADE120x::GetRegisterData(uint8_t addr, RegisterData_Type *pBuff) 00306 { 00307 uint16_t reg_addr[] = { 00308 REG_CTRL, 00309 REG_BIN_CTRL, 00310 REG_BIN_THR, 00311 REG_WARNA_THR, 00312 REG_WARNB_THR, 00313 REG_WARNC_THR, 00314 REG_BIN_FILTER, 00315 REG_WARNA_FILTER, 00316 REG_WARNB_FILTER, 00317 REG_WARNC_FILTER, 00318 REG_MASK, 00319 REG_PL_CTRL, 00320 REG_PL_RISE_THR, 00321 REG_PL_LOW_CODE, 00322 REG_PL_HIGH_CODE, 00323 REG_PL_HIGH_TIME, 00324 REG_EGY_MTR_CTRL, 00325 REG_EGY_MTR_THR, 00326 REG_PL_EN, 00327 REG_PGA_GAIN}; 00328 00329 uint8_t reg_addr_size = sizeof(reg_addr)/sizeof(*reg_addr); 00330 uint8_t i = 0; 00331 while(i<reg_addr_size) 00332 { 00333 pBuff[i].reg_addr = reg_addr[i]; 00334 pBuff[i].reg_data = ReadReg(addr, reg_addr[i]); 00335 i++; 00336 wait_us(1000); 00337 } 00338 } 00339 00340 /** 00341 @brief Convert ADC Code to voltage. 00342 @param ADCCode: ADC code. 00343 @param ADCPga: the actual 1.82V reference voltage. 00344 @param VOLTAGE_Gain: THe gain factor set by the external resistor divider network 00345 @return Voltage in volt. 00346 **/ 00347 float ADE120x::ADCCode2Volt(uint32_t ADCCode, uint8_t ADCPga, float VOLTAGE_Gain) 00348 { 00349 float tmp = 0.0; 00350 float fVolt = 0.0; 00351 tmp = (ADCCode&0xFF); 00352 tmp = 1.25 * (tmp/255) / VOLTAGE_Gain; 00353 switch(ADCPga) 00354 { 00355 case ADCPGA_1: 00356 fVolt = tmp; 00357 break; 00358 case ADCPGA_2: 00359 fVolt = tmp/2; 00360 break; 00361 case ADCPGA_5: 00362 fVolt = tmp/5; 00363 break; 00364 case ADCPGA_10: 00365 fVolt = tmp/10; 00366 break; 00367 default:break; 00368 } 00369 return fVolt; 00370 }
Generated on Fri Jul 15 2022 13:17:29 by 1.7.2