add net manager
This commit is contained in:
1127
components/meter_manager/driver/meter_ade7758/ade7758.c
Executable file
1127
components/meter_manager/driver/meter_ade7758/ade7758.c
Executable file
File diff suppressed because it is too large
Load Diff
455
components/meter_manager/driver/meter_ade7758/ade7758.h
Executable file
455
components/meter_manager/driver/meter_ade7758/ade7758.h
Executable file
@@ -0,0 +1,455 @@
|
||||
#include "driver/spi_common.h"
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
|
||||
|
||||
#define WRITE 0x80 // WRITE bit BT7 to write to registers
|
||||
#define CLKIN 10000000 // ADE7758 frec, 10.000000MHz
|
||||
#define PERIODO 50 // Actually it is frequency, it is used to calculate the amount of Cycles that it accumulates for energy.
|
||||
#define PHASE_A 1
|
||||
#define PHASE_B 2
|
||||
#define PHASE_C 3
|
||||
|
||||
|
||||
//Register address
|
||||
|
||||
//------Name--------Address---------Lenght
|
||||
#define AWATTHR 0x01 //---------16
|
||||
#define BWATTHR 0x02 //---------16
|
||||
#define CWATTHR 0x03 //---------16
|
||||
|
||||
#define AVARHR 0x04 //---------16
|
||||
#define BVARHR 0x05 //---------16
|
||||
#define CVARHR 0x06 //---------16
|
||||
|
||||
#define AVAHR 0x07 //---------16
|
||||
#define BVAHR 0x08 //---------16
|
||||
#define CVAHR 0x09 //---------16
|
||||
|
||||
#define AIRMS 0x0A //---------24
|
||||
#define BIRMS 0x0B //---------24
|
||||
#define CIRMS 0x0C //---------24
|
||||
|
||||
#define AVRMS 0x0D //---------24
|
||||
#define BVRMS 0x0E //---------24
|
||||
#define CVRMS 0x0F //---------24
|
||||
|
||||
#define FREQ 0x10 //---------12
|
||||
#define TEMP 0x11 //---------8
|
||||
#define WFORM 0x12 //---------24
|
||||
#define OPMODE 0x13 //---------8
|
||||
#define MMODE 0x14 //---------8
|
||||
#define WAVMODE 0x15 //---------8
|
||||
#define COMPMODE 0x16 //---------8
|
||||
#define LCYCMODE 0x17 //---------8
|
||||
#define MASK 0x18 //---------24
|
||||
#define STATUS 0x19 //---------24
|
||||
#define RSTATUS 0x1A //---------24
|
||||
#define ZXTOUT 0x1B //---------16
|
||||
#define LINECYC 0x1C //---------16
|
||||
#define SAGCYC 0x1D //---------8
|
||||
#define SAGLVL 0x1E //---------8
|
||||
#define VPINTLVL 0x1F //---------8
|
||||
#define IPINTLVL 0x20 //---------8
|
||||
#define VPEAK 0x21 //---------8
|
||||
#define IPEAK 0x22 //---------8
|
||||
#define GAIN 0x23 //---------8
|
||||
#define AVRMSGAIN 0x24 //---------12
|
||||
#define BVRMSGAIN 0x25 //---------12
|
||||
#define CVRMSGAIN 0x26 //---------12
|
||||
#define AIGAIN 0x27 //---------12
|
||||
#define BIGAIN 0x28 //---------12
|
||||
#define CIGAIN 0x29 //---------12
|
||||
#define AWG 0x2A //---------12
|
||||
#define BWG 0x2B //---------12
|
||||
#define CWG 0x2C //---------12
|
||||
#define AVARG 0x2D //---------12
|
||||
#define BVARG 0x2E //---------12
|
||||
#define CVARG 0x2F //---------12
|
||||
#define AVAG 0x30 //---------12
|
||||
#define BVAG 0X31 //---------12
|
||||
#define CVAG 0x32 //---------12
|
||||
#define AVRMSOS 0x33 //---------12
|
||||
#define BVRMSOS 0X34 //---------12
|
||||
#define CVRMSOS 0X35 //---------12
|
||||
#define AIRMSOS 0X36 //---------12
|
||||
#define BIRMSOS 0X37 //---------12
|
||||
#define CIRMSOS 0X38 //---------12
|
||||
#define AWATTOS 0X39 //---------12
|
||||
#define BWATTOS 0X3A //---------12
|
||||
#define CWATTOS 0X3B //---------12
|
||||
#define AVAROS 0X3C //---------12
|
||||
#define BVAROS 0X3D //---------12
|
||||
#define CVAROS 0X3E //---------12
|
||||
#define APHCAL 0X3F //---------7
|
||||
#define BPHCAL 0X40 //---------7
|
||||
#define CPHCAL 0X41 //---------7
|
||||
#define WDIV 0X42 //---------8
|
||||
#define VARDIV 0X43 //---------8
|
||||
#define VADIV 0X44 //---------8
|
||||
#define APCFNUM 0X45 //---------16
|
||||
#define APCFDEN 0X46 //---------12
|
||||
#define VARCFNUM 0X47 //---------16
|
||||
#define VARCFDEN 0X48 //---------12
|
||||
|
||||
#define CHKSUM 0X7E //---------8
|
||||
#define VERSION 0x7f //---------8
|
||||
#define DUMMY_BYTE 0xFF
|
||||
|
||||
|
||||
//bits
|
||||
|
||||
/**
|
||||
OPERATIONAL MODE REGISTER (0x13)
|
||||
The general configuration of the ADE7758 is defined by writing to the OPMODE register.
|
||||
Table 18 summarizes the functionality of each bit in the OPMODE register.
|
||||
|
||||
Bit Location Bit Mnemonic Default Value Description
|
||||
0 DISHPF 0 The HPFs in all current channel inputs are disabled when this bit is set.
|
||||
1 DISLPF 0 The LPFs after the watt and VAR multipliers are disabled when this bit is set.
|
||||
2 DISCF 1 The frequency outputs APCF and VARCF are disabled when this bit is set.
|
||||
3 to 5 DISMOD 0 By setting these bits, ADE7758<35>s ADCs can be turned off. In normal operation, these bits should be left at Logic 0.
|
||||
DISMOD[2:0] Description
|
||||
0 0 0 Normal operation.
|
||||
1 0 0 Redirect the voltage inputs to the signal paths for the current channels and the current inputs to the signal paths for the voltage channels.
|
||||
0 0 1 Switch off only the current channel ADCs.
|
||||
1 0 1 Switch off current channel ADCs and redirect the current input signals to the voltage channel signal paths.
|
||||
0 1 0 Switch off only the voltage channel ADCs.
|
||||
1 1 0 Switch off voltage channel ADCs and redirect the voltage input signals to the current channel signal paths.
|
||||
0 1 1 Put the ADE7758 in sleep mode.
|
||||
1 1 1 Put the ADE7758 in power-down mode (reduces AIDD to 1 mA typ).
|
||||
6 SWRST 0 Software Chip Reset. A data transfer to the ADE7758 should not take place for at least 18 <20>s after a software reset.
|
||||
7 RESERVED 0 This should be left at 0.
|
||||
|
||||
*/
|
||||
|
||||
#define DISHPF 0x01
|
||||
#define DISLPF 0x02
|
||||
#define DISCF 0x04
|
||||
#define SWRST 0x40
|
||||
|
||||
/**
|
||||
MEASUREMENT MODE REGISTER (0x14)
|
||||
The configuration of the PERIOD and peak measurements made by the ADE7758 is defined by writing to the MMODE register.
|
||||
Table 19 summarizes the functionality of each bit in the MMODE register.
|
||||
|
||||
Bit Location Bit Mnemonic Default Value Description
|
||||
0 to 1 FREQSEL 0 These bits are used to select the source of the measurement of the voltage line frequency.
|
||||
FREQSEL1 FREQSEL0 Source
|
||||
0 0 Phase A
|
||||
0 1 Phase B
|
||||
1 0 Phase C
|
||||
1 1 Reserved
|
||||
2 to 4 PEAKSEL 7 These bits select the phases used for the voltage and current peak registers.
|
||||
Setting Bit 2 switches the IPEAK and VPEAK registers to hold the absolute values
|
||||
of the largest current and voltage waveform (over a fixed number of half-line cycles)
|
||||
from Phase A. The number of half-line cycles is determined by the content of the
|
||||
LINECYC register. At the end of the LINECYC number of half-line cycles, the content
|
||||
of the registers is replaced with the new peak values. Similarly, setting Bit 3 turns
|
||||
on the peak detection for Phase B, and Bit 4 for Phase C. Note that if more than one
|
||||
bit is set, the VPEAK and IPEAK registers can hold values from two different phases, that is,
|
||||
the voltage and current peak are independently processed (see the Peak Current Detection section).
|
||||
5 to 7 PKIRQSEL 7 These bits select the phases used for the peak interrupt detection.
|
||||
Setting Bit 5 switches on the monitoring of the absolute current and voltage waveform to Phase A.
|
||||
Similarly, setting Bit 6 turns on the waveform detection for Phase B, and Bit 7 for Phase C.
|
||||
Note that more than one bit can be set for detection on multiple phases.
|
||||
If the absolute values of the voltage or current waveform samples in the selected phases exceeds
|
||||
the preset level specified in the VPINTLVL or IPINTLVL registers the corresponding bit(s) in the
|
||||
STATUS registers are set (see the Peak Current Detection section).
|
||||
|
||||
*/
|
||||
|
||||
#define FREQSEL0 0x01
|
||||
#define FREQSEL1 0x02
|
||||
|
||||
|
||||
/**
|
||||
WAVEFORM MODE REGISTER (0x15)
|
||||
The waveform sampling mode of the ADE7758 is defined by writing to the WAVMODE register.
|
||||
Table 20 summarizes the functionality of each bit in the WAVMODE register.
|
||||
|
||||
Bit Location Bit Mnemonic Default Value Description
|
||||
0 to 1 PHSEL 0 These bits are used to select the phase of the waveform sample.
|
||||
PHSEL[1:0] Source
|
||||
0 0 Phase A
|
||||
0 1 Phase B
|
||||
1 0 Phase C
|
||||
1 1 Reserved
|
||||
2 to 4 WAVSEL 0 These bits are used to select the type of waveform.
|
||||
WAVSEL[2:0] Source
|
||||
0 0 0 Current
|
||||
0 0 1 Voltage
|
||||
0 1 0 Active Power Multiplier Output
|
||||
0 1 1 Reactive Power Multiplier Output
|
||||
1 0 0 VA Multiplier Output
|
||||
-Others- Reserved
|
||||
5 to 6 DTRT 0 These bits are used to select the data rate.
|
||||
DTRT[1:0] Update Rate
|
||||
0 0 26.04 kSPS (CLKIN/3/128)
|
||||
0 1 13.02 kSPS (CLKIN/3/256)
|
||||
1 0 6.51 kSPS (CLKIN/3/512)
|
||||
1 1 3.25 kSPS (CLKIN/3/1024)
|
||||
7 VACF 0 Setting this bit to Logic 1 switches the VARCF output pin to an output
|
||||
frequency that is proportional to the total apparent power (VA).
|
||||
In the default state, Logic 0, the VARCF pin outputs a frequency proportional
|
||||
to the total reactive power (VAR).
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
COMPUTATIONAL MODE REGISTER (0x16)
|
||||
The computational method of the ADE7758 is defined by writing to the COMPMODE register.
|
||||
|
||||
Bit Location Bit Mnemonic Default Value Description
|
||||
0 to 1 CONSEL 0 These bits are used to select the input to the energy accumulation registers.
|
||||
CONSEL[1:0] = 11 is reserved. IA, IB, and IC are IA, IB, and IC phase shifted by <20>90<39>, respectively.
|
||||
Registers CONSEL[1, 0] = 00 CONSEL[1, 0] = 01 CONSEL[1, 0] = 10
|
||||
AWATTHR VA <20> IA VA <20> (IA <20> IB) VA <20> (IA<49>IB)
|
||||
BWATTHR VB <20> IB 0 0
|
||||
CWATTHR VC <20> IC VC <20> (IC <20> IB) VC <20> IC
|
||||
|
||||
AVARHR VA <20> IA VA <20> (IA <20> IB) VA <20> (IA<49>IB)
|
||||
BVARHR VB <20> IB 0 0
|
||||
CVARHR VC <20> IC VC <20> (IC <20> IB) VC <20> IC
|
||||
|
||||
AVAHR VARMS <20> IARMS VARMS <20> IARMS VARMS <20> ARMS
|
||||
BVAHR VBRMS <20> IBRMS (VARMS + VCRMS)/2 <20> IBRMS VARMS <20> IBRMS
|
||||
CVAHR VCRMS <20> ICRMS VCRMS <20> ICRMS VCRMS <20> ICRMS
|
||||
|
||||
2 to 4 TERMSEL 7 These bits are used to select the phases to be included in the APCF and VARCF pulse outputs.
|
||||
Setting Bit 2 selects Phase A (the inputs to AWATTHR and AVARHR registers) to be included.
|
||||
Bit 3 and Bit 4 are for Phase B and Phase C, respectively.
|
||||
Setting all three bits enables the sum of all three phases to be included in the frequency outputs
|
||||
(see the Active Power Frequency Output and the Reactive Power Frequency Output sections).
|
||||
|
||||
5 ABS 0 Setting this bit places the APCF output pin in absolute only mode.
|
||||
Namely, the APCF output frequency is proportional to the sum of the absolute values of the watt-hour
|
||||
accumulation registers (AWATTHR, BWATTHR, and CWATTHR).
|
||||
Note that this bit only affects the APCF pin and has no effect on the content of the corresponding
|
||||
registers.
|
||||
|
||||
6 SAVAR 0 Setting this bit places the VARCF output pin in the signed adjusted mode.
|
||||
Namely, the VARCF output frequency is proportional to the sign-adjusted sum of the VAR-hour accumulation
|
||||
registers (AVARHR, BVARHR, and CVARHR).
|
||||
The sign of the VAR is determined from the sign of the watt calculation from the corresponding phase,
|
||||
that is, the sign of the VAR is flipped if the sign of the watt is negative, and if the watt is positive,
|
||||
there is no change to the sign of the VAR.
|
||||
Note that this bit only affects the VARCF pin and has no effect on the content of the corresponding
|
||||
registers.
|
||||
|
||||
7 NOLOAD 0 Setting this bit activates the no-load threshold in the ADE7758.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
LINE CYCLE ACCUMULATION MODE REGISTER (0x17)
|
||||
The functionalities involved the line-cycle accumulation mode in the ADE7758 are defined by writing to the LCYCMODE register.
|
||||
|
||||
Bit Location Bit Mnemonic Default Value Description
|
||||
|
||||
0 LWATT 0 Setting this bit places the watt-hour accumulation registers
|
||||
(AWATTHR, BWATTHR, and CWATTHR registers) into line-cycle accumulation mode.
|
||||
1 LVAR 0 Setting this bit places the VAR-hour accumulation registers (AVARHR, BVARHR, and CVARHR registers)
|
||||
into line-cycle accumulation mode.
|
||||
2 LVA 0 Setting this bit places the VA-hour accumulation registers (AVAHR, BVAHR, and CVAHR registers)
|
||||
into line-cycle accumulation mode.
|
||||
3 to 5 ZXSEL 7 These bits select the phases used for counting the number of zero crossings in the line-cycle
|
||||
accumulation mode. Bit 3, Bit 4, and Bit 5 select Phase A, Phase B, and Phase C, respectively.
|
||||
More than one phase can be selected for the zero-crossing detection,
|
||||
and the accumulation time is shortened accordingly.
|
||||
6 RSTREAD 1 Setting this bit enables the read-with-reset for all the WATTHR, VARHR, and VAHR registers for all three
|
||||
phases, that is, a read to those registers resets the registers to 0 after the content of the registers
|
||||
have been read. This bit should be set to Logic 0 when the LWATT, LVAR, or LVA bits are set to Logic 1.
|
||||
7 FREQSEL 0 Setting this bit causes the FREQ (0x10) register to display the period, instead of the frequency of the
|
||||
line input.
|
||||
*/
|
||||
|
||||
|
||||
#define LWATT 0x01
|
||||
#define LVAR 0x02
|
||||
#define LVA 0x04
|
||||
#define ZXSEL_A 0x08
|
||||
#define ZXSEL_B 0x10
|
||||
#define ZXSEL_C 0x20
|
||||
#define RSTREAD 0x40
|
||||
#define FREQSEL 0x80
|
||||
|
||||
|
||||
|
||||
/** INTERRUPT MASK REGISTER (0x18)
|
||||
When an interrupt event occurs in the ADE7758, the IRQ logic output goes active low if the mask bit for this event is Logic 1 in the MASK register.
|
||||
The IRQ logic output is reset to its default collector open state when the RSTATUS register is read.
|
||||
describes the function of each bit in the interrupt mask register.
|
||||
**/
|
||||
|
||||
// The next table summarizes the function of each bit for
|
||||
// the Interrupt Enable Register
|
||||
|
||||
/* Bit Mask // Bit Location / Description
|
||||
#define AEHF 0x0001 // bit 0 - Enables an interrupt when there is a change in Bit 14 of any one of the three WATTHR registers, that is, the WATTHR register is half full.
|
||||
#define REHF 0x0002 // bit 1 - Enables an interrupt when there is a change in Bit 14 of any one of the three VARHR registers, that is, the VARHR register is half full.
|
||||
#define VAEHF 0x0004 // bit 2 - Enables an interrupt when there is a 0 to 1 transition in the MSB of any one of the three VAHR registers, that is, the VAHR register is half full.
|
||||
#define SAGA 0x0008 // bit 3 - Enables an interrupt when there is a SAG on the line voltage of the Phase A.
|
||||
#define SAGB 0x0010 // bit 4 - Enables an interrupt when there is a SAG on the line voltage of the Phase B.
|
||||
#define SAGC 0x0020 // bit 5 - Enables an interrupt when there is a SAG on the line voltage of the Phase C.
|
||||
#define ZXTOA 0x0040 // bit 6 - Enables an interrupt when there is a zero-crossing timeout detection on Phase A.
|
||||
#define ZXTOB 0x0080 // bit 7 - Enables an interrupt when there is a zero-crossing timeout detection on Phase B.
|
||||
#define ZXTOC 0x0100 // bit 8 - Enables an interrupt when there is a zero-crossing timeout detection on Phase C.
|
||||
#define ZXA 0x0200 // bit 9 - Enables an interrupt when there is a zero crossing in the voltage channel of Phase A
|
||||
#define ZXB 0x0400 // bit 10 - Enables an interrupt when there is a zero crossing in the voltage channel of Phase B
|
||||
#define ZXC 0x0800 // bit 11 - Enables an interrupt when there is a zero crossing in the voltage channel of Phase C
|
||||
#define LENERGY 0x1000 // bit 12 - Enables an interrupt when the energy accumulations over LINECYC are finished.
|
||||
//RESERVED 0x2000 // bit 13 - RESERVED
|
||||
#define PKV 0x4000 // bit 14 - Enables an interrupt when the voltage input selected in the MMODE register is above the value in the VPINTLVL register.
|
||||
#define PKI 0x8000 // bit 15 - Enables an interrupt when the current input selected in the MMODE register is above the value in the IPINTLVL register.
|
||||
#define WFSM 0x010000 // bit 16 - Enables an interrupt when data is present in the WAVEMODE register.
|
||||
#define REVPAP 0x020000 // bit 17 - Enables an interrupt when there is a sign change in the watt calculation among any one of the phases specified by the TERMSEL bits in the COMPMODE register.
|
||||
#define REVPRP 0x040000 // bit 18 - Enables an interrupt when there is a sign change in the VAR calculation among any one of the phases specified by the TERMSEL bits in the COMPMODE register.
|
||||
#define SEQERR 0x080000 // bit 19 - Enables an interrupt when the zero crossing from Phase A is followed not by the zero crossing of Phase C but with that of Phase B.
|
||||
*/
|
||||
/** INTERRUPT STATUS REGISTER (0x19)/RESET INTERRUPT STATUS REGISTER (0x1A)
|
||||
The interrupt status register is used to determine the source of an interrupt event.
|
||||
When an interrupt event occurs in the ADE7758, the corresponding flag in the interrupt status register is set.
|
||||
The IRQ pin goes active low if the corresponding bit in the interrupt mask register is set.
|
||||
When the MCU services the interrupt, it must first carry out a read from the interrupt status register to determine the source of the interrupt.
|
||||
All the interrupts in the interrupt status register stay at their logic high state after an event occurs.
|
||||
The state of the interrupt bit in the interrupt status register is reset to its default value once the reset interrupt status register is read.
|
||||
**/
|
||||
|
||||
// The next table summarizes the function of each bit for
|
||||
// the Interrupt Status Register, the Reset Interrupt Status Register.
|
||||
|
||||
// Bit Mask // Bit Location / Description
|
||||
#define AEHF 0x0001 // bit 0 - Indicates that an interrupt was caused by a change in Bit 14 among any one of the three WATTHR registers, that is, the WATTHR register is half full.
|
||||
#define REHF 0x0002 // bit 1 - Indicates that an interrupt was caused by a change in Bit 14 among any one of the three VARHR registers, that is, the VARHR register is half full.
|
||||
#define VAEHF 0x0004 // bit 2 - Indicates that an interrupt was caused by a 0 to 1 transition in Bit 15 among any one of the three VAHR registers, that is, the VAHR register is half full.
|
||||
#define SAGA 0x0008 // bit 3 - Indicates that an interrupt was caused by a SAG on the line voltage of the Phase A.
|
||||
#define SAGB 0x0010 // bit 4 - Indicates that an interrupt was caused by a SAG on the line voltage of the Phase B.
|
||||
#define SAGC 0x0020 // bit 5 - Indicates that an interrupt was caused by a SAG on the line voltage of the Phase C.
|
||||
#define ZXTOA 0x0040 // bit 6 - Indicates that an interrupt was caused by a missing zero crossing on the line voltage of the Phase A.
|
||||
#define ZXTOB 0x0080 // bit 7 - Indicates that an interrupt was caused by a missing zero crossing on the line voltage of the Phase B.
|
||||
#define ZXTOC 0x0100 // bit 8 - Indicates that an interrupt was caused by a missing zero crossing on the line voltage of the Phase C
|
||||
#define ZXA 0x0200 // bit 9 - Indicates a detection of a rising edge zero crossing in the voltage channel of Phase A.
|
||||
#define ZXB 0x0400 // bit 10 - Indicates a detection of a rising edge zero crossing in the voltage channel of Phase B
|
||||
#define ZXC 0x0800 // bit 11 - Indicates a detection of a rising edge zero crossing in the voltage channel of Phase C
|
||||
#define LENERGY 0x1000 // bit 12 - In line energy accumulation, indicates the end of an integration over an integer number of half- line cycles (LINECYC). See the Calibration section.
|
||||
#define RESET 0x2000 // bit 13 - Indicates that the 5 V power supply is below 4 V. Enables a software reset of the ADE7758 and sets the registers back to their default values. This bit in the STATUS or RSTATUS register is logic high for only one clock cycle after a reset event.
|
||||
#define PKV 0x4000 // bit 14 - Indicates that an interrupt was caused when the selected voltage input is above the value in the VPINTLVL register.
|
||||
#define PKI 0x8000 // bit 15 - Indicates that an interrupt was caused when the selected current input is above the value in the IPINTLVL register.
|
||||
#define WFSM 0x010000 // bit 16 - Indicates that new data is present in the waveform register.
|
||||
#define REVPAP 0x020000 // bit 17 - Indicates that an interrupt was caused by a sign change in the watt calculation among any one of the phases specified by the TERMSEL bits in the COMPMODE register.
|
||||
#define REVPRP 0x040000 // bit 18 - Indicates that an interrupt was caused by a sign change in the VAR calculation among any one of the phases specified by the TERMSEL bits in the COMPMODE register.
|
||||
#define SEQERR 0x080000 // bit 19 - Indicates that an interrupt was caused by a zero crossing from Phase A followed not by the zero crossing of Phase C but by that of Phase B.
|
||||
|
||||
|
||||
//constants
|
||||
#define GAIN_1 0x00
|
||||
#define GAIN_2 0x01
|
||||
#define GAIN_4 0x02
|
||||
#define INTEGRATOR_ON 1
|
||||
#define INTEGRATOR_OFF 0
|
||||
#define FULLSCALESELECT_0_5V 0x00
|
||||
#define FULLSCALESELECT_0_25V 0x01
|
||||
#define FULLSCALESELECT_0_125V 0x02
|
||||
|
||||
esp_err_t transferByte(const uint8_t reg_addr, const uint8_t data, const uint8_t command);
|
||||
esp_err_t transferMultiplesBytes(const uint8_t reg_addr, uint8_t *tx_buf, uint8_t *rx_buf, size_t data_length, const uint8_t command);
|
||||
|
||||
esp_err_t Init(const spi_host_device_t spi_peripheral, const int pin_miso, const int pin_mosi, const int pin_sclk);
|
||||
esp_err_t InitSpi(const int ss);
|
||||
|
||||
esp_err_t RegisterDevice(const uint8_t mode, const int ss, const int addr_length, const int command_length, const int bus_speed);
|
||||
uint8_t ReadRegister(const uint8_t reg_addr, const uint8_t command);
|
||||
esp_err_t WriteRegister(const uint8_t reg_addr, const uint8_t reg_data, const uint8_t command);
|
||||
esp_err_t WriteRegisterMultipleBytes(const uint8_t reg_addr, uint8_t *reg_data_buffer, const uint8_t byte_count, const uint8_t command);
|
||||
esp_err_t ReadRegisterMultipleBytes(const uint8_t reg_addr, uint8_t *reg_data_buffer, const uint8_t byte_count, const uint8_t command);
|
||||
spi_device_handle_t GetHandle();
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Modes and configurations
|
||||
//----------------------------------------------------------------------------
|
||||
void setOpMode(uint8_t m);
|
||||
uint8_t getOpMode();
|
||||
void setMMode(uint8_t m);
|
||||
uint8_t getMMode();
|
||||
void setWavMode(uint8_t m);
|
||||
uint8_t getWavMode();
|
||||
void setCompMode(uint8_t m);
|
||||
uint8_t getCompMode();
|
||||
void setLcycMode(uint8_t m);
|
||||
uint8_t getLcycMode();
|
||||
void gainSetup(uint8_t integrator, uint8_t scale, uint8_t PGA2, uint8_t PGA1);
|
||||
void setupDivs(uint8_t Watt_div,uint8_t VAR_div,uint8_t VA_div);
|
||||
uint32_t getMaskInterrupts();
|
||||
void setMaskInterrupts(uint32_t m);
|
||||
uint32_t getStatus();
|
||||
uint32_t resetStatus();
|
||||
int32_t getAIRMS();
|
||||
int32_t getBIRMS();
|
||||
int32_t getCIRMS();
|
||||
int32_t getAVRMS();
|
||||
int32_t getBVRMS();
|
||||
int32_t getCVRMS();
|
||||
uint32_t avrms();
|
||||
uint32_t bvrms();
|
||||
uint32_t cvrms();
|
||||
uint32_t airms();
|
||||
uint32_t birms();
|
||||
int32_t cirms();
|
||||
int32_t getFreq();
|
||||
void setLineCyc(uint32_t d);
|
||||
int32_t getACurrentOffset();
|
||||
int32_t getBCurrentOffset();
|
||||
int32_t getCCurrentOffset();
|
||||
void setACurrentOffset(int32_t o);
|
||||
void setBCurrentOffset(int32_t o);
|
||||
void setCCurrentOffset(int32_t o);
|
||||
int32_t getAVoltageOffset();
|
||||
int32_t getBVoltageOffset();
|
||||
int32_t getCVoltageOffset();
|
||||
void setAVoltageOffset(int32_t o);
|
||||
void setBVoltageOffset(int32_t o);
|
||||
void setCVoltageOffset(int32_t o);
|
||||
void setAWattOffset(int32_t o);
|
||||
void setBWattOffset(int32_t o);
|
||||
void setCWattOffset(int32_t o);
|
||||
void setZeroCrossingTimeout(int32_t d);
|
||||
int32_t getZeroCrossingTimeout();
|
||||
uint8_t setPotLine(uint8_t Phase, uint32_t Ciclos);
|
||||
int32_t getWatt(uint8_t Phase);
|
||||
int32_t getVar(uint8_t Phase);
|
||||
int32_t getVa(uint8_t Phase);
|
||||
uint8_t getVersion();
|
||||
uint8_t read8(uint8_t reg);
|
||||
uint32_t read16(uint8_t reg);
|
||||
uint32_t read24(uint8_t reg);
|
||||
|
||||
esp_err_t write24(uint8_t reg, uint32_t data);
|
||||
esp_err_t write16(uint8_t reg, uint32_t data);
|
||||
esp_err_t write8(uint8_t reg, uint8_t data);
|
||||
|
||||
void enableADE7758Chip();
|
||||
void disableADE7758Chip();
|
||||
void setAPCFDEN(int32_t d);
|
||||
int32_t getAPCFDEN();
|
||||
void setAPCFNUM(int32_t d);
|
||||
int32_t getAPCFNUM();
|
||||
void setVARCFNUM(int32_t d);
|
||||
int32_t getVARCFNUM();
|
||||
void setVARCFDEN(int32_t d);
|
||||
int32_t getVARCFDEN();
|
||||
void setAWG(int32_t d);
|
||||
int32_t getAWG();
|
||||
void setBWG(int32_t d);
|
||||
void setCWG(int32_t d);
|
||||
void setAVARG(int32_t d);
|
||||
int32_t getAVARG();
|
||||
void setBVARG(int32_t d);
|
||||
int32_t getBVARG();
|
||||
void setCVARG(int32_t d);
|
||||
int32_t getCVARG();
|
||||
void setAVAG(int32_t d);
|
||||
void setBVAG(int32_t d);
|
||||
void setCVAG(int32_t d);
|
||||
176
components/meter_manager/driver/meter_ade7758/meter_ade7758.c
Executable file
176
components/meter_manager/driver/meter_ade7758/meter_ade7758.c
Executable file
@@ -0,0 +1,176 @@
|
||||
#include "meter_ade7758.h"
|
||||
#include "ade7758.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "driver/spi_master.h"
|
||||
|
||||
#define TAG "meter_ade7758"
|
||||
|
||||
// === Configurações de hardware ===
|
||||
#define PIN_NUM_CLK 15
|
||||
#define PIN_NUM_MOSI 2
|
||||
#define PIN_NUM_MISO 4
|
||||
#define PIN_NUM_CS 23
|
||||
#define EEPROM_HOST HSPI_HOST
|
||||
|
||||
// === Constantes de calibração ===
|
||||
#define VRMS_CAL 4732.78f
|
||||
#define IRMS_CAL 53416.0f
|
||||
|
||||
#define METER_READ_INTERVAL_MS 5000
|
||||
|
||||
// === Dados internos ===
|
||||
typedef struct {
|
||||
float vrms[3];
|
||||
float irms[3];
|
||||
int watt[3];
|
||||
int var[3]; // reservados
|
||||
int va[3]; // reservados
|
||||
} meter_ade7758_internal_data_t;
|
||||
|
||||
static meter_ade7758_internal_data_t meter_data;
|
||||
static TaskHandle_t meter_task = NULL;
|
||||
static SemaphoreHandle_t meter_mutex = NULL;
|
||||
static uint32_t meter_watchdog_counter = 0;
|
||||
|
||||
// === Utilitários internos ===
|
||||
|
||||
static void meter_ade7758_clear_internal_data(void) {
|
||||
if (meter_mutex && xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
||||
memset(&meter_data, 0, sizeof(meter_data));
|
||||
xSemaphoreGive(meter_mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static bool meter_ade7758_read_internal(meter_ade7758_internal_data_t *out) {
|
||||
if (!out) return false;
|
||||
if (xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
||||
*out = meter_data;
|
||||
xSemaphoreGive(meter_mutex);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void meter_ade7758_task_func(void *param) {
|
||||
ESP_LOGI(TAG, "Meter task started");
|
||||
|
||||
meter_ade7758_internal_data_t previous = {0};
|
||||
|
||||
while (true) {
|
||||
meter_ade7758_internal_data_t current = {0};
|
||||
|
||||
current.vrms[0] = avrms() / VRMS_CAL;
|
||||
current.vrms[1] = bvrms() / VRMS_CAL;
|
||||
current.vrms[2] = cvrms() / VRMS_CAL;
|
||||
|
||||
current.irms[0] = airms() / IRMS_CAL;
|
||||
current.irms[1] = birms() / IRMS_CAL;
|
||||
current.irms[2] = cirms() / IRMS_CAL;
|
||||
|
||||
if (setPotLine(PHASE_A, 20)) current.watt[0] = getWatt(PHASE_A);
|
||||
if (setPotLine(PHASE_B, 20)) current.watt[1] = getWatt(PHASE_B);
|
||||
if (setPotLine(PHASE_C, 20)) current.watt[2] = getWatt(PHASE_C);
|
||||
|
||||
if (memcmp(&previous, ¤t, sizeof(current)) != 0) {
|
||||
if (xSemaphoreTake(meter_mutex, pdMS_TO_TICKS(10)) == pdTRUE) {
|
||||
meter_data = current;
|
||||
meter_watchdog_counter++;
|
||||
xSemaphoreGive(meter_mutex);
|
||||
}
|
||||
previous = current;
|
||||
}
|
||||
|
||||
vTaskDelay(pdMS_TO_TICKS(METER_READ_INTERVAL_MS));
|
||||
}
|
||||
}
|
||||
|
||||
// === Interface pública: controle ===
|
||||
|
||||
esp_err_t meter_ade7758_init(void) {
|
||||
ESP_LOGI(TAG, "Inicializando medidor ADE7758...");
|
||||
|
||||
if (!meter_mutex) {
|
||||
meter_mutex = xSemaphoreCreateMutex();
|
||||
if (!meter_mutex) {
|
||||
ESP_LOGE(TAG, "Falha ao criar mutex");
|
||||
return ESP_ERR_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
meter_ade7758_clear_internal_data();
|
||||
|
||||
esp_err_t err = Init(EEPROM_HOST, PIN_NUM_MISO, PIN_NUM_MOSI, PIN_NUM_CLK);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGE(TAG, "Erro ao inicializar SPI (%d)", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
InitSpi(PIN_NUM_CS);
|
||||
gainSetup(INTEGRATOR_OFF, FULLSCALESELECT_0_5V, GAIN_1, GAIN_1);
|
||||
setupDivs(1, 1, 1);
|
||||
setLcycMode(0x00);
|
||||
resetStatus();
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t meter_ade7758_start(void) {
|
||||
if (meter_task) return ESP_ERR_INVALID_STATE;
|
||||
|
||||
meter_ade7758_clear_internal_data();
|
||||
BaseType_t result = xTaskCreate(meter_ade7758_task_func, "meter_ade7758_task", 4096, NULL, 5, &meter_task);
|
||||
return result == pdPASS ? ESP_OK : ESP_FAIL;
|
||||
}
|
||||
|
||||
void meter_ade7758_stop(void) {
|
||||
if (meter_task) {
|
||||
vTaskDelete(meter_task);
|
||||
meter_task = NULL;
|
||||
}
|
||||
meter_ade7758_clear_internal_data();
|
||||
}
|
||||
|
||||
bool meter_ade7758_is_running(void) {
|
||||
return meter_task != NULL;
|
||||
}
|
||||
|
||||
void meter_ade7758_clear_data(void) {
|
||||
meter_ade7758_clear_internal_data();
|
||||
}
|
||||
|
||||
// === Interface pública: acesso aos dados ===
|
||||
|
||||
float meter_ade7758_get_vrms_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.vrms[0] : 0; }
|
||||
float meter_ade7758_get_vrms_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.vrms[1] : 0; }
|
||||
float meter_ade7758_get_vrms_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.vrms[2] : 0; }
|
||||
|
||||
float meter_ade7758_get_irms_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.irms[0] : 0; }
|
||||
float meter_ade7758_get_irms_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.irms[1] : 0; }
|
||||
float meter_ade7758_get_irms_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.irms[2] : 0; }
|
||||
|
||||
int meter_ade7758_get_watt_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.watt[0] : 0; }
|
||||
int meter_ade7758_get_watt_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.watt[1] : 0; }
|
||||
int meter_ade7758_get_watt_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.watt[2] : 0; }
|
||||
|
||||
int meter_ade7758_get_var_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.var[0] : 0; }
|
||||
int meter_ade7758_get_var_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.var[1] : 0; }
|
||||
int meter_ade7758_get_var_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.var[2] : 0; }
|
||||
|
||||
int meter_ade7758_get_va_l1(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.va[0] : 0; }
|
||||
int meter_ade7758_get_va_l2(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.va[1] : 0; }
|
||||
int meter_ade7758_get_va_l3(void) { meter_ade7758_internal_data_t d; return meter_ade7758_read_internal(&d) ? d.va[2] : 0; }
|
||||
|
||||
// === Diagnóstico ===
|
||||
|
||||
uint32_t meter_ade7758_get_watchdog_counter(void) {
|
||||
return meter_watchdog_counter;
|
||||
}
|
||||
70
components/meter_manager/driver/meter_ade7758/meter_ade7758.h
Executable file
70
components/meter_manager/driver/meter_ade7758/meter_ade7758.h
Executable file
@@ -0,0 +1,70 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
/**
|
||||
* @brief Inicializa o driver do medidor ADE7758 (SPI, mutex, registradores).
|
||||
*/
|
||||
esp_err_t meter_ade7758_init(void);
|
||||
|
||||
/**
|
||||
* @brief Inicia a tarefa de leitura de dados do medidor ADE7758.
|
||||
*/
|
||||
esp_err_t meter_ade7758_start(void);
|
||||
|
||||
/**
|
||||
* @brief Para a tarefa de leitura e limpa os dados internos do medidor ADE7758.
|
||||
*/
|
||||
void meter_ade7758_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Verifica se o medidor ADE7758 está em execução.
|
||||
*
|
||||
* @return true se a tarefa estiver ativa, false caso contrário.
|
||||
*/
|
||||
bool meter_ade7758_is_running(void);
|
||||
|
||||
/**
|
||||
* @brief Limpa os dados armazenados no medidor ADE7758 (zera todos os valores).
|
||||
*/
|
||||
void meter_ade7758_clear_data(void);
|
||||
|
||||
// ----- Leituras por fase (L1, L2, L3) -----
|
||||
|
||||
// Tensão RMS (em volts)
|
||||
float meter_ade7758_get_vrms_l1(void);
|
||||
float meter_ade7758_get_vrms_l2(void);
|
||||
float meter_ade7758_get_vrms_l3(void);
|
||||
|
||||
// Corrente RMS (em amperes)
|
||||
float meter_ade7758_get_irms_l1(void);
|
||||
float meter_ade7758_get_irms_l2(void);
|
||||
float meter_ade7758_get_irms_l3(void);
|
||||
|
||||
// Potência ativa (W)
|
||||
int meter_ade7758_get_watt_l1(void);
|
||||
int meter_ade7758_get_watt_l2(void);
|
||||
int meter_ade7758_get_watt_l3(void);
|
||||
|
||||
// Potência reativa (VAR)
|
||||
int meter_ade7758_get_var_l1(void);
|
||||
int meter_ade7758_get_var_l2(void);
|
||||
int meter_ade7758_get_var_l3(void);
|
||||
|
||||
// Potência aparente (VA)
|
||||
int meter_ade7758_get_va_l1(void);
|
||||
int meter_ade7758_get_va_l2(void);
|
||||
int meter_ade7758_get_va_l3(void);
|
||||
|
||||
// (Opcional) contador de watchdog para diagnóstico
|
||||
uint32_t meter_ade7758_get_watchdog_counter(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user