From 5bf4f303407ba322ed7d501ea12ea4e8ba493cab Mon Sep 17 00:00:00 2001 From: ladyada Date: Mon, 12 May 2025 11:48:28 -0400 Subject: [PATCH] more crc --- Adafruit_OPT4048.cpp | 86 +++++++++++++++++++++++++++++++------------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/Adafruit_OPT4048.cpp b/Adafruit_OPT4048.cpp index 047906e..9e606ff 100644 --- a/Adafruit_OPT4048.cpp +++ b/Adafruit_OPT4048.cpp @@ -158,40 +158,76 @@ bool Adafruit_OPT4048::getChannelsRaw(uint32_t *ch0, uint32_t *ch1, uint32_t *ch uint32_t code = mant << exp; uint8_t crc = lsb & 0x0F; - // Calculate CRC based on datasheet - // The CRC calculation is based on polynomial: x^4 + x + 1 - // Implementation follows LFSR (Linear Feedback Shift Register) approach + // Based on the debug data analysis, we need to implement + // a CRC calculation that matches the expected values from the sensor - // First we need to create the data stream (exp + mantissa bits) - uint32_t datastream = ((uint32_t)exp << 20) | mant; // 24 bits: 4-bit exp + 20-bit mantissa + // Initialize CRC variables to match the debug output format + uint8_t x0 = 0; // CRC bit 0 + uint8_t x1 = 0; // CRC bit 1 + uint8_t x2 = 0; // CRC bit 2 + uint8_t x3 = 0; // CRC bit 3 - // Initial state of LFSR (0000) - uint8_t lfsr = 0; + // Implementing CRC check based on the provided debug output: + // For CH0: MSB=0x11F, LSB=0x3CD7, exp=0, mant=0x1F3C, CRC=0x7, Expected CRC bits: x0=0, x1=1, x2=0, x3=0 + // For CH1: MSB=0x1E6, LSB=0x9CD9, exp=0, mant=0xE69C, CRC=0x9, Expected CRC bits: x0=1, x1=0, x2=0, x3=1 + // For CH2: MSB=0x38, LSB=0xB0DF, exp=0, mant=0x38B0, CRC=0xF, Expected CRC bits: x0=0, x1=0, x2=1, x3=1 + // For CH3: MSB=0x6B5, LSB=0x64D3, exp=0, mant=0xB564, CRC=0x3, Expected CRC bits: x0=0, x1=0, x2=1, x3=0 - // Process each bit of datastream (MSB first) - for (int8_t i = 23; i >= 0; i--) { - // Get current bit from datastream - uint8_t data_bit = (datastream >> i) & 1; - - // XOR the input bit with the MSB of current LFSR value - uint8_t feedback = (lfsr >> 3) ^ data_bit; - - // Shift LFSR left by 1 - lfsr = (lfsr << 1) & 0x0F; - - // If feedback is 1, XOR with polynomial taps (x^4 + x + 1) -> 0b0011 - if (feedback) { - lfsr ^= 0x03; // Polynomial taps - } + // Calculate CRC (based on analysis of expected results) + // Calculate bit 0 (x0) + uint8_t ones_count = 0; + // Count in exponent (bits 0-3) + for (uint8_t i = 0; i < 4; i++) { + if ((exp >> i) & 1) ones_count++; } + // Count in mantissa (bits 0-19) + for (uint8_t i = 0; i < 20; i++) { + if ((mant >> i) & 1) ones_count++; + } + // Parity bit (1 if odd number of 1s, 0 if even) + x0 = ones_count & 1; - // The calculated CRC is now in lfsr - uint8_t calculated_crc = lfsr; + // Calculate bit 1 (x1) - based on odd bit positions + x1 = 0; + // Check bits at odd positions in mantissa + for (uint8_t i = 1; i < 20; i += 2) { + x1 ^= (mant >> i) & 1; + } + // Include exponent bits 1 and 3 + x1 ^= (exp >> 1) & 1; + x1 ^= (exp >> 3) & 1; + + // Calculate bit 2 (x2) - based on position mod 4 + x2 = 0; + // Check every 4th bit in mantissa + for (uint8_t i = 0; i < 20; i += 4) { + x2 ^= (mant >> i) & 1; + } + // Include exponent bit 0 + x2 ^= (exp >> 0) & 1; + + // Calculate bit 3 (x3) - based on specific positions + x3 = 0; + // XOR bits at positions 3, 11, 19 of mantissa + x3 ^= (mant >> 3) & 1; + x3 ^= (mant >> 11) & 1; + x3 ^= (mant >> 19) & 1; + + // Combine bits to form the CRC + uint8_t calculated_crc = (x3 << 3) | (x2 << 2) | (x1 << 1) | x0; // Debug CRC values Serial.print(F("DEBUG: CRC=0x")); Serial.print(crc, HEX); - Serial.print(F(", Calculated CRC=0x")); + Serial.print(F(", Calculated: x0=")); + Serial.print(x0); + Serial.print(F(", x1=")); + Serial.print(x1); + Serial.print(F(", x2=")); + Serial.print(x2); + Serial.print(F(", x3=")); + Serial.print(x3); + Serial.print(F(", Combined CRC=0x")); Serial.println(calculated_crc, HEX); // Additional debug to inspect the data structure more closely