Explorar o código

Sensors API changes. LM75 added, BMP280 temporarily abandoned

Victor %!s(int64=3) %!d(string=hai) anos
pai
achega
558f2da568
Modificáronse 8 ficheiros con 156 adicións e 33 borrados
  1. 21 7
      Sensors.c
  2. 3 0
      Sensors.h
  3. 15 12
      interfaces/I2CSensor.c
  4. 2 3
      interfaces/I2CSensor.h
  5. 11 11
      sensors/BMP280.c
  6. 64 0
      sensors/LM75.c
  7. 39 0
      sensors/LM75.h
  8. 1 0
      sensors/SensorsDriver.h

+ 21 - 7
Sensors.c

@@ -149,8 +149,12 @@ bool unitemp_sensors_load() {
         }
         line = strtok((char*)NULL, "\n");
     }
-    uint16_t otherValues[] = {0x76};
-    unitemp_sensor_alloc("BMP280", BMP280, otherValues);
+
+    // uint16_t otherValues[] = {0x76};
+    // unitemp_sensor_alloc("BMP280", BMP280, otherValues);
+    //Адрес 7 бит
+    uint16_t otherValues[] = {0b1001000};
+    unitemp_sensor_alloc("LM75", LM75, otherValues);
 
     free(file_buf);
     file_stream_close(app->file_stream);
@@ -220,7 +224,7 @@ Sensor* unitemp_sensor_alloc(char* name, SensorType st, uint16_t* anotherValues)
         status = unitemp_oneWire_sensorAlloc(sensor, st, anotherValues);
     }
     //Выделение памяти под инстанс датчиков I2C
-    if(st == BMP280) {
+    if(st == BMP280 || st == LM75) {
         status = unitemp_I2C_sensorAlloc(sensor, st, anotherValues);
     }
 
@@ -255,6 +259,7 @@ bool unitemp_sensors_init(void) {
                 app->sensors[i]->name);
             result = false;
         }
+        FURI_LOG_D(APP_NAME, "Sensor %s successfully initialized", app->sensors[i]->name);
     }
     return result;
 }
