mirror of
https://github.com/esphome/esphome.git
synced 2026-10-17 19:52:50 +00:00
[core] Add sign_extend helper (#20933)
This commit is contained in:
@@ -990,6 +990,12 @@ constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, ui
|
||||
(static_cast<uint32_t>(byte3) << 8) | (static_cast<uint32_t>(byte4));
|
||||
}
|
||||
|
||||
/// Sign-extend the low \p BITS bits of \p value, e.g. sign_extend<24>(0xFFFFFE) == -2. Higher bits are ignored.
|
||||
template<unsigned BITS> constexpr int32_t sign_extend(uint32_t value) {
|
||||
static_assert(BITS > 0 && BITS <= 32, "BITS must be 1 to 32");
|
||||
return static_cast<int32_t>(value << (32 - BITS)) >> (32 - BITS);
|
||||
}
|
||||
|
||||
/// Encode a value from its constituent bytes (from most to least significant) in an array with length sizeof(T).
|
||||
template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0> constexpr T encode_value(const uint8_t *bytes) {
|
||||
T val = 0;
|
||||
|
||||
@@ -55,6 +55,21 @@ TEST(HelpersTest, Ilog10RoundTripMatchesLog10) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HelpersTest, SignExtend) {
|
||||
EXPECT_EQ(sign_extend<24>(0x000000), 0);
|
||||
EXPECT_EQ(sign_extend<24>(0x7FFFFF), 8388607);
|
||||
EXPECT_EQ(sign_extend<24>(0x800000), -8388608);
|
||||
EXPECT_EQ(sign_extend<24>(0xFFFFFE), -2);
|
||||
EXPECT_EQ(sign_extend<24>(0xAB000001), 1); // bits above BITS are ignored
|
||||
EXPECT_EQ(sign_extend<12>(0x7FF), 2047);
|
||||
EXPECT_EQ(sign_extend<12>(0x800), -2048);
|
||||
EXPECT_EQ(sign_extend<16>(0xFF38), -200);
|
||||
EXPECT_EQ(sign_extend<1>(1), -1);
|
||||
EXPECT_EQ(sign_extend<32>(0xFFFFFFFF), -1);
|
||||
EXPECT_EQ(sign_extend<32>(0x7FFFFFFF), INT32_MAX);
|
||||
static_assert(sign_extend<12>(0xFFF) == -1, "usable in constant expressions");
|
||||
}
|
||||
|
||||
TEST(HelpersTest, SumBytes) {
|
||||
static constexpr uint8_t FRAME[] = {0x11, 0xDA, 0x27, 0x00, 0xC5, 0x00, 0x10};
|
||||
EXPECT_EQ(sum_bytes(FRAME, sizeof(FRAME)), 0xE7); // the Daikin comfort frame checksum
|
||||
|
||||
Reference in New Issue
Block a user