Tasmota/tasmota/xnrg_23_ade7880.ino

134 lines
3.0 KiB
C++

/*
xnrg_23_ade7880.ino - ADE7880 energy sensor support for Tasmota
SPDX-FileCopyrightText: 2022 Theo Arends and AndreKR
SPDX-License-Identifier: GPL-3.0-only
*/
#ifdef USE_I2C
#ifdef USE_ENERGY_SENSOR
#ifdef USE_ADE7880
/*********************************************************************************************\
* ADE7880 - Energy used in Shelly 3EM
*
* {"NAME":"Shelly 3EM","GPIO":[0,0,0,0,0,8065,0,0,640,8064,608,0,0,0],"FLAG":0,"BASE":18}
*
* Based on datasheet from https://www.analog.com/en/products/ade7880.html
*
* I2C Address: 0x38
\*********************************************************************************************/
#define XNRG_23 23
#define XI2C_65 65 // See I2CDEVICES.md
#define ADE7880_ADDR 0x38
int Ade7880RegSize(uint16_t reg) {
int size = 0;
/*
TBD
switch ((reg >> 8) & 0x0F) {
case 0x03:
size++;
case 0x02:
size++;
case 0x01:
size++;
case 0x00:
case 0x07:
case 0x08:
size++;
}
*/
return size;
}
void Ade7880Write(uint16_t reg, uint32_t val) {
int size = Ade7880RegSize(reg);
if (size) {
Wire.beginTransmission(ADE7880_ADDR);
Wire.write((reg >> 8) & 0xFF);
Wire.write(reg & 0xFF);
while (size--) {
Wire.write((val >> (8 * size)) & 0xFF); // Write data, MSB first
}
Wire.endTransmission();
delayMicroseconds(5); // Bus-free time minimum 4.7us
}
}
int32_t Ade7880Read(uint16_t reg) {
uint32_t response = 0;
int size = Ade7880RegSize(reg);
if (size) {
Wire.beginTransmission(ADE7880_ADDR);
Wire.write((reg >> 8) & 0xFF);
Wire.write(reg & 0xFF);
Wire.endTransmission(0);
Wire.requestFrom(ADE7880_ADDR, size);
if (size <= Wire.available()) {
for (uint32_t i = 0; i < size; i++) {
response = response << 8 | Wire.read(); // receive DATA (MSB first)
}
}
}
return response;
}
void Ade7880Init(void) {
// Ade7953Write(0x102, 0x0004); // Locking the communication interface (Clear bit COMM_LOCK), Enable HPF
// Ade7953Write(0x0FE, 0x00AD); // Unlock register 0x120
// Ade7953Write(0x120, 0x0030); // Configure optimum setting
}
void Ade7880EnergyEverySecond(void) {
}
void Ade7880DrvInit(void) {
if (PinUsed(GPIO_ADE7880_IRQ) && PinUsed(GPIO_ADE7880_IRQ, 1)) {
}
}
bool Ade7880Command(void) {
// Will need calibration for all three phases
bool serviced = true;
return serviced;
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
bool Xnrg23(uint8_t function) {
if (!I2cEnabled(XI2C_07)) { return false; }
bool result = false;
switch (function) {
case FUNC_ENERGY_EVERY_SECOND:
Ade7880EnergyEverySecond();
break;
case FUNC_COMMAND:
result = Ade7880Command();
break;
case FUNC_PRE_INIT:
Ade7880DrvInit();
break;
}
return result;
}
#endif // USE_ADE7880
#endif // USE_ENERGY_SENSOR
#endif // USE_I2C