@@ -284,15 +289,24 @@ bool unitemp_sensors_deInit(void) {
 UnitempStatus unitemp_sensor_updateData(Sensor* sensor) {
     if(sensor == NULL) return UT_ERROR;
 
+    //Проверка на допустимость опроса датчика
+    if(furi_get_tick() - sensor->lastPollingTime < sensor->pollingInterval) {
+        //Возврат ошибки если последний опрос датчика был неудачным
+        if(sensor->status == UT_TIMEOUT) {
+            return UT_TIMEOUT;
+        }
+        return UT_EARLYPOOL;
+    }
+
+    sensor->lastPollingTime = furi_get_tick();
+
     if(!furi_hal_power_is_otg_enabled()) {
         furi_hal_power_enable_otg();
     }
 
     sensor->status = sensor->updater(sensor);
-    if(app->settings.unit == FAHRENHEIT) uintemp_celsiumToFarengate(sensor);
-    return sensor->status;
-
-    sensor->status = UT_ERROR;
+    if(app->settings.unit == FAHRENHEIT && sensor->status == UT_OK)
+        uintemp_celsiumToFarengate(sensor);
     return sensor->status;
 }
 

+ 3 - 0
Sensors.h

@@ -90,6 +90,9 @@ typedef struct Sensor {
     SensorDeinitializer* deinitializer;
     SensorUpdater* updater;
 
+    uint32_t lastPollingTime;
+    uint16_t pollingInterval;
+
 } Sensor;
 
 /**

+ 15 - 12
interfaces/I2CSensor.c

@@ -17,12 +17,14 @@ bool readRegArray(I2CSensor* i2c_sensor, uint8_t startReg, uint8_t len, uint8_t*
     furi_hal_i2c_release(i2c_sensor->i2c);
     return status;
 }
-void writeReg(I2CSensor* i2c_sensor, uint8_t reg, uint8_t value) {
+bool writeReg(I2CSensor* i2c_sensor, uint8_t reg, uint8_t value) {
     //Блокировка шины
     furi_hal_i2c_acquire(i2c_sensor->i2c);
     uint8_t buff[1] = {value};
-    furi_hal_i2c_write_mem(i2c_sensor->i2c, i2c_sensor->currentI2CAdr << 1, reg, buff, 1, 0xFF);
+    bool status = furi_hal_i2c_write_mem(
+        i2c_sensor->i2c, i2c_sensor->currentI2CAdr << 1, reg, buff, 1, 0xFF);
     furi_hal_i2c_release(i2c_sensor->i2c);
+    return status;
 }
 
 bool unitemp_I2C_sensorInit(void* s) {
@@ -53,23 +55,24 @@ UnitempStatus unitemp_I2C_updateData(void* sensor) {
 }
 
 bool unitemp_I2C_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherValues) {
+    bool status = false;
     I2CSensor* instance = malloc(sizeof(I2CSensor));
     instance->interface = I2C;
     instance->i2c = &furi_hal_i2c_handle_external;
 
-    instance->lastPollingTime = 0xFFFFFFFF;
-
-    sensor->initializer = unitemp_I2C_sensorInit;
-    sensor->deinitializer = unitemp_I2C_sensorDeInit;
-    sensor->updater = unitemp_I2C_updateData;
+    sensor->lastPollingTime = 0xFFFFFFFF;
 
     sensor->instance = instance;
     sensor->type = st;
 
-    //Настройки для BMP280
-    if(st == BMP280) {
-        instance->minI2CAdr = 0x76;
-        instance->maxI2CAdr = 0x77;
+    // //Настройки для BMP280
+    // if(st == BMP280) {
+    //     instance->minI2CAdr = 0x76;
+    //     instance->maxI2CAdr = 0x77;
+    // }
+    if(st == LM75) {
+        //Указание функций инициализации, деинициализации и обновления данных, а так же адреса на шине I2C
+        status = unitemp_LM75_alloc(sensor);
     }
 
     if(anotherValues[0] >= instance->minI2CAdr && anotherValues[0] <= instance->maxI2CAdr) {
@@ -77,5 +80,5 @@ bool unitemp_I2C_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherVal
     } else {
         instance->currentI2CAdr = instance->minI2CAdr;
     }
-    return true;
+    return status;
 }

+ 2 - 3
interfaces/I2CSensor.h

@@ -8,8 +8,6 @@
 typedef struct I2CSensor {
     //Тип интерфейса подключения датчика
     Interface interface;
-    //Время последнего опроса
-    uint32_t lastPollingTime;
     //Последнее успешное значение температуры
     float lastTemp;
     //Последнее успешное значение влажности
@@ -69,7 +67,8 @@ bool readRegArray(I2CSensor* i2c_sensor, uint8_t startReg, uint8_t len, uint8_t*
  * @param i2c_sensor Указатель на датчик
  * @param reg Номер регистра
  * @param value Значение для записи
+ * @return Истина если значение записано
  */
-void writeReg(I2CSensor* i2c_sensor, uint8_t reg, uint8_t value);
+bool writeReg(I2CSensor* i2c_sensor, uint8_t reg, uint8_t value);
 
 #endif

+ 11 - 11
sensors/BMP280.c

@@ -66,18 +66,18 @@ bool BMP280_init(I2CSensor* i2c_sensor) {
 
 bool BMP280_updateData(Sensor* sensor) {
     I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
-    if(furi_get_tick() - i2c_sensor->lastPollingTime < 500) {
-        sensor->status = UT_EARLYPOOL;
-        return false;
-    }
-    i2c_sensor->lastPollingTime = furi_get_tick();
+    // if(furi_get_tick() - i2c_sensor->lastPollingTime < 500) {
+    //     sensor->status = UT_EARLYPOOL;
+    //     return false;
+    // }
+    // i2c_sensor->lastPollingTime = furi_get_tick();
 
-    while(readReg(i2c_sensor, 0xF3) & 0b00001001) {
-        if(furi_get_tick() - i2c_sensor->lastPollingTime > 100) {
-            sensor->status = UT_TIMEOUT;
-            return false;
-        }
-    }
+    // while(readReg(i2c_sensor, 0xF3) & 0b00001001) {
+    //     if(furi_get_tick() - i2c_sensor->lastPollingTime > 100) {
+    //         sensor->status = UT_TIMEOUT;
+    //         return false;
+    //     }
+    // }
 
     uint8_t buff[3];
     if(!readRegArray(i2c_sensor, 0xFA, 3, buff)) return false;

+ 64 - 0
sensors/LM75.c

@@ -0,0 +1,64 @@
+#include "LM75.h"
+
+#define LM75_REG_TEMP 0x00
+#define LM75_REG_CONFIG 0x01
+#define LM75_REG_THYST 0x02
+#define LM75_REG_TOS 0x03
+
+#define LM75_CONFIG_SHUTDOWN 0b00000001
+#define LM75_CONFIG_INTERRUPT 0b00000010
+#define LM75_CONFIG_OSPOLARITY_HIGH 0b00000100
+#define LM75_CONFIG_FAULTQUEUE_1 0b00000000
+#define LM75_CONFIG_FAULTQUEUE_2 0b00001000
+#define LM75_CONFIG_FAULTQUEUE_4 0b00010000
+#define LM75_CONFIG_FAULTQUEUE_6 0b00011000
+
+bool unitemp_LM75_alloc(Sensor* sensor) {
+    I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+    //Функции работы с датчиком
+    sensor->initializer = unitemp_LM75_init;
+    sensor->deinitializer = unitemp_LM75_deinit;
+    sensor->updater = unitemp_LM75_update;
+    sensor->pollingInterval = 1000;
+
+    //Адреса на шине I2C (7 бит)
+    i2c_sensor->minI2CAdr = 0b1001000;
+    i2c_sensor->maxI2CAdr = 0b1001111;
+    return true;
+}
+
+bool unitemp_LM75_init(void* s) {
+    Sensor* sensor = (Sensor*)s;
+    I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+
+    //Выход если не удалось записать значение в датчик
+    if(!writeReg(i2c_sensor, LM75_REG_CONFIG, LM75_CONFIG_FAULTQUEUE_1)) return false;
+    //TODO: Работа с прерываниями и компаратором
+
+    return true;
+}
+
+bool unitemp_LM75_deinit(void* s) {
+    Sensor* sensor = (Sensor*)s;
+    I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+    if(!writeReg(i2c_sensor, LM75_REG_CONFIG, LM75_CONFIG_FAULTQUEUE_1 | LM75_CONFIG_SHUTDOWN))
+        return false;
+    UNUSED(sensor);
+    UNUSED(i2c_sensor);
+    return true;
+}
+
+UnitempStatus unitemp_LM75_update(void* s) {
+    Sensor* sensor = (Sensor*)s;
+    I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
+
+    uint8_t buff[2];
+    if(!readRegArray(i2c_sensor, LM75_REG_TEMP, 2, buff)) return UT_TIMEOUT;
+    uint16_t raw =
+        ((((uint16_t)buff[0] << 8) | buff[1]) >> 7) * ((buff[1] & 0b10000000) ? -1.0f : 1.0f);
+    sensor->temp = (float)raw / 2.0f;
+
+    FURI_LOG_D(APP_NAME, "Sensor %s updated %f", sensor->name, (double)raw / (double)2.0);
+
+    return UT_OK;
+}

+ 39 - 0
sensors/LM75.h

@@ -0,0 +1,39 @@
+#ifndef UNITEMP_LM75
+#define UNITEMP_LM75
+
+#include "../unitemp.h"
+#include "SensorsDriver.h"
+#include "../Sensors.h"
+
+/**
+ * @brief Выделение памяти и установка начальных значений датчика LM75
+ * 
+ * @param sensor Указатель на создаваемый датчик
+ * @return Истина при успехе
+ */
+bool unitemp_LM75_alloc(Sensor* sensor);
+
+/**
+ * @brief Инициализации датчика LM75
+ * 
+ * @param sensor Указатель на датчик (тип Sensor)
+ * @return Истина если инициализация упспешная
+ */
+bool unitemp_LM75_init(void* sensor);
+
+/**
+ * @brief Деинициализация датчика, очистка памяти
+ * 
+ * @param sensor Указатель на датчик (тип Sensor)
+ */
+bool unitemp_LM75_deinit(void* s);
+
+/**
+ * @brief Обновление значений из датчика
+ * 
+ * @param sensor Указатель на датчик (тип Sensor)
+ * @return Истина если данныее были получены
+ */
+UnitempStatus unitemp_LM75_update(void* s);
+
+#endif

+ 1 - 0
sensors/SensorsDriver.h

@@ -4,5 +4,6 @@
 #include "../Sensors.h"
 #include "../interfaces/I2CSensor.h"
 #include "BMP280.h"
+#include "LM75.h"
 
 #endif