[htu31d][kamstrup_kmp][ms8607] Use CRC functions from helpers.h (#16313)

This commit is contained in:
Mat931
2026-05-08 13:17:14 +00:00
committed by GitHub
parent eb52ca61fe
commit 3d8fffbea9
8 changed files with 42 additions and 88 deletions
+3 -29
View File
@@ -43,32 +43,6 @@ static const uint8_t HTU31D_RESET = 0x1E;
/** Diagnostics command. */
static const uint8_t HTU31D_DIAGNOSTICS = 0x08;
/**
* Computes a CRC result for the provided input.
*
* @returns the computed CRC result for the provided input
*/
uint8_t compute_crc(uint32_t value) {
uint32_t polynom = 0x98800000; // x^8 + x^5 + x^4 + 1
uint32_t msb = 0x80000000;
uint32_t mask = 0xFF800000;
uint32_t threshold = 0x00000080;
uint32_t result = value;
while (msb != threshold) {
// Check if msb of current value is 1 and apply XOR mask
if (result & msb)
result = ((result ^ polynom) & mask) | (result & ~mask);
// Shift by one
msb >>= 1;
mask >>= 1;
polynom >>= 1;
}
return result;
}
/**
* Resets the sensor and ensures that the devices serial number can be read over
* I2C.
@@ -112,7 +86,7 @@ void HTU31DComponent::update() {
// Calculate temperature value.
uint16_t raw_temp = encode_uint16(thdata[0], thdata[1]);
uint8_t crc = compute_crc((uint32_t) raw_temp << 8);
uint8_t crc = crc8(thdata, 2, 0, 0x31, true);
if (crc != thdata[2]) {
this->status_set_warning();
ESP_LOGE(TAG, "Error validating temperature CRC");
@@ -131,7 +105,7 @@ void HTU31DComponent::update() {
// Calculate humidty value.
uint16_t raw_hum = encode_uint16(thdata[3], thdata[4]);
crc = compute_crc((uint32_t) raw_hum << 8);
crc = crc8(thdata + 3, 2, 0, 0x31, true);
if (crc != thdata[5]) {
this->status_set_warning();
ESP_LOGE(TAG, "Error validating humidty CRC");
@@ -197,7 +171,7 @@ uint32_t HTU31DComponent::read_serial_num_() {
serial = encode_uint32(reply[0], reply[1], reply[2], padding);
uint8_t crc = compute_crc(serial);
uint8_t crc = crc8(reply, 3, 0, 0x31, true);
if (crc != reply[3]) {
ESP_LOGE(TAG, "Error validating serial CRC");
return 0;
@@ -1,5 +1,6 @@
#include "kamstrup_kmp.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
namespace esphome::kamstrup_kmp {
@@ -95,10 +96,7 @@ void KamstrupKMPComponent::send_message_(const uint8_t *msg, int msg_len) {
buffer[i] = msg[i];
}
buffer[buffer_len - 2] = 0;
buffer[buffer_len - 1] = 0;
uint16_t crc = crc16_ccitt(buffer, buffer_len);
uint16_t crc = crc16be(buffer, buffer_len - 2);
buffer[buffer_len - 2] = crc >> 8;
buffer[buffer_len - 1] = crc & 0xFF;
@@ -192,7 +190,7 @@ void KamstrupKMPComponent::read_command_(uint16_t command) {
}
// Validate CRC
if (crc16_ccitt(msg, msg_len)) {
if (crc16be(msg, msg_len - 2) != encode_uint16(msg[msg_len - 2], msg[msg_len - 1])) {
ESP_LOGE(TAG, "Received invalid message (CRC mismatch)");
return;
}
@@ -282,24 +280,4 @@ void KamstrupKMPComponent::set_sensor_value_(uint16_t command, float value, uint
ESP_LOGD(TAG, "Received value for command 0x%04X: %.3f [%s]", command, value, unit);
}
uint16_t crc16_ccitt(const uint8_t *buffer, int len) {
uint32_t poly = 0x1021;
uint32_t reg = 0x00;
for (int i = 0; i < len; i++) {
int mask = 0x80;
while (mask > 0) {
reg <<= 1;
if (buffer[i] & mask) {
reg |= 1;
}
mask >>= 1;
if (reg & 0x10000) {
reg &= 0xffff;
reg ^= poly;
}
}
}
return (uint16_t) reg;
}
} // namespace esphome::kamstrup_kmp
@@ -123,7 +123,4 @@ class KamstrupKMPComponent : public PollingComponent, public uart::UARTDevice {
void set_sensor_value_(uint16_t command, float value, uint8_t unit_idx);
};
// "true" CCITT CRC-16
uint16_t crc16_ccitt(const uint8_t *buffer, int len);
} // namespace esphome::kamstrup_kmp
+1 -31
View File
@@ -63,7 +63,6 @@ enum class MS8607Component::SetupStatus {
};
static uint8_t crc4(uint16_t *buffer, size_t length);
static uint8_t hsensor_crc_check(uint16_t value);
void MS8607Component::setup() {
this->error_code_ = ErrorCode::NONE;
@@ -244,35 +243,6 @@ static uint8_t crc4(uint16_t *buffer, size_t length) {
return (crc_remainder >> 12) & 0xF; // only the most significant 4 bits
}
/**
* @brief Calculates CRC value for the provided humidity (+ status bits) value
*
* CRC-8 check comes from other MS8607 libraries on github. I did not find it in the datasheet,
* and it differs from the crc8 implementation that's already part of esphome.
*
* @param value two byte humidity sensor value read from i2c
* @return uint8_t computed crc value
*/
static uint8_t hsensor_crc_check(uint16_t value) {
uint32_t polynom = 0x988000; // x^8 + x^5 + x^4 + 1
uint32_t msb = 0x800000;
uint32_t mask = 0xFF8000;
uint32_t result = (uint32_t) value << 8; // Pad with zeros as specified in spec
while (msb != 0x80) {
// Check if msb of current value is 1 and apply XOR mask
if (result & msb) {
result = ((result ^ polynom) & mask) | (result & ~mask);
}
// Shift by one
msb >>= 1;
mask >>= 1;
polynom >>= 1;
}
return result & 0xFF;
}
void MS8607Component::request_read_temperature_() {
// Tell MS8607 to start ADC conversion of temperature sensor
if (!this->write_bytes(MS8607_CMD_CONV_D2_OSR_8K, nullptr, 0)) {
@@ -338,7 +308,7 @@ void MS8607Component::read_humidity_(float temperature_float) {
// Bit1 of the two LSBS must be set to '1'. Bit0 is currently not assigned"
uint16_t humidity = encode_uint16(bytes[0], bytes[1]);
uint8_t const expected_crc = bytes[2];
uint8_t const actual_crc = hsensor_crc_check(humidity);
uint8_t const actual_crc = crc8(bytes, 2, 0, 0x31, true);
if (expected_crc != actual_crc) {
ESP_LOGE(TAG, "Incorrect Humidity CRC value. Provided value 0x%01X != calculated value 0x%01X", expected_crc,
actual_crc);
+11
View File
@@ -0,0 +1,11 @@
sensor:
- platform: ms8607
i2c_id: i2c_bus
temperature:
name: Temperature
humidity:
name: Humidity
pressure:
name: Pressure
address: 0x76
update_interval: 15s
@@ -0,0 +1,8 @@
substitutions:
i2c_scl: GPIO16
i2c_sda: GPIO17
packages:
i2c: !include ../../test_build_components/common/i2c/esp32-idf.yaml
<<: !include common.yaml
@@ -0,0 +1,8 @@
substitutions:
i2c_scl: GPIO5
i2c_sda: GPIO4
packages:
i2c: !include ../../test_build_components/common/i2c/esp8266-ard.yaml
<<: !include common.yaml
@@ -0,0 +1,8 @@
substitutions:
i2c_scl: GPIO5
i2c_sda: GPIO4
packages:
i2c: !include ../../test_build_components/common/i2c/rp2040-ard.yaml
<<: !include common.yaml