Procházet zdrojové kódy

Major sensors API update

Victor před 3 roky
rodič
revize
147916bf66
11 změnil soubory, kde provedl 370 přidání a 371 odebrání
  1. 74 45
      Sensors.c
  2. 26 43
      Sensors.h
  3. 8 40
      interfaces/I2CSensor.c
  4. 16 29
      interfaces/I2CSensor.h
  5. 80 64
      interfaces/SingleWireSensor.c
  6. 21 15
      interfaces/SingleWireSensor.h
  7. 82 77
      sensors/BMP280.c
  8. 43 43
      sensors/BMP280.h
  9. 13 7
      sensors/LM75.c
  10. 7 7
      sensors/LM75.h
  11. 0 1
      unitemp.h

+ 74 - 45
Sensors.c

@@ -1,6 +1,7 @@
 #include "Sensors.h"
 #include "./interfaces/SingleWireSensor.h"
 #include "./interfaces/I2CSensor.h"
+#include "./sensors/SensorsDriver.h"
 
 #include <furi_hal_power.h>
 
@@ -12,6 +13,8 @@ const GpioPin RX_14 = {.pin = LL_GPIO_PIN_7, .port = GPIOB};
 
 //Количество доступных портов ввода/вывода
 #define GPIO_ITEMS (sizeof(GPIOList) / sizeof(GPIO))
+//Количество типов датчиков
+#define SENSOR_TYPES_COUNT (int)(sizeof(sensorTypes) / sizeof(const SensorType*))
 
 //Перечень достуных портов ввода/вывода
 //static
@@ -30,28 +33,22 @@ const GPIO GPIOList[] = {
     {16, "16 (C0)", &gpio_ext_pc0},
     {17, "17 (1W)", &ibutton_gpio}};
 
