Przeglądaj źródła

Added DS18B20 data CRC check

Victor 3 lat temu
rodzic
commit
0960f0d5ba
1 zmienionych plików z 36 dodań i 2 usunięć
  1. 36 2
      interfaces/OneWireSensor.c

+ 36 - 2
interfaces/OneWireSensor.c

@@ -86,7 +86,7 @@ static bool oneWire_read_bit(OneWireSensor* instance) {
  * @brief Чтение байта с шины One Wire
  * 
  * @param instance Указатель на инстанс датчика
- * @return 
+ * @return Байт информации
  */
 static uint8_t oneWire_read(OneWireSensor* instance) {
     uint8_t r = 0;
@@ -96,6 +96,18 @@ static uint8_t oneWire_read(OneWireSensor* instance) {
     }
     return r;
 }
+/**
+ * @brief Чтение массива байт с шины One Wire
+ * 
+ * @param instance Указатель на инстанс датчика
+ * @param data Указатель на массив, куда будут записаны данные
+ * @param len Количество байт
+ */
+static void oneWire_readBytes(OneWireSensor* instance, uint8_t* data, size_t len) {
+    for(size_t i = 0; i < len; i++) {
+        data[i] = oneWire_read(instance);
+    }
+}
 
 bool unitemp_OneWire_alloc(void* s, uint16_t* anotherValues) {
     Sensor* sensor = (Sensor*)s;
@@ -115,6 +127,23 @@ bool unitemp_OneWire_alloc(void* s, uint16_t* anotherValues) {
     return false;
 }
 
+static uint8_t onewire_CRC_update(uint8_t crc, uint8_t b) {
+    //  return pgm_read_byte(&onewire_crc_table[crc ^ b]);
+    for(uint8_t p = 8; p; p--) {
+        crc = ((crc ^ b) & 1) ? (crc >> 1) ^ 0b10001100 : (crc >> 1);
+        b >>= 1;
+    }
+    return crc;
+}
+
+static bool onewire_CRC_check(uint8_t* data, size_t len) {
+    uint8_t crc = 0;
+    for(size_t i = 0; i < len; i++) {
+        crc = onewire_CRC_update(crc, data[i]);
+    }
+    return !crc;
+}
+
 bool unitemp_OneWire_free(void* s) {
     Sensor* sensor = (Sensor*)s;
     free(sensor->instance);
@@ -169,7 +198,12 @@ UnitempStatus unitemp_OneWire_update(void* s) {
         if(!oneWire_start(instance)) return UT_TIMEOUT;
         oneWire_write(instance, 0xCC); // skip ROM
         oneWire_write(instance, 0xBE); // Read Scratch-pad
-        int16_t raw = oneWire_read(instance) | ((int16_t)oneWire_read(instance) << 8);
+        uint8_t buff[9];
+        oneWire_readBytes(instance, buff, 9);
+        if(!onewire_CRC_check(buff, 9)) {
+            return UT_BADCRC;
+        }
+        int16_t raw = buff[0] | ((int16_t)buff[1] << 8);
         sensor->temp = (float)raw / 16.0f;
     }