diff --git a/fw/Core/Src/main.c b/fw/Core/Src/main.c index a291fcf..a058d38 100644 --- a/fw/Core/Src/main.c +++ b/fw/Core/Src/main.c @@ -331,9 +331,10 @@ int main(void) /* Read SCD4x data (if connected) */ if (scd4x_is_connected == 1) { - scd4x_read_measurement(&CO2, - &T_SCD4x, - &RH_SCD4x); + if (scd4x_read_measurement(&CO2, &T_SCD4x, &RH_SCD4x) != SCD4X_OK) { + /* read failed, either I2C fail or CRC error */ + // TODO something + } if (CO2 > 0) { co2_valid = 1; } else { diff --git a/fw/Core/Src/scd4x.c b/fw/Core/Src/scd4x.c index e5c4645..6452c3a 100644 --- a/fw/Core/Src/scd4x.c +++ b/fw/Core/Src/scd4x.c @@ -80,11 +80,9 @@ int8_t scd4x_read_measurement(uint16_t *co2, int16_t *temperature, uint16_t *rel buffer[0] = SCD4X_READ_MEASUREMENT >> 8; buffer[1] = SCD4X_READ_MEASUREMENT & 0x00ff; result = i2c_transmit(SCD4X_I2C_ADDRESS<<1, buffer, 2); - - // TODO: Proc to vraci NACK? Vyresit. - /*if (result != I2C_OK) { + if (result != I2C_OK) { return SCD4X_ERROR; - }*/ + } uart_enable_interrupts(); LL_mDelay(1); // 10 ms should be enough uart_disable_interrupts(); @@ -95,12 +93,22 @@ int8_t scd4x_read_measurement(uint16_t *co2, int16_t *temperature, uint16_t *rel { return SCD4X_ERROR; } - - // TODO checksum - // Convert to T and RH; taken directly from pseudocode in SHT4x datasheet, page 3 + /* Convert to T and RH; taken directly from pseudocode in SHT4x datasheet, page 3 */ uint32_t co2_ticks = (buffer[0] << 8) + buffer[1]; + uint8_t co2_crc = buffer[2]; uint32_t t_ticks = (buffer[3] << 8) + buffer[4]; + uint8_t t_crc = buffer[5]; uint32_t rh_ticks = (buffer[6] << 8) + buffer[7]; + uint8_t rh_crc = buffer[8]; + + /* check CRC-8 checksum */ + uint8_t crc_correct = crc8_calculate(buffer, 2) == co2_crc; + crc_correct &= crc8_calculate(buffer + 3, 2) == t_crc; + crc_correct &= crc8_calculate(buffer + 6, 2) == rh_crc; + if (!crc_correct) { + return SCD4X_CRC8_ERROR; + } + /* copy to output variables */ int t_degC = -450 + 10 * 175 * t_ticks / 65535; int rh_pRH = 100 * rh_ticks / 65535; if (rh_pRH > 100) {