mirror of
https://github.com/esphome/esphome.git
synced 2024-12-23 14:04:53 +01:00
SML: fix incomplete sign extension for abbreviated transmissions (#5544)
This commit is contained in:
parent
cc4c0e3e0b
commit
51688d4078
1 changed files with 8 additions and 17 deletions
|
@ -88,11 +88,6 @@ uint64_t bytes_to_uint(const bytes &buffer) {
|
||||||
for (auto const value : buffer) {
|
for (auto const value : buffer) {
|
||||||
val = (val << 8) + value;
|
val = (val << 8) + value;
|
||||||
}
|
}
|
||||||
// Some smart meters send 24 bit signed integers. Sign extend to 64 bit if the
|
|
||||||
// 24 bit value is negative.
|
|
||||||
if (buffer.size() == 3 && buffer[0] & 0x80) {
|
|
||||||
val |= 0xFFFFFFFFFF000000;
|
|
||||||
}
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,19 +95,15 @@ int64_t bytes_to_int(const bytes &buffer) {
|
||||||
uint64_t tmp = bytes_to_uint(buffer);
|
uint64_t tmp = bytes_to_uint(buffer);
|
||||||
int64_t val;
|
int64_t val;
|
||||||
|
|
||||||
switch (buffer.size()) {
|
// sign extension for abbreviations of leading ones (e.g. 3 byte transmissions, see 6.2.2 of SML protocol definition)
|
||||||
case 1: // int8
|
// see https://stackoverflow.com/questions/42534749/signed-extension-from-24-bit-to-32-bit-in-c
|
||||||
val = (int8_t) tmp;
|
if (buffer.size() < 8) {
|
||||||
break;
|
const int bits = buffer.size() * 8;
|
||||||
case 2: // int16
|
const uint64_t m = 1u << (bits - 1);
|
||||||
val = (int16_t) tmp;
|
tmp = (tmp ^ m) - m;
|
||||||
break;
|
|
||||||
case 4: // int32
|
|
||||||
val = (int32_t) tmp;
|
|
||||||
break;
|
|
||||||
default: // int64
|
|
||||||
val = (int64_t) tmp;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val = (int64_t) tmp;
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue