Sfoglia il codice sorgente

Started work on the BMP280 sensor

Victor 3 anni fa
parent
commit
b0283f3308
5 ha cambiato i file con 148 aggiunte e 9 eliminazioni
  1. 23 7
      Sensors.c
  2. 80 0
      interfaces/I2CSensor.c
  3. 44 0
      interfaces/I2CSensor.h
  4. 1 0
      interfaces/OneWireSensor.c
  5. 0 2
      unitemp.c

+ 23 - 7
Sensors.c

@@ -1,5 +1,6 @@
 #include "Sensors.h"
 #include "./interfaces/OneWireSensor.h"
+#include "./interfaces/I2CSensor.h"
 
 #include <furi_hal_power.h>
 
@@ -144,14 +145,13 @@ bool unitemp_sensors_load() {
         uint16_t otherValues[] = {otherValue};
         //Проверка типа датчика
         if(type < SENSOR_TYPES_COUNT && sizeof(name) <= 11) {
-            app->sensors[app->sensors_count] = unitemp_sensor_alloc(name, type, otherValues);
-            if(app->sensors[app->sensors_count] != NULL) {
-                //Сохранение датчика если всё ок
-                app->sensors_count++;
-            }
+            unitemp_sensor_alloc(name, type, otherValues);
         }
         line = strtok((char*)NULL, "\n");
     }
+    uint16_t otherValues[] = {0x76};
+    unitemp_sensor_alloc("BMP280", BMP280, otherValues);
+
     free(file_buf);
     file_stream_close(app->file_stream);
     stream_free(app->file_stream);
@@ -207,6 +207,7 @@ bool unitemp_sensors_save(void) {
 }
 
 Sensor* unitemp_sensor_alloc(char* name, SensorType st, uint16_t* anotherValues) {
+    bool status = false;
     //Выделение памяти под датчик
     Sensor* sensor = malloc(sizeof(Sensor));
     if(sensor == NULL) return false;
@@ -216,9 +217,24 @@ Sensor* unitemp_sensor_alloc(char* name, SensorType st, uint16_t* anotherValues)
 
     //Выделение памяти под инстанс датчиков One Wire
     if(st == DHT11 || st == DHT12_1W || st == DHT21 || st == DHT22 || st == AM2320_1W) {
-        unitemp_oneWire_sensorAlloc(sensor, st, anotherValues);
+        status = unitemp_oneWire_sensorAlloc(sensor, st, anotherValues);
+    }
+    //Выделение памяти под инстанс датчиков I2C
+    if(st == BMP280) {
+        status = unitemp_I2C_sensorAlloc(sensor, st, anotherValues);
     }
-    return sensor;
+
+    //Если датчик успешно развёрнут, то добавление его в общий список и выход
+    if(status) {
+        app->sensors[app->sensors_count] = sensor;
+        app->sensors_count++;
+        return sensor;
+    }
+    //Если ни один из типов не подошёл, то выход с очисткой
+    free(sensor->name);
+    free(sensor);
+    FURI_LOG_E(APP_NAME, "Sensor %s allocation error", name);
+    return NULL;
 }
 
 bool unitemp_sensors_init(void) {

+ 80 - 0
interfaces/I2CSensor.c

@@ -0,0 +1,80 @@
+#include "I2CSensor.h"
+
+static uint8_t readReg(I2CSensor* i2c_sensor, uint8_t reg) {
+    //Блокировка шины
+    furi_hal_i2c_acquire(i2c_sensor->i2c);
+    uint8_t buff[1];
+    furi_hal_i2c_read_mem(i2c_sensor->i2c, i2c_sensor->currentI2CAdr << 1, reg, buff, 1, 0xFF);
+    furi_hal_i2c_release(i2c_sensor->i2c);
+    return buff[0];
+}
+static void 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);
+    furi_hal_i2c_release(i2c_sensor->i2c);
+}
+
+bool unitemp_I2C_sensorInit(void* sensor) {
+    I2CSensor* i2c_sensor = (I2CSensor*)((Sensor*)sensor)->instance;
+    //BMP280
+    if(((Sensor*)sensor)->type == BMP280) {
+        //Перезагрузка
+        writeReg(i2c_sensor, 0xE0, 0xB6);
+        //Чтение ID датчика
+        uint8_t id = readReg(i2c_sensor, 0xD0);
+        if(id != 0x58) {
+            ((Sensor*)sensor)->status = UT_ERROR;
+            return false;
+        }
+
+        //TODO: Дальнейшая инициализация
+
+        ((Sensor*)sensor)->status = UT_OK;
+        return true;
+    }
+    return false;
+}
+
+bool unitemp_I2C_sensorDeInit(void* sensor) {
+    //TODO датчик в спячку, очистить память
+    UNUSED(sensor);
+    return true;
+}
+
+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;
+    }
+    //I2CSensor* i2c_sensor = (I2CSensor*)((Sensor*)sensor)->instance;
+    return UT_OK;
+}
+
+bool unitemp_I2C_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anotherValues) {
+    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->instance = instance;
+    sensor->type = st;
+
+    //Настройки для BMP280
+    if(st == BMP280) {
+        instance->minI2CAdr = 0x76;
+        instance->maxI2CAdr = 0x77;
+    }
+
+    if(anotherValues[0] >= instance->minI2CAdr && anotherValues[0] <= instance->maxI2CAdr) {
+        instance->currentI2CAdr = anotherValues[0];
+    } else {
+        instance->currentI2CAdr = instance->minI2CAdr;
+    }
+    return true;
+}

+ 44 - 0
interfaces/I2CSensor.h

@@ -0,0 +1,44 @@
+#ifndef UNITEMP_I2C
+#define UNITEMP_I2C
+
+#include "../unitemp.h"
+
+#include <furi_hal_i2c.h>
+
+typedef struct I2CSensor {
+    //Тип интерфейса подключения датчика
+    Interface interface;
+    //Время последнего опроса
+    uint32_t lastPollingTime;
+    //Последнее успешное значение температуры
+    float lastTemp;
+    //Последнее успешное значение влажности
+    float lastHum;
+    //Указатель на интерфейс I2C
+    FuriHalI2cBusHandle* i2c;
+    //Минимальный адрес устройства на шине I2C
+    uint8_t minI2CAdr;
+    //Максимальный адрес устройства на шине I2C
+    uint8_t maxI2CAdr;
+    //Текущий адрес устройства на шине I2C
+    uint8_t currentI2CAdr;
+
+} 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);
+
+#endif

+ 1 - 0
interfaces/OneWireSensor.c

@@ -22,6 +22,7 @@ bool unitemp_oneWire_sensorAlloc(Sensor* sensor, SensorType st, uint16_t* anothe
         unitemp_oneWire_sensorSetGPIO(sensor, unitemp_GPIO_getFromInt(anotherValues[0]));
         return true;
     }
+    free(instance);
     return false;
 }
 

+ 0 - 2
unitemp.c

@@ -141,7 +141,6 @@ static bool unitemp_loadSettings(void) {
             } else {
                 app->settings.infinityBacklight = true;
             }
-            FURI_LOG_D(APP_NAME, "INFINITY_BACKLIGHT: %d\r\n", p);
         } else if(!strcmp(buff, "UNIT")) {
             //Чтение значения параметра
             int p = 0;
@@ -151,7 +150,6 @@ static bool unitemp_loadSettings(void) {
             } else {
                 app->settings.unit = FAHRENHEIT;
             }
-            FURI_LOG_D(APP_NAME, "UNIT: %d\r\n", p);
         } else {
             FURI_LOG_W(APP_NAME, "Unknown settings parameter: %s\r\n", buff);
         }