From 99c775d8cbad9afe3be4ae6c9a446dde34c1f3cd Mon Sep 17 00:00:00 2001 From: Oxan van Leeuwen Date: Wed, 10 Nov 2021 19:44:01 +0100 Subject: [PATCH] Introduce encode_value/decode_value() template functions (#2662) --- esphome/components/ccs811/ccs811.cpp | 2 +- esphome/core/helpers.cpp | 11 -------- esphome/core/helpers.h | 42 +++++++++++++++++++++++----- 3 files changed, 36 insertions(+), 19 deletions(-) diff --git a/esphome/components/ccs811/ccs811.cpp b/esphome/components/ccs811/ccs811.cpp index 11a66f5100..f8cee79c55 100644 --- a/esphome/components/ccs811/ccs811.cpp +++ b/esphome/components/ccs811/ccs811.cpp @@ -52,7 +52,7 @@ void CCS811Component::setup() { if (this->baseline_.has_value()) { // baseline available, write to sensor - this->write_bytes(0x11, decode_uint16(*this->baseline_)); + this->write_bytes(0x11, decode_value(*this->baseline_)); } auto hardware_version_data = this->read_bytes<1>(0x21); diff --git a/esphome/core/helpers.cpp b/esphome/core/helpers.cpp index edd2f74c12..daca3ffd32 100644 --- a/esphome/core/helpers.cpp +++ b/esphome/core/helpers.cpp @@ -350,17 +350,6 @@ std::string str_sprintf(const char *fmt, ...) { return str; } -uint16_t encode_uint16(uint8_t msb, uint8_t lsb) { return (uint16_t(msb) << 8) | uint16_t(lsb); } -std::array decode_uint16(uint16_t value) { - uint8_t msb = (value >> 8) & 0xFF; - uint8_t lsb = (value >> 0) & 0xFF; - return {msb, lsb}; -} - -uint32_t encode_uint32(uint8_t msb, uint8_t byte2, uint8_t byte3, uint8_t lsb) { - return (uint32_t(msb) << 24) | (uint32_t(byte2) << 16) | (uint32_t(byte3) << 8) | uint32_t(lsb); -} - std::string hexencode(const uint8_t *data, uint32_t len) { char buf[20]; std::string res; diff --git a/esphome/core/helpers.h b/esphome/core/helpers.h index 9a60d036e4..c67ad8eea3 100644 --- a/esphome/core/helpers.h +++ b/esphome/core/helpers.h @@ -138,13 +138,6 @@ uint8_t reverse_bits_8(uint8_t x); uint16_t reverse_bits_16(uint16_t x); uint32_t reverse_bits_32(uint32_t x); -/// Encode a 16-bit unsigned integer given a most and least-significant byte. -uint16_t encode_uint16(uint8_t msb, uint8_t lsb); -/// Decode a 16-bit unsigned integer into an array of two values: most significant byte, least significant byte. -std::array decode_uint16(uint16_t value); -/// Encode a 32-bit unsigned integer given four bytes in MSB -> LSB order -uint32_t encode_uint32(uint8_t msb, uint8_t byte2, uint8_t byte3, uint8_t lsb); - /// Convert RGB floats (0-1) to hue (0-360) & saturation/value percentage (0-1) void rgb_to_hsv(float red, float green, float blue, int &hue, float &saturation, float &value); /// Convert hue (0-360) & saturation/value percentage (0-1) to RGB floats (0-1) @@ -306,6 +299,41 @@ constexpr uint64_t byteswap(uint64_t n) { return __builtin_bswap64(n); } /// @name Bit manipulation ///@{ +/// Encode a 16-bit value given the most and least significant byte. +constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb) { + return (static_cast(msb) << 8) | (static_cast(lsb)); +} +/// Encode a 32-bit value given four bytes in most to least significant byte order. +constexpr uint32_t encode_uint32(uint8_t byte1, uint8_t byte2, uint8_t byte3, uint8_t byte4) { + return (static_cast(byte1) << 24) | (static_cast(byte2) << 16) | + (static_cast(byte3) << 8) | (static_cast(byte4)); +} + +/// Encode a value from its constituent bytes (from most to least significant) in an array with length sizeof(T). +template::value, int> = 0> inline T encode_value(const uint8_t *bytes) { + T val = 0; + for (size_t i = 0; i < sizeof(T); i++) { + val <<= 8; + val |= bytes[i]; + } + return val; +} +/// Encode a value from its constituent bytes (from most to least significant) in an std::array with length sizeof(T). +template::value, int> = 0> +inline T encode_value(const std::array bytes) { + return encode_value(bytes.data()); +} +/// Decode a value into its constituent bytes (from most to least significant). +template::value, int> = 0> +inline std::array decode_value(T val) { + std::array ret{}; + for (size_t i = sizeof(T); i > 0; i--) { + ret[i - 1] = val & 0xFF; + val >>= 8; + } + return ret; +} + /// Convert a value between host byte order and big endian (most significant byte first) order. template::value, int> = 0> constexpr T convert_big_endian(T val) { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__