-//Перечень имён датчиков
-static const char* sensorNames[SENSOR_TYPES_COUNT] = {
-    "DHT11",
-    "DHT12 (1 Wire)",
-    "DHT12 (I2C)",
-    "DHT20",
-    "DHT21", //AM2301
-    "DHT22", //AM2302
-    "AM2320 (1W)",
-    "AM2320 (I2C)",
-    "LM75",
-    "DS18B20",
-    "BMP180",
-    "BMP280",
-    "BME280",
-};
-
-const char* unitemp_getSensorTypeName(SensorType st) {
-    if(st >= SENSOR_TYPES_COUNT) return NULL;
-    return sensorNames[st];
+//Перечень датчиков
+static const SensorType* sensorTypes[] = {&DHT11, &DHT12_SW, &DHT21, &DHT22, &AM2320_SW, &LM75};
+
+const SensorType* unitemp_getTypeFromInt(int type) {
+    if(type > SENSOR_TYPES_COUNT) return NULL;
+    return sensorTypes[type];
 }
 
+int unitemp_getIntFromType(const SensorType* type) {
+    for(int i = 0; i < SENSOR_TYPES_COUNT; i++) {
+        if(!strcmp(type->typename, sensorTypes[i]->typename)) {
+            return i;
+        }
+    }
+    return 255;
+}
 const GPIO* unitemp_GPIO_getFromInt(uint8_t name) {
     for(uint8_t i = 0; i < GPIO_ITEMS; i++) {
         if(GPIOList[i].num == name) {
@@ -145,16 +142,15 @@ bool unitemp_sensors_load() {
         uint16_t otherValues[] = {otherValue};
         //Проверка типа датчика
         if(type < SENSOR_TYPES_COUNT && sizeof(name) <= 11) {
-            unitemp_sensor_alloc(name, type, otherValues);
+            unitemp_sensor_alloc(name, unitemp_getTypeFromInt(type), otherValues);
+        } else {
+            FURI_LOG_E(APP_NAME, "Unsupported sensor name (%s) or sensor type (%d)", name, type);
         }
         line = strtok((char*)NULL, "\n");
     }
 
     // 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);
@@ -192,13 +188,13 @@ bool unitemp_sensors_save(void) {
 
     //Сохранение датчиков
     for(size_t i = 0; i < app->sensors_count; i++) {
-        if(app->sensors[i]->interface == SINGLE_WIRE) {
+        if(app->sensors[i]->type->interface == SINGLE_WIRE) {
             stream_write_format(
                 app->file_stream,
                 "%s %d %d\n",
                 app->sensors[i]->name,
-                app->sensors[i]->type,
-                unitemp_GPIO_toInt(unitemp_oneWire_sensorGetGPIO(app->sensors[i])->pin));
+                unitemp_getIntFromType(app->sensors[i]->type),
+                unitemp_GPIO_toInt(unitemp_singleWire_sensorGetGPIO(app->sensors[i])->pin));
         }
     }
 
@@ -210,40 +206,73 @@ bool unitemp_sensors_save(void) {
     return true;
 }
 
-Sensor* unitemp_sensor_alloc(char* name, SensorType st, uint16_t* anotherValues) {
+Sensor* unitemp_sensor_alloc(char* name, const SensorType* type, uint16_t* anotherValues) {
     bool status = false;
     //Выделение памяти под датчик
     Sensor* sensor = malloc(sizeof(Sensor));
-    if(sensor == NULL) return false;
+    if(sensor == NULL) {
+        FURI_LOG_E(APP_NAME, "Sensor %s allocation error", name);
+        return false;
+    }
+
+    //Выделение памяти под имя
     sensor->name = malloc(11);
+    if(sensor->name == NULL) {
+        FURI_LOG_E(APP_NAME, "Sensor %s name allocation error", name);
+        return false;
+    }
+    //Запись имени датчка
     strcpy(sensor->name, name);
+    //Тип датчика
+    sensor->type = type;
+    //Статус датчика по умолчанию - ошибка
     sensor->status = UT_ERROR;
+    //Время последнего опроса
+    sensor->lastPollingTime =
+        furi_get_tick() - 10000; //чтобы первый опрос произошёл как можно раньше
 
-    //Выделение памяти под инстанс датчиков One Wire
-    if(st == DHT11 || st == DHT12_1W || st == DHT21 || st == DHT22 || st == AM2320_1W) {
-        status = unitemp_oneWire_sensorAlloc(sensor, st, anotherValues);
+    sensor->temp = -128.0f;
+    sensor->hum = -128.0f;
+
+    //Выделение памяти под инстанс датчика в зависимости от его интерфейса
+    if(sensor->type->interface == SINGLE_WIRE) {
+        status = sensor->type->allocator(sensor, anotherValues);
     }
-    //Выделение памяти под инстанс датчиков I2C
-    if(st == BMP280 || st == LM75) {
-        status = unitemp_I2C_sensorAlloc(sensor, st, anotherValues);
+    if(sensor->type->interface == I2C) {
+        status = unitemp_I2C_sensorAlloc(sensor, anotherValues);
     }
 
     //Если датчик успешно развёрнут, то добавление его в общий список и выход
     if(status) {
-        app->sensors[app->sensors_count] = sensor;
-        app->sensors_count++;
+        app->sensors[app->sensors_count++] = sensor;
         return sensor;
     }
     //Если ни один из типов не подошёл, то выход с очисткой
     free(sensor->name);
     free(sensor);
-    FURI_LOG_E(APP_NAME, "Sensor %s allocation error", name);
+    FURI_LOG_E(APP_NAME, "Sensor %s type is unsupported: %s", name, type->typename);
     return NULL;
 }
 
 void unitemp_sensor_free(Sensor* sensor) {
-    //Высвобождение памяти под инстанс датчиков I2C
-    if(sensor->type == BMP280 || sensor->type == LM75) {
+    if(sensor == NULL) {
+        FURI_LOG_E(APP_NAME, "Null pointer sensor releasing");
+        return;
+    }
+    if(sensor->type == NULL) {
+        FURI_LOG_E(APP_NAME, "Sensor type is null");
+        return;
+    }
+    if(sensor->type->mem_releaser == NULL) {
+        FURI_LOG_E(APP_NAME, "Sensor releaser is null");
+        return;
+    }
+    //Высвобождение памяти под инстанс
+    if(sensor->type->interface == SINGLE_WIRE) {
+        sensor->type->mem_releaser(sensor);
+    }
+
+    if(sensor->type->interface == I2C) {
         unitemp_I2C_sensorFree(sensor);
     }
     free(sensor->name);
@@ -268,7 +297,7 @@ bool unitemp_sensors_init(void) {
             furi_hal_power_enable_otg();
             FURI_LOG_D(APP_NAME, "OTG enabled");
         }
-        if(!(*app->sensors[i]->initializer)(app->sensors[i])) {
+        if(!(*app->sensors[i]->type->initializer)(app->sensors[i])) {
             FURI_LOG_E(
                 APP_NAME,
                 "An error occurred during sensor initialization %s",
@@ -290,14 +319,13 @@ bool unitemp_sensors_deInit(void) {
 
     //Перебор датчиков из списка
     for(size_t i = 0; i < app->sensors_count; i++) {
-        if(!(*app->sensors[i]->deinitializer)(app->sensors[i])) {
+        if(!(*app->sensors[i]->type->deinitializer)(app->sensors[i])) {
             FURI_LOG_E(
                 APP_NAME,
                 "An error occurred during sensor deinitialization %s",
                 app->sensors[i]->name);
             result = false;
         }
-        free(app->sensors[i]);
     }
     return result;
 }
@@ -306,7 +334,7 @@ UnitempStatus unitemp_sensor_updateData(Sensor* sensor) {
     if(sensor == NULL) return UT_ERROR;
 
     //Проверка на допустимость опроса датчика
-    if(furi_get_tick() - sensor->lastPollingTime < sensor->pollingInterval) {
+    if(furi_get_tick() - sensor->lastPollingTime < sensor->type->pollingInterval) {
         //Возврат ошибки если последний опрос датчика был неудачным
         if(sensor->status == UT_TIMEOUT) {
             return UT_TIMEOUT;
@@ -320,7 +348,8 @@ UnitempStatus unitemp_sensor_updateData(Sensor* sensor) {
         furi_hal_power_enable_otg();
     }
 
-    sensor->status = sensor->updater(sensor);
+    sensor->status = sensor->type->updater(sensor);
+    FURI_LOG_D(APP_NAME, "Sensor %s update status %d", sensor->name, sensor->status);
     if(app->settings.unit == FAHRENHEIT && sensor->status == UT_OK)
         uintemp_celsiumToFarengate(sensor);
     return sensor->status;

+ 26 - 43
Sensors.h

@@ -12,26 +12,6 @@ typedef enum {
     UT_ERROR, //Прочие ошибки
 } UnitempStatus;
 
-//Типы датчиков
-typedef enum {
-    DHT11,
-    DHT12_1W,
-    DHT12_I2C,
-    DHT20, //AM2108
-    DHT21, //AM2301
-    DHT22, //AM2302
-    AM2320_1W,
-    AM2320_I2C,
-    LM75,
-    DS18B20,
-    BMP180,
-    BMP280,
-    BME280,
-
-    //Порядок сенсоров сверху не менять!
-    SENSOR_TYPES_COUNT //Общее количество типов датчиков
-} SensorType;
-
 //Типы подключения датчиков
 typedef enum Interface {
     SINGLE_WIRE, //Собственный однопроводной протокол датчиков DHTXX и AM23XX
@@ -49,11 +29,10 @@ typedef struct GPIO {
     const GpioPin* pin;
 } GPIO;
 
-struct Sensor;
 /**
  * @brief Указатель функции выделения памяти и подготовки экземпляра датчика
  */
-typedef void(SensorAllocator)(void* sensor, SensorType st);
+typedef bool(SensorAllocator)(void* sensor, uint16_t* anotherValues);
 /**
  * @brief Указатель на функцию высвобождении памяти датчика
  */
@@ -71,6 +50,26 @@ typedef bool(SensorDeinitializer)(void* sensor);
  */
 typedef UnitempStatus(SensorUpdater)(void* sensor);
 
+//Типы датчиков
+typedef struct {
+    //Имя типа датчика
+    char* typename;
+    //Интерфейс подключения
+    Interface interface;
+    //Интервал опроса датчика
+    uint16_t pollingInterval;
+    //Функция выделения памяти для датчика
+    SensorAllocator* allocator;
+    //Функция высвыбождения памяти для датчика
+    SensorFree* mem_releaser;
+    //Функция инициализации датчика
+    SensorInitializer* initializer;
+    //Функция деинициализация датчика
+    SensorDeinitializer* deinitializer;
+    //Функция обновления значения датчка
+    SensorUpdater* updater;
+} SensorType;
+
 //Датчик
 typedef struct Sensor {
     //Имя датчика
@@ -81,33 +80,16 @@ typedef struct Sensor {
     float hum;
 
     //Тип датчика
-    SensorType type;
-    //Интерфейсы подключения
-    Interface interface;
+    const SensorType* type;
     //Статус последнего опроса датчика
     UnitempStatus status;
-
+    //Время последнего опроса датчика
+    uint32_t lastPollingTime;
     //Экземпляр датчика
     void* instance;
-    SensorAllocator* allocator;
-    SensorFree* memoryfree;
-    SensorInitializer* initializer;
-    SensorDeinitializer* deinitializer;
-    SensorUpdater* updater;
-
-    uint32_t lastPollingTime;
-    uint16_t pollingInterval;
 
 } Sensor;
 
-/**
- * @brief Получить имя типа датчика
- * 
- * @param st Тип датчика
- * @return Указатель на строку с именем типа датчика
- */
-const char* unitemp_getSensorTypeName(SensorType st);
-
 /**
  * @brief Конвертация номера порта на корпусе FZ в GPIO 
  * 
@@ -132,7 +114,7 @@ uint8_t unitemp_GPIO_toInt(const GpioPin* gpio);
  * @param anotherValues Массив других различных значений
  * @return Указатель на датчик
  */
-Sensor* unitemp_sensor_alloc(char* name, SensorType st, uint16_t* anotherValues);
+Sensor* unitemp_sensor_alloc(char* name, const SensorType* type, uint16_t* anotherValues);
 
 /**
  * @brief Инициализация загруженных датчиков
@@ -180,4 +162,5 @@ void unitemp_sensors_updateValues(void);
  */
 void unitemp_sensors_free(void);
 
+const SensorType* unitemp_getTypeFromInt(int type);
 #endif

+ 8 - 40
interfaces/I2CSensor.c

@@ -27,53 +27,21 @@ bool writeReg(I2CSensor* i2c_sensor, uint8_t reg, uint8_t value) {
     return status;
 }
 
-bool unitemp_I2C_sensorInit(void* s) {
+bool unitemp_I2C_sensorAlloc(void* s, uint16_t* anotherValues) {
     Sensor* sensor = (Sensor*)s;
-    I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
-    //BMP280
-    if(sensor->type == BMP280) {
-        if(BMP280_init(i2c_sensor)) {
-            sensor->status = UT_OK;
-            return true;
-        }
-    }
-    return false;
-}
-
-bool unitemp_I2C_sensorDeInit(void* s) {
-    Sensor* sensor = (Sensor*)s;
-    return sensor->deinitializer(s);
-}
-
-UnitempStatus unitemp_I2C_updateData(void* sensor) {
-    if(((Sensor*)sensor)->status == UT_ERROR || ((Sensor*)sensor)->status == UT_TIMEOUT) {
-        if(((Sensor*)sensor)->initializer(sensor) != true) return UT_ERROR;
-    }
-    BMP280_updateData(sensor);
-    return UT_OK;
-}
-
-bool unitemp_I2C_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherValues) {
     bool status = false;
     I2CSensor* instance = malloc(sizeof(I2CSensor));
-    instance->interface = I2C;
+    if(instance == NULL) {
+        FURI_LOG_E(APP_NAME, "Sensor %s instance allocation error", sensor->name);
+        return false;
+    }
     instance->i2c = &furi_hal_i2c_handle_external;
-
-    sensor->lastPollingTime = 0xFFFFFFFF;
-
     sensor->instance = instance;
-    sensor->type = st;
 
-    // //Настройки для BMP280
-    // if(st == BMP280) {
-    //     instance->minI2CAdr = 0x76;
-    //     instance->maxI2CAdr = 0x77;
-    // }
-    if(st == LM75) {
-        //Указание функций инициализации, деинициализации и обновления данных, а так же адреса на шине I2C
-        status = unitemp_LM75_alloc(sensor);
-    }
+    //Указание функций инициализации, деинициализации и обновления данных, а так же адреса на шине I2C
+    status = sensor->type->allocator(sensor, anotherValues);
 
+    //Установка адреса шины I2C
     if(anotherValues[0] >= instance->minI2CAdr && anotherValues[0] <= instance->maxI2CAdr) {
         instance->currentI2CAdr = anotherValues[0];
     } else {

+ 16 - 29
interfaces/I2CSensor.h

@@ -6,12 +6,6 @@
 #include <furi_hal_i2c.h>
 
 typedef struct I2CSensor {
-    //Тип интерфейса подключения датчика
-    Interface interface;
-    //Последнее успешное значение температуры
-    float lastTemp;
-    //Последнее успешное значение влажности
-    float lastHum;
     //Указатель на интерфейс I2C
     FuriHalI2cBusHandle* i2c;
     //Минимальный адрес устройства на шине I2C
@@ -25,25 +19,24 @@ typedef struct I2CSensor {
 
 } I2CSensor;
 
-/**
- * @brief Функция инициализации датчика на шине I2C
- * 
- * @param sensor Указатель на датчик
- * @return Истина если датчик на шине
- */
-bool unitemp_I2C_sensorInit(void* sensor);
 /**
  * @brief Выделение памяти для датчика на шине I2C
- * 
+ *
  * @param sensor Указатель на датчик
  * @param st Тип датчика
  * @return Истина если всё ок
  */
-bool unitemp_I2C_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherValues);
+bool unitemp_I2C_sensorAlloc(void* s, uint16_t* anotherValues);
 
 /**
- * @brief Прочитать значение регистра reg
+ * @brief Высвобождение памяти инстанса датчика
  * 
+ * @param sensor Указатель на датчик
+ */
+void unitemp_I2C_sensorFree(Sensor* sensor);
+/**
+ * @brief Прочитать значение регистра reg
+ *
  * @param i2c_sensor Указатель на датчик
  * @param reg Номер регистра
  * @return Значение регистра
@@ -51,19 +44,19 @@ bool unitemp_I2C_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherVal
 uint8_t readReg(I2CSensor* i2c_sensor, uint8_t reg);
 
 /**
- * @brief Прочитать масссив значений из памяти 
- * 
- * @param i2c_sensor 
- * @param startReg 
- * @param len 
- * @param data 
+ * @brief Прочитать масссив значений из памяти
+ *
+ * @param i2c_sensor
+ * @param startReg
+ * @param len
+ * @param data
  * @return Истина если устройство вернуло данные
  */
 bool readRegArray(I2CSensor* i2c_sensor, uint8_t startReg, uint8_t len, uint8_t* data);
 
 /**
  * @brief Записать значение в регистр
- * 
+ *
  * @param i2c_sensor Указатель на датчик
  * @param reg Номер регистра
  * @param value Значение для записи
@@ -71,10 +64,4 @@ bool readRegArray(I2CSensor* i2c_sensor, uint8_t startReg, uint8_t len, uint8_t*
  */
 bool writeReg(I2CSensor* i2c_sensor, uint8_t reg, uint8_t value);
 
-/**
- * @brief Высвобождение памяти инстанса датчика
- * 
- * @param sensor Указатель на датчик
- */
-void unitemp_I2C_sensorFree(Sensor* sensor);
 #endif

+ 80 - 64
interfaces/SingleWireSensor.c

@@ -6,27 +6,78 @@
 //Максимальное количество попугаев ожидания датчика
 #define POLLING_TIMEOUT_TICKS 10000
 
-bool unitemp_oneWire_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherValues) {
+/* Типы датчиков и их параметры */
+//DHT11
+const SensorType DHT11 = {
+    .typename = "DHT11",
+    .interface = SINGLE_WIRE,
+    .pollingInterval = 2000,
+    .allocator = unitemp_singleWire_alloc,
+    .mem_releaser = unitemp_singleWire_free,
+    .initializer = unitemp_singleWire_init,
+    .deinitializer = unitemp_singleWire_deinit,
+    .updater = unitemp_singleWire_update};
+const SensorType DHT12_SW = {
+    .typename = "DHT12 (1 Wire)",
+    .interface = SINGLE_WIRE,
+    .pollingInterval = 2000,
+    .allocator = unitemp_singleWire_alloc,
+    .mem_releaser = unitemp_singleWire_free,
+    .initializer = unitemp_singleWire_init,
+    .deinitializer = unitemp_singleWire_deinit,
+    .updater = unitemp_singleWire_update};
+
+const SensorType DHT21 = {
+    .typename = "DHT21",
+    .interface = SINGLE_WIRE,
+    .pollingInterval = 2000,
+    .allocator = unitemp_singleWire_alloc,
+    .mem_releaser = unitemp_singleWire_free,
+    .initializer = unitemp_singleWire_init,
+    .deinitializer = unitemp_singleWire_deinit,
+    .updater = unitemp_singleWire_update};
+const SensorType DHT22 = {
+    .typename = "DHT22",
+    .interface = SINGLE_WIRE,
+    .pollingInterval = 2000,
+    .allocator = unitemp_singleWire_alloc,
+    .mem_releaser = unitemp_singleWire_free,
+    .initializer = unitemp_singleWire_init,
+    .deinitializer = unitemp_singleWire_deinit,
+    .updater = unitemp_singleWire_update};
+const SensorType AM2320_SW = {
+    .typename = "AM2320 (1 Wire)",
+    .interface = SINGLE_WIRE,
+    .pollingInterval = 2000,
+    .allocator = unitemp_singleWire_alloc,
+    .mem_releaser = unitemp_singleWire_free,
+    .initializer = unitemp_singleWire_init,
+    .deinitializer = unitemp_singleWire_deinit,
+    .updater = unitemp_singleWire_update};
+
+bool unitemp_singleWire_alloc(void* s, uint16_t* anotherValues) {
+    Sensor* sensor = (Sensor*)s;
     SingleWireSensor* instance = malloc(sizeof(SingleWireSensor));
-    instance->interface = SINGLE_WIRE;
-    instance->lastPollingTime = 0xFFFFFFFF;
-
-    sensor->initializer = unitemp_oneWire_sensorInit;
-    sensor->deinitializer = unitemp_oneWire_sensorDeInit;
-    sensor->updater = unitemp_oneWire_updateData;
-
+    if(instance == NULL) {
+        FURI_LOG_E(APP_NAME, "Sensor %s instance allocation error", sensor->name);
+        return false;
+    }
     sensor->instance = instance;
-    sensor->type = st;
 
-    if(unitemp_GPIO_getFromInt(anotherValues[0]) != NULL) {
-        unitemp_oneWire_sensorSetGPIO(sensor, unitemp_GPIO_getFromInt(anotherValues[0]));
+    if(unitemp_singleWire_sensorSetGPIO(sensor, unitemp_GPIO_getFromInt(anotherValues[0]))) {
         return true;
     }
+    FURI_LOG_E(APP_NAME, "Sensor %s GPIO setting error", sensor->name);
     free(instance);
     return false;
 }
+void unitemp_singleWire_free(void* s) {
+    Sensor* sensor = (Sensor*)s;
+    free(sensor->instance);
+    FURI_LOG_D(APP_NAME, "Sensor %s memory successfully released", sensor->name);
+}
 
-bool unitemp_oneWire_sensorInit(void* sensor) {
+bool unitemp_singleWire_init(void* sensor) {
     SingleWireSensor* instance = ((Sensor*)sensor)->instance;
     if(instance == NULL || instance->gpio == NULL) {
         FURI_LOG_E(APP_NAME, "Sensor pointer is null!");
@@ -43,7 +94,7 @@ bool unitemp_oneWire_sensorInit(void* sensor) {
     return true;
 }
 
-bool unitemp_oneWire_sensorDeInit(void* sensor) {
+bool unitemp_singleWire_deinit(void* sensor) {
     SingleWireSensor* instance = ((Sensor*)sensor)->instance;
     if(instance == NULL || instance->gpio == NULL) return false;
     //Низкий уровень по умолчанию
@@ -57,41 +108,25 @@ bool unitemp_oneWire_sensorDeInit(void* sensor) {
     return true;
 }
 
-bool unitemp_oneWire_sensorSetGPIO(Sensor* sensor, const GPIO* gpio) {
+bool unitemp_singleWire_sensorSetGPIO(Sensor* sensor, const GPIO* gpio) {
     if(sensor == NULL || gpio == NULL) return false;
     SingleWireSensor* instance = sensor->instance;
     instance->gpio = gpio;
     return true;
 }
-const GPIO* unitemp_oneWire_sensorGetGPIO(Sensor* sensor) {
+const GPIO* unitemp_singleWire_sensorGetGPIO(Sensor* sensor) {
     if(sensor == NULL) return NULL;
     SingleWireSensor* instance = sensor->instance;
     return instance->gpio;
 }
 
-UnitempStatus unitemp_oneWire_updateData(void* sensor) {
-    SingleWireSensor* instance = ((Sensor*)sensor)->instance;
-    //Проверка на допустимость опроса датчика
-    if(furi_get_tick() - instance->lastPollingTime < POLLING_INTERVAL) {
-        //Возврат ошибки если последний опрос датчика был неудачным
-        if(instance->lastHum == -128.0f && instance->lastTemp == -128.0f) {
-            ((Sensor*)sensor)->hum = instance->lastHum;
-            ((Sensor*)sensor)->temp = instance->lastTemp;
-            return UT_TIMEOUT;
-        }
-
-        //Выход в случае раннего опроса
-        ((Sensor*)sensor)->hum = instance->lastHum;
-        ((Sensor*)sensor)->temp = instance->lastTemp;
-        return UT_EARLYPOOL;
-    }
+UnitempStatus unitemp_singleWire_update(void* s) {
+    Sensor* sensor = (Sensor*)s;
+    SingleWireSensor* instance = sensor->instance;
 
     //Массив для приёма данных
     uint8_t data[5] = {0};
 
-    //Сохранение времени последнего опроса
-    instance->lastPollingTime = furi_get_tick();
-
     /* Запрос */
     //Опускание линии
     furi_hal_gpio_write(instance->gpio->pin, false);
@@ -112,9 +147,6 @@ UnitempStatus unitemp_oneWire_updateData(void* sensor) {
         if(timeout > POLLING_TIMEOUT_TICKS) {
             //Включение прерываний
             __enable_irq();
-            //Запись неправильных значений
-            instance->lastHum = -128.0f;
-            instance->lastTemp = -128.0f;
             //Возврат признака отсутствующего датчика
             return UT_TIMEOUT;
         }
@@ -127,9 +159,6 @@ UnitempStatus unitemp_oneWire_updateData(void* sensor) {
         if(timeout > POLLING_TIMEOUT_TICKS) {
             //Включение прерываний
             __enable_irq();
-            //Запись неправильных значений
-            instance->lastHum = -128.0f;
-            instance->lastTemp = -128.0f;
             //Возврат признака отсутствующего датчика
             return UT_TIMEOUT;
         }
@@ -141,9 +170,6 @@ UnitempStatus unitemp_oneWire_updateData(void* sensor) {
         if(timeout > POLLING_TIMEOUT_TICKS) {
             //Включение прерываний
             __enable_irq();
-            //Запись неправильных значений
-            instance->lastHum = -128.0f;
-            instance->lastTemp = -128.0f;
             //Возврат признака отсутствующего датчика
             return UT_TIMEOUT;
         }
@@ -156,9 +182,6 @@ UnitempStatus unitemp_oneWire_updateData(void* sensor) {
         if(timeout > POLLING_TIMEOUT_TICKS) {
             //Включение прерываний
             __enable_irq();
-            //Запись неправильных значений
-            instance->lastHum = -128.0f;
-            instance->lastTemp = -128.0f;
             //Возврат признака отсутствующего датчика
             return UT_TIMEOUT;
         }
@@ -182,49 +205,42 @@ UnitempStatus unitemp_oneWire_updateData(void* sensor) {
 
     //Проверка контрольной суммы
     if((uint8_t)(data[0] + data[1] + data[2] + data[3]) != data[4]) {
-        //Запись неправильных значений
-        instance->lastHum = -128.0f;
-        instance->lastTemp = -128.0f;
         //Если контрольная сумма не совпала, возврат ошибки
         return UT_BADCRC;
     }
 
     /* Преобразование данных в явный вид */
     //DHT11 и DHT12
-    if(((Sensor*)sensor)->type == DHT11 || ((Sensor*)sensor)->type == DHT12_1W) {
-        instance->lastHum = (float)data[0];
-        instance->lastTemp = (float)data[2];
+    if(sensor->type == &DHT11 || sensor->type == &DHT12_SW) {
+        sensor->hum = (float)data[0];
+        sensor->temp = (float)data[2];
 
         //Проверка на отрицательность температуры
         if(data[3] != 0) {
             //Проверка знака
             if(!(data[3] & (1 << 7))) {
                 //Добавление положительной дробной части
-                instance->lastTemp += data[3] * 0.1f;
+                sensor->temp += data[3] * 0.1f;
             } else {
                 //А тут делаем отрицательное значение
                 data[3] &= ~(1 << 7);
-                instance->lastTemp += data[3] * 0.1f;
-                instance->lastTemp *= -1;
+                sensor->temp += data[3] * 0.1f;
+                sensor->temp *= -1;
             }
         }
     }
 
     //DHT21, DHT22, AM2320
-    if(((Sensor*)sensor)->type == DHT21 || ((Sensor*)sensor)->type == DHT22 ||
-       ((Sensor*)sensor)->type == AM2320_1W) {
-        instance->lastHum = (float)(((uint16_t)data[0] << 8) | data[1]) / 10;
+    if(sensor->type == &DHT21 || sensor->type == &DHT22 || sensor->type == &AM2320_SW) {
+        sensor->hum = (float)(((uint16_t)data[0] << 8) | data[1]) / 10;
         //Проверка на отрицательность температуры
         if(!(data[2] & (1 << 7))) {
-            instance->lastTemp = (float)(((uint16_t)data[2] << 8) | data[3]) / 10;
+            sensor->temp = (float)(((uint16_t)data[2] << 8) | data[3]) / 10;
         } else {
             data[2] &= ~(1 << 7);
-            instance->lastTemp = (float)(((uint16_t)data[2] << 8) | data[3]) / 10 * -1;
+            sensor->temp = (float)(((uint16_t)data[2] << 8) | data[3]) / 10 * -1;
         }
     }
-
-    ((Sensor*)sensor)->hum = instance->lastHum;
-    ((Sensor*)sensor)->temp = instance->lastTemp;
     //Возврат признака успешного опроса
     return UT_OK;
-}
+}

+ 21 - 15
interfaces/SingleWireSensor.h

@@ -3,27 +3,26 @@
 
 #include "../unitemp.h"
 
-//Интерфейс One Wire
+//Интерфейс Single Wire
 typedef struct {
-    //Тип интерфейса подключения датчика
-    Interface interface;
     //Порт подключения датчика
     const GPIO* gpio;
-    //Время последнего опроса
-    uint32_t lastPollingTime;
-    //Последнее успешное значение температуры
-    float lastTemp;
-    //Последнее успешное значение влажности
-    float lastHum;
 } SingleWireSensor;
 
+/* Датчики */
+extern const SensorType DHT11;
+extern const SensorType DHT12_SW;
+extern const SensorType DHT21;
+extern const SensorType DHT22;
+extern const SensorType AM2320_SW;
+
 /**
  * @brief Инициализация датчика
  * 
  * @param sensor Указатель на инициализируемый датчик
  * @return Истина если всё прошло успешно
  */
-bool unitemp_oneWire_sensorInit(void* sensor);
+bool unitemp_singleWire_init(void* sensor);
 
 /**
  * @brief Деинициализация датчика
@@ -31,7 +30,7 @@ bool unitemp_oneWire_sensorInit(void* sensor);
  * @param sensor Указатель на инициализируемый датчик
  * @return Истина если всё прошло успешно
  */
-bool unitemp_oneWire_sensorDeInit(void* sensor);
+bool unitemp_singleWire_deinit(void* sensor);
 
 /**
  * @brief Получение данных с датчика по однопроводному интерфейсу DHTxx и AM2xxx
@@ -39,7 +38,7 @@ bool unitemp_oneWire_sensorDeInit(void* sensor);
  * @param sensor Указатель на датчик
  * @return Статус опроса
  */
-UnitempStatus unitemp_oneWire_updateData(void* sensor);
+UnitempStatus unitemp_singleWire_update(void* sensor);
 
 /**
  * @brief Установить порт датчика
@@ -48,7 +47,7 @@ UnitempStatus unitemp_oneWire_updateData(void* sensor);
  * @param gpio Устанавливаемый порт
  * @return Истина если всё ок
  */
-bool unitemp_oneWire_sensorSetGPIO(Sensor* sensor, const GPIO* gpio);
+bool unitemp_singleWire_sensorSetGPIO(Sensor* sensor, const GPIO* gpio);
 
 /**
  * @brief Получить порт датчика
@@ -56,7 +55,7 @@ bool unitemp_oneWire_sensorSetGPIO(Sensor* sensor, const GPIO* gpio);
  * @param sensor Указатель на датчик
  * @return Указатель на GPIO
  */
-const GPIO* unitemp_oneWire_sensorGetGPIO(Sensor* sensor);
+const GPIO* unitemp_singleWire_sensorGetGPIO(Sensor* sensor);
 
 /**
  * @brief Выделение памяти под датчик на линии One Wire
@@ -64,5 +63,12 @@ const GPIO* unitemp_oneWire_sensorGetGPIO(Sensor* sensor);
  * @param sensor Указатель на датчик
  * @param st Тип датчика
  */
-bool unitemp_oneWire_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherValues);
+bool unitemp_singleWire_alloc(void* sensor, uint16_t* anotherValues);
+
+/**
+ * @brief Высвобождение памяти инстанса датчика
+ * 
+ * @param sensor Указатель на датчик
+ */
+void unitemp_singleWire_free(void* sensor);
 #endif

+ 82 - 77
sensors/BMP280.c

@@ -1,87 +1,92 @@
-#include "SensorsDriver.h"
-#include "BMP280.h"
+// #include "SensorsDriver.h"
+// #include "BMP280.h"
 
-#define TEMP_CAL_START_ADDR 0x88
-#define PRESS_CAL_START_ADDR 0x8E
+// #define TEMP_CAL_START_ADDR 0x88
+// #define PRESS_CAL_START_ADDR 0x8E
 
-static double bmp280_compensate_T_double(I2CSensor* i2c_sensor, int32_t adc_T) {
-    BMP280_instance* bmp280_instance = (BMP280_instance*)i2c_sensor->sensorInstance;
-    double var1, var2, T;
-    var1 = (((double)adc_T) / (double)16384.0 -
-            ((double)bmp280_instance->temp_cal.dig_T1) / (double)1024.0) *
-           ((double)bmp280_instance->temp_cal.dig_T2);
-    var2 = ((((double)adc_T) / (double)131072.0 -
-             ((double)bmp280_instance->temp_cal.dig_T1) / (double)8192.0) *
-            (((double)adc_T) / (double)131072.0 -
-             ((double)bmp280_instance->temp_cal.dig_T1) / (double)8192.0)) *
-           ((double)bmp280_instance->temp_cal.dig_T3);
-    T = (var1 + var2) / (double)5120.0;
-    return T;
-}
+// static double bmp280_compensate_T_double(I2CSensor* i2c_sensor, int32_t adc_T) {
+//     BMP280_instance* bmp280_instance = (BMP280_instance*)i2c_sensor->sensorInstance;
+//     double var1, var2, T;
+//     var1 = (((double)adc_T) / (double)16384.0 -
+//             ((double)bmp280_instance->temp_cal.dig_T1) / (double)1024.0) *
+//            ((double)bmp280_instance->temp_cal.dig_T2);
+//     var2 = ((((double)adc_T) / (double)131072.0 -
+//              ((double)bmp280_instance->temp_cal.dig_T1) / (double)8192.0) *
+//             (((double)adc_T) / (double)131072.0 -
+//              ((double)bmp280_instance->temp_cal.dig_T1) / (double)8192.0)) *
+//            ((double)bmp280_instance->temp_cal.dig_T3);
+//     T = (var1 + var2) / (double)5120.0;
+//     return T;
+// }
 
-static bool readCalValues(I2CSensor* i2c_sensor) {
-    BMP280_instance* bmp280_instance = (BMP280_instance*)i2c_sensor->sensorInstance;
-    if(!readRegArray(i2c_sensor, TEMP_CAL_START_ADDR, 6, (uint8_t*)&bmp280_instance->temp_cal))
-        return false;
+// static bool readCalValues(I2CSensor* i2c_sensor) {
+//     BMP280_instance* bmp280_instance = (BMP280_instance*)i2c_sensor->sensorInstance;
+//     if(!readRegArray(i2c_sensor, TEMP_CAL_START_ADDR, 6, (uint8_t*)&bmp280_instance->temp_cal))
+//         return false;
 
-    if(!readRegArray(i2c_sensor, PRESS_CAL_START_ADDR, 18, (uint8_t*)&bmp280_instance->press_cal))
-        return false;
-    FURI_LOG_D(
-        APP_NAME,
-        "Sensor BMP280 (0x%02X): T1-3: %d, %d, %d; P1-9: %d, %d, %d, %d, %d, %d, %d, %d, %d",
-        i2c_sensor->currentI2CAdr,
-        bmp280_instance->temp_cal.dig_T1,
-        bmp280_instance->temp_cal.dig_T2,
-        bmp280_instance->temp_cal.dig_T3,
-        bmp280_instance->press_cal.dig_P1,
-        bmp280_instance->press_cal.dig_P2,
-        bmp280_instance->press_cal.dig_P3,
-        bmp280_instance->press_cal.dig_P4,
-        bmp280_instance->press_cal.dig_P5,
-        bmp280_instance->press_cal.dig_P6,
-        bmp280_instance->press_cal.dig_P7,
-        bmp280_instance->press_cal.dig_P8,
-        bmp280_instance->press_cal.dig_P9);
-    return true;
-}
+//     if(!readRegArray(i2c_sensor, PRESS_CAL_START_ADDR, 18, (uint8_t*)&bmp280_instance->press_cal))
+//         return false;
+//     FURI_LOG_D(
+//         APP_NAME,
+//         "Sensor BMP280 (0x%02X): T1-3: %d, %d, %d; P1-9: %d, %d, %d, %d, %d, %d, %d, %d, %d",
+//         i2c_sensor->currentI2CAdr,
+//         bmp280_instance->temp_cal.dig_T1,
+//         bmp280_instance->temp_cal.dig_T2,
+//         bmp280_instance->temp_cal.dig_T3,
+//         bmp280_instance->press_cal.dig_P1,
+//         bmp280_instance->press_cal.dig_P2,
+//         bmp280_instance->press_cal.dig_P3,
+//         bmp280_instance->press_cal.dig_P4,
+//         bmp280_instance->press_cal.dig_P5,
+//         bmp280_instance->press_cal.dig_P6,
+//         bmp280_instance->press_cal.dig_P7,
+//         bmp280_instance->press_cal.dig_P8,
+//         bmp280_instance->press_cal.dig_P9);
+//     return true;
+// }
 
-bool BMP280_init(I2CSensor* i2c_sensor) {
-    //Перезагрузка
-    writeReg(i2c_sensor, 0xE0, 0xB6);
-    //Чтение ID датчика
-    if(readReg(i2c_sensor, 0xD0) != 0x58) {
-        return false;
-    }
-    i2c_sensor->sensorInstance = malloc(sizeof(BMP280_instance));
-    //Чтение калибровочных значений
-    if(!readCalValues(i2c_sensor)) {
-        return false;
-    }
+// bool BMP280_init(I2CSensor* i2c_sensor) {
+//     //Перезагрузка
+//     writeReg(i2c_sensor, 0xE0, 0xB6);
+//     //Чтение ID датчика
+//     if(readReg(i2c_sensor, 0xD0) != 0x58) {
+//         return false;
+//     }
+//     i2c_sensor->sensorInstance = malloc(sizeof(BMP280_instance));
+//     //Чтение калибровочных значений
+//     if(!readCalValues(i2c_sensor)) {
+//         return false;
+//     }
 
-    writeReg(i2c_sensor, 0xF4, 0b01010111);
-    writeReg(i2c_sensor, 0xF5, 0b10110100);
+//     writeReg(i2c_sensor, 0xF4, 0b01010111);
+//     writeReg(i2c_sensor, 0xF5, 0b10110100);
 
-    return true;
-}
+//     return true;
+// }
+// //Настройки для BMP280
+// if(st == BMP280) {
+//     instance->minI2CAdr = 0x76;
+//     instance->maxI2CAdr = 0x77;
+// }
 
-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();
+// 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();
 
-    // 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;
-    int32_t adc_T = ((int32_t)buff[2] << 12) | ((int32_t)buff[1] << 4) | ((int32_t)buff[2] >> 4);
-    sensor->temp = bmp280_compensate_T_double(i2c_sensor, adc_T);
-    return true;
-}
+//     uint8_t buff[3];
+//     if(!readRegArray(i2c_sensor, 0xFA, 3, buff)) return false;
+//     int32_t adc_T = ((int32_t)buff[2] << 12) | ((int32_t)buff[1] << 4) | ((int32_t)buff[2] >> 4);
+//     sensor->temp = bmp280_compensate_T_double(i2c_sensor, adc_T);
+//     return true;
+// }

+ 43 - 43
sensors/BMP280.h

@@ -1,43 +1,43 @@
-#ifndef UNITEMP_BMP280
-#define UNITEMP_BMP280
-#include "../unitemp.h"
-#include "../Sensors.h"
-#include "../interfaces/I2CSensor.h"
-#include "SensorsDriver.h"
-
-typedef struct {
-    uint16_t dig_T1;
-    int16_t dig_T2;
-    int16_t dig_T3;
-} BMP280_temp_cal;
-
-typedef struct {
-    uint16_t dig_P1;
-    int16_t dig_P2;
-    int16_t dig_P3;
-    int16_t dig_P4;
-    int16_t dig_P5;
-    int16_t dig_P6;
-    int16_t dig_P7;
-    int16_t dig_P8;
-    int16_t dig_P9;
-} BMP280_press_cal;
-
-typedef struct {
-    BMP280_temp_cal temp_cal;
-    BMP280_press_cal press_cal;
-
-} BMP280_instance;
-
-/**
- * @brief Инициализация датчика
- * 
- * @param i2c_sensor Указатель на датчик
- * @return Инстина если инициализация успешная
- */
-
-bool BMP280_init(I2CSensor* i2c_sensor);
-
-bool BMP280_updateData(Sensor* sensor);
-
-#endif
+// #ifndef UNITEMP_BMP280
+// #define UNITEMP_BMP280
+// #include "../unitemp.h"
+// #include "../Sensors.h"
+// #include "../interfaces/I2CSensor.h"
+// #include "SensorsDriver.h"
+
+// typedef struct {
+//     uint16_t dig_T1;
+//     int16_t dig_T2;
+//     int16_t dig_T3;
+// } BMP280_temp_cal;
+
+// typedef struct {
+//     uint16_t dig_P1;
+//     int16_t dig_P2;
+//     int16_t dig_P3;
+//     int16_t dig_P4;
+//     int16_t dig_P5;
+//     int16_t dig_P6;
+//     int16_t dig_P7;
+//     int16_t dig_P8;
+//     int16_t dig_P9;
+// } BMP280_press_cal;
+
+// typedef struct {
+//     BMP280_temp_cal temp_cal;
+//     BMP280_press_cal press_cal;
+
+// } BMP280_instance;
+
+// /**
+//  * @brief Инициализация датчика
+//  *
+//  * @param i2c_sensor Указатель на датчик
+//  * @return Инстина если инициализация успешная
+//  */
+
+// bool BMP280_init(I2CSensor* i2c_sensor);
+
+// bool BMP280_updateData(Sensor* sensor);
+
+// #endif

+ 13 - 7
sensors/LM75.c

@@ -13,14 +13,20 @@
 #define LM75_CONFIG_FAULTQUEUE_4 0b00010000
 #define LM75_CONFIG_FAULTQUEUE_6 0b00011000
 
-bool unitemp_LM75_alloc(Sensor* sensor) {
+const SensorType LM75 = {
+    .typename = "LM75",
+    .interface = I2C,
+    .pollingInterval = 500,
+    .allocator = unitemp_LM75_alloc,
+    .mem_releaser = unitemp_LM75_free,
+    .initializer = unitemp_LM75_init,
+    .deinitializer = unitemp_LM75_deinit,
+    .updater = unitemp_LM75_update};
+
+bool unitemp_LM75_alloc(void* s, uint16_t* anotherValues) {
+    UNUSED(anotherValues);
+    Sensor* sensor = (Sensor*)s;
     I2CSensor* i2c_sensor = (I2CSensor*)sensor->instance;
-    //Функции работы с датчиком
-    sensor->initializer = unitemp_LM75_init;
-    sensor->deinitializer = unitemp_LM75_deinit;
-    sensor->updater = unitemp_LM75_update;
-    sensor->memoryfree = unitemp_LM75_free;
-    sensor->pollingInterval = 1000;
 
     //Адреса на шине I2C (7 бит)
     i2c_sensor->minI2CAdr = 0b1001000;

+ 7 - 7
sensors/LM75.h

@@ -4,18 +4,18 @@
 #include "../unitemp.h"
 #include "SensorsDriver.h"
 #include "../Sensors.h"
-
+extern const SensorType LM75;
 /**
  * @brief Выделение памяти и установка начальных значений датчика LM75
- * 
+ *
  * @param sensor Указатель на создаваемый датчик
  * @return Истина при успехе
  */
-bool unitemp_LM75_alloc(Sensor* sensor);
+bool unitemp_LM75_alloc(void* s, uint16_t* anotherValues);
 
 /**
  * @brief Инициализации датчика LM75
- * 
+ *
  * @param sensor Указатель на датчик (тип Sensor)
  * @return Истина если инициализация упспешная
  */
@@ -23,14 +23,14 @@ bool unitemp_LM75_init(void* sensor);
 
 /**
  * @brief Деинициализация датчика
- * 
+ *
  * @param sensor Указатель на датчик (тип Sensor)
  */
 bool unitemp_LM75_deinit(void* s);
 
 /**
  * @brief Обновление значений из датчика
- * 
+ *
  * @param sensor Указатель на датчик (тип Sensor)
  * @return Истина если данныее были получены
  */
@@ -38,7 +38,7 @@ UnitempStatus unitemp_LM75_update(void* s);
 
 /**
  * @brief Высвободить память датчика
- * 
+ *
  * @param sensor Указатель на датчик (тип Sensor)
  */
 void unitemp_LM75_free(void* sensor);

+ 0 - 1
unitemp.h

@@ -10,7 +10,6 @@
 #include <gui/gui.h>
 #include <gui/view_dispatcher.h>
 #include <gui/modules/widget.h>
-
 //Уведомления
 #include <notification/notification.h>
 #include <notification/notification_messages.h>