ESPHome 2025.5.0
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 {
13namespace ade7880 {
14
15// adapted from https://stackoverflow.com/a/55912127/1886371
16template<size_t Bits, typename T> inline T sign_extend(const T &v) noexcept {
17 using S = struct { signed Val : Bits; };
18 return reinterpret_cast<const S *>(&v)->Val;
19}
20
21// Register types
22// unsigned 8-bit (uint8_t)
23// signed 10-bit - 16-bit ZP on wire (int16_t, needs sign extension)
24// unsigned 16-bit (uint16_t)
25// unsigned 20-bit - 32-bit ZP on wire (uint32_t)
26// signed 24-bit - 32-bit ZPSE on wire (int32_t, needs sign extension)
27// signed 24-bit - 32-bit ZP on wire (int32_t, needs sign extension)
28// signed 24-bit - 32-bit SE on wire (int32_t)
29// signed 28-bit - 32-bit ZP on wire (int32_t, needs sign extension)
30// unsigned 32-bit (uint32_t)
31// signed 32-bit (int32_t)
32
33uint8_t ADE7880::read_u8_register16_(uint16_t a_register) {
34 uint8_t in;
35 this->read_register16(a_register, &in, sizeof(in));
36 return in;
37}
38
39int16_t ADE7880::read_s16_register16_(uint16_t a_register) {
40 int16_t in;
41 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
42 return convert_big_endian(in);
43}
44
45uint16_t ADE7880::read_u16_register16_(uint16_t a_register) {
46 uint16_t in;
47 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
48 return convert_big_endian(in);
49}
50
51int32_t ADE7880::read_s24zp_register16_(uint16_t a_register) {
52 // s24zp means 24 bit signed value in the lower 24 bits of a 32-bit register
53 int32_t in;
54 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
56}
57
58int32_t ADE7880::read_s32_register16_(uint16_t a_register) {
59 int32_t in;
60 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
61 return convert_big_endian(in);
62}
63
64uint32_t ADE7880::read_u32_register16_(uint16_t a_register) {
65 uint32_t in;
66 this->read_register16(a_register, reinterpret_cast<uint8_t *>(&in), sizeof(in));
67 return convert_big_endian(in);
68}
69
70void ADE7880::write_u8_register16_(uint16_t a_register, uint8_t value) {
71 this->write_register16(a_register, &value, sizeof(value));
72}
73
74void ADE7880::write_s10zp_register16_(uint16_t a_register, int16_t value) {
75 int16_t out = convert_big_endian(value & 0x03FF);
76 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
77}
78
79void ADE7880::write_u16_register16_(uint16_t a_register, uint16_t value) {
80 uint16_t out = convert_big_endian(value);
81 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
82}
83
84void ADE7880::write_s24zpse_register16_(uint16_t a_register, int32_t value) {
85 // s24zpse means a 24-bit signed value, sign-extended to 28 bits, in the lower 28 bits of a 32-bit register
86 int32_t out = convert_big_endian(value & 0x0FFFFFFF);
87 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
88}
89
90void ADE7880::write_s32_register16_(uint16_t a_register, int32_t value) {
91 int32_t out = convert_big_endian(value);
92 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
93}
94
95void ADE7880::write_u32_register16_(uint16_t a_register, uint32_t value) {
96 uint32_t out = convert_big_endian(value);
97 this->write_register16(a_register, reinterpret_cast<uint8_t *>(&out), sizeof(out));
98}
99
100} // namespace ade7880
101} // namespace esphome
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, bool stop=true)
write an array of bytes to a specific register in the I²C device
Definition i2c.cpp:34
ErrorCode read_register16(uint16_t a_register, uint8_t *data, size_t len, bool stop=true)
reads an array of bytes from a specific register in the I²C device
Definition i2c.cpp:17
T sign_extend(const T &v) noexcept
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
constexpr14 T convert_big_endian(T val)
Convert a value between host byte order and big endian (most significant byte first) order.
Definition helpers.h:248