feat: add src/telemetry.c

This commit is contained in:
2026-09-25 11:56:46 +08:00
parent ff1cf0d739
commit 42aa9c4cfc

36
src/telemetry.c Normal file
View File

@@ -0,0 +1,36 @@
#include "telemetry.h"
static uint8_t crc8(const uint8_t *data, size_t length) {
uint8_t crc = 0;
for (size_t i = 0; i < length; ++i) {
crc ^= data[i];
for (int bit = 0; bit < 8; ++bit)
crc = (uint8_t)((crc & 0x80u) ? (((unsigned)crc << 1) ^ 0x07u) : ((unsigned)crc << 1));
}
return crc;
}
frame_result_t decode_frame(const uint8_t *bytes, size_t length, sample_t *sample) {
if (!bytes || !sample || length != 8) return FRAME_SHORT;
if (bytes[0] != 1) return FRAME_VERSION;
if (crc8(bytes, 7) != bytes[7]) return FRAME_CRC;
sample->sequence = (uint16_t)((bytes[1] << 8) | bytes[2]);
sample->temperature_centi = (int16_t)((bytes[3] << 8) | bytes[4]);
sample->voltage_mv = (uint16_t)((bytes[5] << 8) | bytes[6]);
if (sample->temperature_centi < -4000 || sample->temperature_centi > 8500 ||
sample->voltage_mv < 9000 || sample->voltage_mv > 16000) return FRAME_RANGE;
return FRAME_OK;
}
const char *frame_result_name(frame_result_t result) {
switch (result) {
case FRAME_OK: return "accepted";
case FRAME_SHORT: return "invalid length";
case FRAME_VERSION: return "unsupported version";
case FRAME_CRC: return "crc mismatch";
case FRAME_RANGE: return "sample out of range";
case FRAME_DUPLICATE: return "duplicate sequence";
case FRAME_ROLLBACK: return "sequence rollback";
}
return "unknown";
}