mirror of
https://github.com/esphome/esphome.git
synced 2026-05-10 05:37:55 +08:00
[htu31d][kamstrup_kmp][ms8607] Use CRC functions from helpers.h (#16313)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user