mirror of
https://github.com/esphome/esphome.git
synced 2026-11-15 17:45:57 +00:00
Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
937c4e175b | ||
|
|
46348dd851 | ||
|
|
db36074b49 | ||
|
|
a876276d4c | ||
|
|
0c42290b02 |
No files matched your search
@@ -114,10 +114,10 @@ void BME280Component::setup() {
|
||||
this->calibration_.h1 = read_u8_(BME280_REGISTER_DIG_H1);
|
||||
this->calibration_.h2 = read_s16_le_(BME280_REGISTER_DIG_H2);
|
||||
this->calibration_.h3 = read_u8_(BME280_REGISTER_DIG_H3);
|
||||
this->calibration_.h4 =
|
||||
sign_extend<12>(read_u8_(BME280_REGISTER_DIG_H4) << 4 | (read_u8_(BME280_REGISTER_DIG_H4 + 1) & 0x0F));
|
||||
this->calibration_.h5 =
|
||||
sign_extend<12>(read_u8_(BME280_REGISTER_DIG_H5 + 1) << 4 | (read_u8_(BME280_REGISTER_DIG_H5) >> 4));
|
||||
this->calibration_.h4 = sign_extend<12>(
|
||||
encode_uint12(read_u8_(BME280_REGISTER_DIG_H4), low_nibble(read_u8_(BME280_REGISTER_DIG_H4 + 1))));
|
||||
this->calibration_.h5 = sign_extend<12>(
|
||||
encode_uint12(read_u8_(BME280_REGISTER_DIG_H5 + 1), high_nibble(read_u8_(BME280_REGISTER_DIG_H5))));
|
||||
this->calibration_.h6 = read_u8_(BME280_REGISTER_DIG_H6);
|
||||
|
||||
uint8_t humid_control_val = 0;
|
||||
|
||||
@@ -70,8 +70,9 @@ bool BME680Component::setup_registers_() {
|
||||
this->calibration_.t2 = encode_value_le<int16_t>(&coeff1[1]);
|
||||
this->calibration_.t3 = coeff1[3];
|
||||
|
||||
this->calibration_.h1 = coeff2[2] << 4 | (coeff2[1] & 0x0F);
|
||||
this->calibration_.h2 = encode_uint16(coeff2[0], coeff2[1]) >> 4;
|
||||
// H1 and H2 are 12-bit values sharing byte 1: its low nibble ends H1, its high nibble ends H2
|
||||
this->calibration_.h1 = encode_uint12(coeff2[2], low_nibble(coeff2[1]));
|
||||
this->calibration_.h2 = encode_uint12(coeff2[0], high_nibble(coeff2[1]));
|
||||
this->calibration_.h3 = coeff2[3];
|
||||
this->calibration_.h4 = coeff2[4];
|
||||
this->calibration_.h5 = coeff2[5];
|
||||
@@ -243,7 +244,7 @@ void BME680Component::read_data_() {
|
||||
uint32_t raw_pressure = encode_uint24(data[2], data[3], data[4]) >> 4;
|
||||
uint32_t raw_humidity = encode_uint16(data[8], data[9]);
|
||||
uint16_t raw_gas = encode_uint16(data[13], data[14]) >> 6;
|
||||
uint8_t gas_range = data[14] & 0x0F;
|
||||
uint8_t gas_range = low_nibble(data[14]);
|
||||
|
||||
float temperature = this->calc_temperature_(raw_temperature);
|
||||
float pressure = this->calc_pressure_(raw_pressure);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "cst328_touchscreen.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
#include "esphome/core/log.h"
|
||||
|
||||
namespace esphome::cst328 {
|
||||
@@ -99,7 +100,7 @@ void CST328Touchscreen::update_touches() {
|
||||
return;
|
||||
}
|
||||
|
||||
uint8_t touch_cnt = touch_data[CST_REG_FINGER_COUNT_IDX] & 0x0F;
|
||||
uint8_t touch_cnt = low_nibble(touch_data[CST_REG_FINGER_COUNT_IDX]);
|
||||
if (touch_cnt == 0 || touch_cnt > CST328_TOUCH_MAX_POINTS) {
|
||||
this->update_button_state_(false);
|
||||
} else {
|
||||
|
||||
@@ -37,11 +37,18 @@ struct TouchRecord {
|
||||
uint8_t z;
|
||||
};
|
||||
|
||||
/// Decodes record `index` of a touch report.
|
||||
/// Decodes record `index` of a touch report. Each record is 5 bytes:
|
||||
/// [id:4 | event:4] [x 11..4] [y 11..4] [x 3..0 | y 3..0] [z].
|
||||
/// The first record is followed by 2 extra bytes, so later records start 2 bytes further on.
|
||||
inline TouchRecord decode_touch(const uint8_t *report, uint8_t index) {
|
||||
const uint8_t *r = report + index * 5 + (index == 0 ? 0 : 2);
|
||||
return {static_cast<uint8_t>(r[0] >> 4), static_cast<uint8_t>(r[0] & 0x0F),
|
||||
static_cast<uint16_t>(r[1] << 4 | r[3] >> 4), static_cast<uint16_t>(r[2] << 4 | (r[3] & 0x0F)), r[4]};
|
||||
return {
|
||||
.id = high_nibble(r[0]),
|
||||
.event = low_nibble(r[0]),
|
||||
.x = encode_uint12(r[1], high_nibble(r[3])),
|
||||
.y = encode_uint12(r[2], low_nibble(r[3])),
|
||||
.z = r[4],
|
||||
};
|
||||
}
|
||||
|
||||
class CSTTouchscreen : public touchscreen::Touchscreen, public i2c::I2CDevice {
|
||||
|
||||
@@ -35,12 +35,12 @@ void EKTF2232Touchscreen::setup() {
|
||||
if (err == i2c::ERROR_OK) {
|
||||
err = this->read(received, 4);
|
||||
if (err == i2c::ERROR_OK) {
|
||||
this->x_raw_max_ = ((received[2])) | ((received[3] & 0xf0) << 4);
|
||||
this->x_raw_max_ = encode_uint16(high_nibble(received[3]), received[2]);
|
||||
err = this->write(GET_Y_RES, 4);
|
||||
if (err == i2c::ERROR_OK) {
|
||||
err = this->read(received, 4);
|
||||
if (err == i2c::ERROR_OK) {
|
||||
this->y_raw_max_ = ((received[2])) | ((received[3] & 0xf0) << 4);
|
||||
this->y_raw_max_ = encode_uint16(high_nibble(received[3]), received[2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -74,8 +74,9 @@ void EKTF2232Touchscreen::update_touches() {
|
||||
|
||||
for (int i = 0; i < touch_count; i++) {
|
||||
uint8_t *d = raw + 1 + (i * 3);
|
||||
x_raw = (d[0] & 0xF0) << 4 | d[1];
|
||||
y_raw = (d[0] & 0x0F) << 8 | d[2];
|
||||
// d[0] holds the top 4 bits of X (high nibble) and of Y (low nibble)
|
||||
x_raw = encode_uint16(high_nibble(d[0]), d[1]);
|
||||
y_raw = encode_uint16(low_nibble(d[0]), d[2]);
|
||||
this->add_raw_touch_position_(i, x_raw, y_raw);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,8 +69,8 @@ void FT5x06Touchscreen::update_touches() {
|
||||
for (uint8_t i = 0; i != touch_cnt; i++) {
|
||||
uint8_t status = data[i][0] >> 6;
|
||||
uint8_t id = data[i][2] >> 3;
|
||||
uint16_t x = encode_uint16(data[i][0] & 0x0F, data[i][1]);
|
||||
uint16_t y = encode_uint16(data[i][2] & 0xF, data[i][3]);
|
||||
uint16_t x = encode_uint16(low_nibble(data[i][0]), data[i][1]);
|
||||
uint16_t y = encode_uint16(low_nibble(data[i][2]), data[i][3]);
|
||||
|
||||
ESP_LOGV(TAG, "Read %X status, id: %d, pos %d/%d", status, id, x, y);
|
||||
if (status == 0 || status == 2) {
|
||||
|
||||
@@ -90,31 +90,31 @@ void FT63X6Touchscreen::update_touches() {
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t FT63X6Touchscreen::read_touch_number_() { return this->read_byte_(FT63X6_ADDR_TD_STATUS) & 0x0F; }
|
||||
uint8_t FT63X6Touchscreen::read_touch_number_() { return low_nibble(this->read_byte_(FT63X6_ADDR_TD_STATUS)); }
|
||||
// Touch 1 functions
|
||||
uint16_t FT63X6Touchscreen::read_touch_x_(uint8_t touch) {
|
||||
uint8_t read_buf[2];
|
||||
read_buf[0] = this->read_byte_(FT63X6_ADDR_TOUCH1_X + (touch * 6));
|
||||
read_buf[1] = this->read_byte_(FT63X6_ADDR_TOUCH1_X + 1 + (touch * 6));
|
||||
return encode_uint16(read_buf[0] & 0x0f, read_buf[1]);
|
||||
return encode_uint16(low_nibble(read_buf[0]), read_buf[1]);
|
||||
}
|
||||
uint16_t FT63X6Touchscreen::read_touch_y_(uint8_t touch) {
|
||||
uint8_t read_buf[2];
|
||||
read_buf[0] = this->read_byte_(FT63X6_ADDR_TOUCH1_Y + (touch * 6));
|
||||
read_buf[1] = this->read_byte_(FT63X6_ADDR_TOUCH1_Y + 1 + (touch * 6));
|
||||
return encode_uint16(read_buf[0] & 0x0f, read_buf[1]);
|
||||
return encode_uint16(low_nibble(read_buf[0]), read_buf[1]);
|
||||
}
|
||||
uint8_t FT63X6Touchscreen::read_touch_event_(uint8_t touch) {
|
||||
return this->read_byte_(FT63X6_ADDR_TOUCH1_X + (touch * 6)) >> 6;
|
||||
}
|
||||
uint8_t FT63X6Touchscreen::read_touch_id_(uint8_t touch) {
|
||||
return this->read_byte_(FT63X6_ADDR_TOUCH1_ID + (touch * 6)) >> 4;
|
||||
return high_nibble(this->read_byte_(FT63X6_ADDR_TOUCH1_ID + (touch * 6)));
|
||||
}
|
||||
uint8_t FT63X6Touchscreen::read_touch_weight_(uint8_t touch) {
|
||||
return this->read_byte_(FT63X6_ADDR_TOUCH1_WEIGHT + (touch * 6));
|
||||
}
|
||||
uint8_t FT63X6Touchscreen::read_touch_misc_(uint8_t touch) {
|
||||
return this->read_byte_(FT63X6_ADDR_TOUCH1_MISC + (touch * 6)) >> 4;
|
||||
return high_nibble(this->read_byte_(FT63X6_ADDR_TOUCH1_MISC + (touch * 6)));
|
||||
}
|
||||
|
||||
uint8_t FT63X6Touchscreen::read_byte_(uint8_t addr) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "gsl3670_touchscreen.h"
|
||||
#include "esphome/core/log.h"
|
||||
#include "esphome/core/hal.h"
|
||||
#include "esphome/core/helpers.h"
|
||||
|
||||
namespace esphome::gsl3670 {
|
||||
|
||||
@@ -66,10 +67,11 @@ void GSL3670Touchscreen::update_touches() {
|
||||
|
||||
// Build gsl_touch_info exactly as the Seeed driver does
|
||||
for (uint8_t j = 0; j != finger_num; j++) {
|
||||
// buf[(j+1)*4 + 0..3]: byte0=y_lo, byte1=y_hi, byte2=x_lo, byte3=id|x_hi
|
||||
auto x = (uint16_t) (((buf[(j + 1) * 4 + 3] & 0x0f) << 8) | buf[(j + 1) * 4 + 2]);
|
||||
auto y = (uint16_t) ((buf[(j + 1) * 4 + 1] << 8) | buf[(j + 1) * 4 + 0]);
|
||||
auto id = (buf[(j + 1) * 4 + 3] >> 4) & 0x0f;
|
||||
// Record: y_lo, y_hi, x_lo, then the id (high nibble) and the top 4 bits of X (low nibble)
|
||||
const uint8_t *record = &buf[(j + 1) * 4];
|
||||
auto x = encode_uint16(low_nibble(record[3]), record[2]);
|
||||
auto y = encode_uint16(record[1], record[0]);
|
||||
auto id = high_nibble(record[3]);
|
||||
ESP_LOGV(TAG, "Touch id=%u, x=%u y=%u", id, x, y);
|
||||
if (x <= 8192 && y <= 8192)
|
||||
this->add_raw_touch_position_(id, x, y);
|
||||
|
||||
@@ -62,7 +62,7 @@ void LilygoT547Touchscreen::update_touches() {
|
||||
return;
|
||||
}
|
||||
|
||||
point = buffer[5] & 0xF;
|
||||
point = low_nibble(buffer[5]);
|
||||
if (point > 2) {
|
||||
ESP_LOGW(TAG, "Invalid touch point count: %d", point);
|
||||
point = 2;
|
||||
@@ -88,9 +88,11 @@ void LilygoT547Touchscreen::update_touches() {
|
||||
|
||||
uint16_t id, x_raw, y_raw;
|
||||
for (uint8_t i = 0; i < point; i++) {
|
||||
id = (buffer[i * 5] >> 4) & 0x0F;
|
||||
y_raw = (uint16_t) ((buffer[i * 5 + 1] << 4) | ((buffer[i * 5 + 3] >> 4) & 0x0F));
|
||||
x_raw = (uint16_t) ((buffer[i * 5 + 2] << 4) | (buffer[i * 5 + 3] & 0x0F));
|
||||
const uint8_t *record = buffer + i * 5;
|
||||
id = high_nibble(record[0]);
|
||||
// The low 4 bits of Y and X share byte 3
|
||||
y_raw = encode_uint12(record[1], high_nibble(record[3]));
|
||||
x_raw = encode_uint12(record[2], low_nibble(record[3]));
|
||||
this->add_raw_touch_position_(id, x_raw, y_raw);
|
||||
}
|
||||
|
||||
|
||||
+11
-1
@@ -1155,6 +1155,16 @@ bool random_bytes(uint8_t *data, size_t len);
|
||||
/// @name Bit manipulation
|
||||
///@{
|
||||
|
||||
/// The high 4 bits of a byte, e.g. high_nibble(0xA5) == 0xA.
|
||||
constexpr uint8_t high_nibble(uint8_t byte) { return byte >> 4; }
|
||||
/// The low 4 bits of a byte, e.g. low_nibble(0xA5) == 0x5.
|
||||
constexpr uint8_t low_nibble(uint8_t byte) { return byte & 0x0F; }
|
||||
|
||||
/// Encode a 12-bit value from its high 8 and low 4 bits, e.g. encode_uint12(0x12, 0x3) == 0x123.
|
||||
/// Bits above the low 4 of \p low_bits are ignored.
|
||||
constexpr uint16_t encode_uint12(uint8_t high_bits, uint8_t low_bits) {
|
||||
return (static_cast<uint16_t>(high_bits) << 4) | low_nibble(low_bits);
|
||||
}
|
||||
/// 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<uint16_t>(msb) << 8) | (static_cast<uint16_t>(lsb));
|
||||
@@ -1257,7 +1267,7 @@ constexpr uint8_t *put_le32(uint8_t *dst, uint32_t value) {
|
||||
}
|
||||
|
||||
/// Decode a two-digit packed BCD byte (tens in the high nibble) to its value, e.g. 0x59 to 59.
|
||||
constexpr uint8_t bcd_to_uint8(uint8_t bcd) { return (bcd >> 4) * 10 + (bcd & 0x0F); }
|
||||
constexpr uint8_t bcd_to_uint8(uint8_t bcd) { return high_nibble(bcd) * 10 + low_nibble(bcd); }
|
||||
/// 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); }
|
||||
|
||||
|
||||
@@ -55,6 +55,26 @@ TEST(HelpersTest, Ilog10RoundTripMatchesLog10) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST(HelpersTest, Nibbles) {
|
||||
EXPECT_EQ(high_nibble(0xA5), 0xA);
|
||||
EXPECT_EQ(low_nibble(0xA5), 0x5);
|
||||
EXPECT_EQ(high_nibble(0x0F), 0x0);
|
||||
EXPECT_EQ(low_nibble(0xF0), 0x0);
|
||||
static_assert(high_nibble(0xFF) == 0xF && low_nibble(0xFF) == 0xF, "usable in constant expressions");
|
||||
}
|
||||
|
||||
TEST(HelpersTest, EncodeUint12) {
|
||||
EXPECT_EQ(encode_uint12(0x12, 0x3), 0x123);
|
||||
EXPECT_EQ(encode_uint12(0xFF, 0xF), 0xFFF);
|
||||
EXPECT_EQ(encode_uint12(0x00, 0x0), 0x000);
|
||||
EXPECT_EQ(encode_uint12(0x12, 0xA3), 0x123);
|
||||
// A touch record byte packing the low nibbles of X (high) and Y (low)
|
||||
const uint8_t shared = 0x5C;
|
||||
EXPECT_EQ(encode_uint12(0x34, high_nibble(shared)), 0x345);
|
||||
EXPECT_EQ(encode_uint12(0x67, low_nibble(shared)), 0x67C);
|
||||
static_assert(encode_uint12(0xAB, 0xC) == 0xABC, "usable in constant expressions");
|
||||
}
|
||||
|
||||
TEST(HelpersTest, SignExtend) {
|
||||
EXPECT_EQ(sign_extend<24>(0x000000), 0);
|
||||
EXPECT_EQ(sign_extend<24>(0x7FFFFF), 8388607);
|
||||
|
||||
Reference in new issue
Block a user