ESPHome 2026.6.0-dev
Loading...
Searching...
No Matches
ade7880_i2c.cpp
Go to the documentation of this file.
1// This component was developed using knowledge gathered by a number
2// of people who reverse-engineered the Shelly 3EM:
3//
4// @AndreKR on GitHub
5// Axel (@Axel830 on GitHub)
6// Marko (@goodkiller on GitHub)
7// Michaël Piron (@michaelpiron on GitHub)
8// Theo Arends (@arendst on GitHub)
9
10#include "ade7880.h"
11
12namespace esphome::ade7880 {
13
14// adapted from https://stackoverflow.com/a/55912127/1886371
15template<size_t Bits, typename T> inline T sign_extend(const T &v) noexcept {
16 using S = struct { signed Val : Bits; };
17 return reinterpret_cast<const S *>(&v)->Val;
18}
19
20// Register types
21// unsigned 8-bit (uint8_t)
22// signed 10-bit - 16-bit ZP on wire (int16_t, needs sign extension)
23// unsigned 16-bit (uint16_t)
24// unsigned 20-bit - 32-bit ZP on wire (uint32_t)
25// signed 24-bit - 32-bit ZPSE on wire (int32_t, needs sign extension)
26// signed 24-bit - 32-bit ZP on wire (int32_t, needs sign extension)
27// signed 24-bit - 32-bit SE on wire (int32_t)
28// signed 28-bit - 32-bit ZP on wire (int32_t, needs sign extension)
29// unsigned 32-bit (uint32_t)
30// signed 32-bit (int32_t)
31
32uint8_t ADE7880::read_u8_register16_(uint16_t a_register) {
33 uint8_t in;
34 this->read_register16(a_register, &in, sizeof(in));
35 return in;
36}
37
38int16_t ADE7880::read_s16_register16_(uint16_t a_register) {
39 int16_t in;
40 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
41 return convert_big_endian(in);
42}
43
44uint16_t ADE7880::read_u16_register16_(uint16_t a_register) {
45 uint16_t in;
46 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
47 return convert_big_endian(in);
48}
49
50int32_t ADE7880::read_s24zp_register16_(uint16_t a_register) {
51 // s24zp means 24 bit signed value in the lower 24 bits of a 32-bit register
52 int32_t in;
53 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
55}
56
57int32_t ADE7880::read_s32_register16_(uint16_t a_register) {
58 int32_t in;
59 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
60 return convert_big_endian(in);
61}
62
64 uint32_t in;
65 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
66 return convert_big_endian(in);
67}
68
69void ADE7880::write_u8_register16_(uint16_t a_register, uint8_t value) {
70 this->write_register16(a_register, &value, sizeof(value));
71}
72
73void ADE7880::write_s10zp_register16_(uint16_t a_register, int16_t value) {
74 int16_t out = convert_big_endian(value & 0x03FF);
75 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
76}
77
78void ADE7880::write_u16_register16_(uint16_t a_register, uint16_t value) {
79 uint16_t out = convert_big_endian(value);
80 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
81}
82
83void ADE7880::write_s24zpse_register16_(uint16_t a_register, int32_t value) {
84 // s24zpse means a 24-bit signed value, sign-extended to 28 bits, in the lower 28 bits of a 32-bit register
85 int32_t out = convert_big_endian(value & 0x0FFFFFFF);
86 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
87}
88
89void ADE7880::write_s32_register16_(uint16_t a_register, int32_t value) {
90 int32_t out = convert_big_endian(value);
91 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
92}
93
94void ADE7880::write_u32_register16_(uint16_t a_register, uint32_t value) {
95 uint32_t out = convert_big_endian(value);
96 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
97}
98
99} // namespace esphome::ade7880
int16_t read_s16_register16_(uint16_t a_register)
int32_t read_s32_register16_(uint16_t a_register)
void write_u8_register16_(uint16_t a_register, uint8_t value)
uint16_t read_u16_register16_(uint16_t a_register)
void write_s32_register16_(uint16_t a_register, int32_t value)
int32_t read_s24zp_register16_(uint16_t a_register)
void write_s24zpse_register16_(uint16_t a_register, int32_t value)
uint32_t read_u32_register16_(uint16_t a_register)
void write_s10zp_register16_(uint16_t a_register, int16_t value)
void write_u16_register16_(uint16_t a_register, uint16_t value)
uint8_t read_u8_register16_(uint16_t a_register)
void write_u32_register16_(uint16_t a_register, uint32_t value)
ErrorCode write_register16(uint16_t a_register, const uint8_t *data, size_t len) const
write an array of bytes to a specific register in the I²C device
Definition i2c.cpp:43
ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:29
T sign_extend(const T &v) noexcept
constexpr T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
Definition helpers.h:915
static void uint32_t