mirror of https://github.com/arendst/Tasmota.git
134 lines
3.0 KiB
Arduino
134 lines
3.0 KiB
Arduino
|
/*
|
||
|
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
|