mirror of
https://github.com/esphome/esphome.git
synced 2026-10-22 05:46:12 +00:00
Add assign_bits to set or clear register bits from a bool
This commit is contained in:
@@ -211,8 +211,8 @@ file does, and it is the authority when they disagree. The most useful starting
|
||||
logged with `get_log_str` and `LOG_STR_ARG`, copied out with `ESPHOME_strncpy_P` before `publish_state`.
|
||||
A `dump_config` helper that picks a name returns `const LogString *` from `LOG_STR(...)`.
|
||||
* **CRCs and bit tricks** come from `esphome/core/helpers.h` (`crc8`, `crc16`, `xor_bytes`, `sum16_bytes`,
|
||||
`reverse_bits`, `encode_uint16`, `encode_value_le`, `sign_extend<BITS>`, `bcd_to_uint8`); pick the helper's
|
||||
arguments instead of writing a loop. Epson style 7-byte RTC calendars (one-hot weekday) use
|
||||
`reverse_bits`, `encode_uint16`, `encode_value_le`, `sign_extend<BITS>`, `bcd_to_uint8`, `assign_bits`); pick
|
||||
the helper's arguments instead of writing a loop. Epson style 7-byte RTC calendars (one-hot weekday) use
|
||||
`time::decode_bcd_calendar`.
|
||||
* **Bus helpers:** UART drains with `read_available(on_byte)` and `discard_available()`, text lines with
|
||||
`LineReader<N>`; I2C has `update_register`, `write_registers` (PROGMEM `I2CRegValue` table), `check_chip_id`
|
||||
|
||||
@@ -1067,6 +1067,11 @@ constexpr uint8_t bcd_to_uint8(uint8_t bcd) { return (bcd >> 4) * 10 + (bcd & 0x
|
||||
/// Encode a value from 0 to 99 as a two-digit packed BCD byte, e.g. 59 to 0x59.
|
||||
constexpr uint8_t uint8_to_bcd(uint8_t value) { return ((value / 10) << 4) | (value % 10); }
|
||||
|
||||
/// Set the bits of \p mask in \p value when \p on is true, clear them otherwise.
|
||||
template<typename T, typename M> constexpr void assign_bits(T &value, M mask, bool on) {
|
||||
value = on ? static_cast<T>(value | mask) : static_cast<T>(value & ~mask);
|
||||
}
|
||||
|
||||
/// Reverse the order of 8 bits.
|
||||
inline uint8_t reverse_bits(uint8_t x) {
|
||||
x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome::core::testing {
|
||||
|
||||
static constexpr uint8_t BIT_3 = 1 << 3;
|
||||
|
||||
static constexpr uint8_t assigned(uint8_t value, uint8_t mask, bool on) {
|
||||
assign_bits(value, mask, on);
|
||||
return value;
|
||||
}
|
||||
|
||||
static_assert(assigned(0x00, BIT_3, true) == 0x08);
|
||||
static_assert(assigned(0xFF, BIT_3, false) == 0xF7);
|
||||
|
||||
TEST(AssignBits, SetsAndClearsOnlyTheMask) {
|
||||
uint8_t reg = 0b1010'0001;
|
||||
assign_bits(reg, 0b0000'0110, true);
|
||||
EXPECT_EQ(reg, 0b1010'0111);
|
||||
assign_bits(reg, 0b1000'0010, false);
|
||||
EXPECT_EQ(reg, 0b0010'0101);
|
||||
}
|
||||
|
||||
TEST(AssignBits, KeepsTheTargetWidth) {
|
||||
uint16_t reg = 0xFFFF;
|
||||
assign_bits(reg, 1u << 15, false);
|
||||
EXPECT_EQ(reg, 0x7FFF);
|
||||
uint32_t wide = 0;
|
||||
assign_bits(wide, 1ul << 31, true);
|
||||
EXPECT_EQ(wide, 0x80000000u);
|
||||
}
|
||||
|
||||
} // namespace esphome::core::testing
|
||||
Reference in New Issue
Block a user