Просмотр исходного кода

Added an excluding for adding sensors ds18x2x with the same ID. Minor fixes on the one wire bus

Victor 3 лет назад
Родитель
Сommit
b32454c8da
4 измененных файлов с 94 добавлено и 43 удалено
  1. 48 32
      interfaces/OneWireSensor.c
  2. 12 3
      interfaces/OneWireSensor.h
  3. 2 1
      unitemp.c
  4. 32 7
      views/SensorEdit_view.c

+ 48 - 32
interfaces/OneWireSensor.c

@@ -26,10 +26,10 @@ OneWireBus* uintemp_onewire_bus_alloc(const GPIO* gpio) {
 
 
     //Проверка на наличие шины на этом порте
     //Проверка на наличие шины на этом порте
     for(uint8_t i = 0; i < app->sensors_count; i++) {
     for(uint8_t i = 0; i < app->sensors_count; i++) {
-        if(app->sensors[i]->type == &DS18x2x &&
-           ((OneWireBus*)(app->sensors[i]->instance))->gpio == gpio) {
-            ((OneWireBus*)(app->sensors[i]->instance))->device_count++;
-            return ((OneWireBus*)(app->sensors[i]->instance));
+        if(app->sensors[i]->type->interface == &ONE_WIRE &&
+           ((OneWireSensor*)app->sensors[i]->instance)->bus->gpio->num == gpio->num) {
+            //Если шина на этом порту уже есть, то возврат указателя на шину
+            return ((OneWireSensor*)app->sensors[i]->instance)->bus;
         }
         }
     }
     }
 
 
@@ -38,14 +38,16 @@ OneWireBus* uintemp_onewire_bus_alloc(const GPIO* gpio) {
     bus->gpio = gpio;
     bus->gpio = gpio;
     bus->powerMode = PWR_ACTIVE;
     bus->powerMode = PWR_ACTIVE;
 
 
-    FURI_LOG_D(APP_NAME, "one wire bus (port %d) allocated", unitemp_gpio_toInt(gpio));
+    FURI_LOG_D(APP_NAME, "one wire bus (port %d) allocated", gpio->num);
 
 
     return bus;
     return bus;
 }
 }
 
 
 bool unitemp_onewire_bus_init(OneWireBus* bus) {
 bool unitemp_onewire_bus_init(OneWireBus* bus) {
     if(bus == NULL) return false;
     if(bus == NULL) return false;
-    if(bus->device_count > 0) return true;
+    bus->device_count++;
+    //Выход если шина уже была инициализирована
+    if(bus->device_count > 1) return true;
 
 
     unitemp_gpio_lock(bus->gpio, &ONE_WIRE);
     unitemp_gpio_lock(bus->gpio, &ONE_WIRE);
     //Высокий уровень по умолчанию
     //Высокий уровень по умолчанию
@@ -56,15 +58,15 @@ bool unitemp_onewire_bus_init(OneWireBus* bus) {
         GpioModeOutputOpenDrain, //Режим работы - открытый сток
         GpioModeOutputOpenDrain, //Режим работы - открытый сток
         GpioPullUp, //Принудительная подтяжка линии данных к питанию
         GpioPullUp, //Принудительная подтяжка линии данных к питанию
         GpioSpeedVeryHigh); //Скорость работы - максимальная
         GpioSpeedVeryHigh); //Скорость работы - максимальная
-    bus->device_count++;
 
 
     return true;
     return true;
 }
 }
 bool unitemp_onewire_bus_deinit(OneWireBus* bus) {
 bool unitemp_onewire_bus_deinit(OneWireBus* bus) {
+    FURI_LOG_D(APP_NAME, "devices on wire %d: %d", bus->gpio->num, bus->device_count);
     bus->device_count--;
     bus->device_count--;
     if(bus->device_count <= 0) {
     if(bus->device_count <= 0) {
         bus->device_count = 0;
         bus->device_count = 0;
-        unitemp_gpio_lock(bus->gpio, &ONE_WIRE);
+        unitemp_gpio_unlock(bus->gpio);
         //Режим работы - аналог, подтяжка выключена
         //Режим работы - аналог, подтяжка выключена
         furi_hal_gpio_init(
         furi_hal_gpio_init(
             bus->gpio->pin, //Порт FZ
             bus->gpio->pin, //Порт FZ
@@ -117,15 +119,15 @@ void unitemp_onewire_send_bit(OneWireBus* bus, bool state) {
     }
     }
 }
 }
 
 
-void unitemp_onewire_send_byte(OneWireBus* bus, uint8_t data) {
+void unitemp_onewire_bus_send_byte(OneWireBus* bus, uint8_t data) {
     for(int i = 0; i < 8; i++) {
     for(int i = 0; i < 8; i++) {
         unitemp_onewire_send_bit(bus, (data & (1 << i)) != 0);
         unitemp_onewire_send_bit(bus, (data & (1 << i)) != 0);
     }
     }
 }
 }
 
 
-void unitemp_onewire_send_byteArray(OneWireBus* bus, uint8_t* data, uint8_t len) {
+void unitemp_onewire_bus_send_byteArray(OneWireBus* bus, uint8_t* data, uint8_t len) {
     for(uint8_t i = 0; i < len; i++) {
     for(uint8_t i = 0; i < len; i++) {
-        unitemp_onewire_send_byte(bus, data[i]);
+        unitemp_onewire_bus_send_byte(bus, data[i]);
     }
     }
 }
 }
 
 
@@ -172,7 +174,7 @@ bool unitemp_onewire_CRC_check(uint8_t* data, uint8_t len) {
 
 
 bool unitemp_onewire_sensor_readID(OneWireSensor* instance) {
 bool unitemp_onewire_sensor_readID(OneWireSensor* instance) {
     if(!unitemp_onewire_bus_start(instance->bus)) return false;
     if(!unitemp_onewire_bus_start(instance->bus)) return false;
-    unitemp_onewire_send_byte(instance->bus, 0x33); // Чтение ПЗУ
+    unitemp_onewire_bus_send_byte(instance->bus, 0x33); // Чтение ПЗУ
     unitemp_onewire_read_byteArray(instance->bus, instance->deviceID, 8);
     unitemp_onewire_read_byteArray(instance->bus, instance->deviceID, 8);
     if(!unitemp_onewire_CRC_check(instance->deviceID, 8)) {
     if(!unitemp_onewire_CRC_check(instance->deviceID, 8)) {
         memset(instance->deviceID, 0, 8);
         memset(instance->deviceID, 0, 8);
@@ -205,7 +207,7 @@ uint8_t* unitemp_onewire_enum_next(OneWireBus* bus) {
     uint8_t next = 0;
     uint8_t next = 0;
 
 
     uint8_t p = 1;
     uint8_t p = 1;
-    unitemp_onewire_send_byte(bus, 0xF0);
+    unitemp_onewire_bus_send_byte(bus, 0xF0);
     uint8_t newfork = 0;
     uint8_t newfork = 0;
     for(;;) {
     for(;;) {
         uint8_t not0 = unitemp_onewire_read_bit(bus);
         uint8_t not0 = unitemp_onewire_read_bit(bus);
@@ -254,9 +256,9 @@ uint8_t* unitemp_onewire_enum_next(OneWireBus* bus) {
     return &onewire_enum[0];
     return &onewire_enum[0];
 }
 }
 
 
-void unitemp_onewire_sensor_select(OneWireSensor* instance) {
-    unitemp_onewire_send_byte(instance->bus, 0x55);
-    unitemp_onewire_send_byteArray(instance->bus, instance->deviceID, 8);
+void unitemp_onewire_bus_select_sensor(OneWireSensor* instance) {
+    unitemp_onewire_bus_send_byte(instance->bus, 0x55);
+    unitemp_onewire_bus_send_byteArray(instance->bus, instance->deviceID, 8);
 }
 }
 
 
 bool unitemp_onewire_sensor_alloc(Sensor* sensor, char* args) {
 bool unitemp_onewire_sensor_alloc(Sensor* sensor, char* args) {
@@ -294,6 +296,7 @@ bool unitemp_onewire_sensor_alloc(Sensor* sensor, char* args) {
     instance->familyCode = instance->deviceID[0];
     instance->familyCode = instance->deviceID[0];
 
 
     instance->bus = uintemp_onewire_bus_alloc(unitemp_gpio_getFromInt(gpio));
     instance->bus = uintemp_onewire_bus_alloc(unitemp_gpio_getFromInt(gpio));
+
     if(instance != NULL) {
     if(instance != NULL) {
         return true;
         return true;
     }
     }
@@ -303,10 +306,12 @@ bool unitemp_onewire_sensor_alloc(Sensor* sensor, char* args) {
 }
 }
 
 
 bool unitemp_onewire_sensor_free(Sensor* sensor) {
 bool unitemp_onewire_sensor_free(Sensor* sensor) {
-    if(((OneWireSensor*)sensor->instance)->bus->device_count == 0) {
-        unitemp_gpio_unlock(((OneWireSensor*)sensor->instance)->bus->gpio);
-        free(((OneWireSensor*)sensor->instance)->bus);
+    if(((OneWireSensor*)sensor->instance)->bus != NULL) {
+        if(((OneWireSensor*)sensor->instance)->bus->device_count == 0) {
+            free(((OneWireSensor*)sensor->instance)->bus);
+        }
     }
     }
+
     free(sensor->instance);
     free(sensor->instance);
 
 
     return true;
     return true;
@@ -314,28 +319,31 @@ bool unitemp_onewire_sensor_free(Sensor* sensor) {
 
 
 bool unitemp_onewire_sensor_init(Sensor* sensor) {
 bool unitemp_onewire_sensor_init(Sensor* sensor) {
     OneWireSensor* instance = sensor->instance;
     OneWireSensor* instance = sensor->instance;
-    if(instance == NULL || instance->bus->gpio == NULL) {
+    if(instance == NULL || instance->bus == NULL) {
         FURI_LOG_E(APP_NAME, "Sensor pointer is null!");
         FURI_LOG_E(APP_NAME, "Sensor pointer is null!");
         return false;
         return false;
     }
     }
+
     unitemp_onewire_bus_init(instance->bus);
     unitemp_onewire_bus_init(instance->bus);
     furi_delay_ms(1);
     furi_delay_ms(1);
 
 
     if(instance->familyCode == FC_DS18B20 || instance->familyCode == FC_DS1822) {
     if(instance->familyCode == FC_DS18B20 || instance->familyCode == FC_DS1822) {
         //Установка разрядности в 10 бит
         //Установка разрядности в 10 бит
         if(!unitemp_onewire_bus_start(instance->bus)) return false;
         if(!unitemp_onewire_bus_start(instance->bus)) return false;
-        unitemp_onewire_sensor_select(instance);
-        unitemp_onewire_send_byte(instance->bus, 0x4E); // Запись в память
+        unitemp_onewire_bus_select_sensor(instance);
+        unitemp_onewire_bus_send_byte(instance->bus, 0x4E); // Запись в память
         uint8_t buff[3];
         uint8_t buff[3];
-        buff[0] = 0x4B; //Значение нижнего предела
-        buff[1] = 0x46; //Значение высшего предела
+        //Значения тревоги
+        buff[0] = 0x4B; //Значение нижнего предела температуры
+        buff[1] = 0x46; //Значение верхнего предела температуры
+        //Конфигурация
         buff[2] = 0x3F; //10 бит разрядность преобразования
         buff[2] = 0x3F; //10 бит разрядность преобразования
-        unitemp_onewire_send_byteArray(instance->bus, buff, 3);
+        unitemp_onewire_bus_send_byteArray(instance->bus, buff, 3);
 
 
         //Сохранение значений в EEPROM для автоматического восстановления после сбоев питания
         //Сохранение значений в EEPROM для автоматического восстановления после сбоев питания
         if(!unitemp_onewire_bus_start(instance->bus)) return false;
         if(!unitemp_onewire_bus_start(instance->bus)) return false;
-        unitemp_onewire_sensor_select(instance);
-        unitemp_onewire_send_byte(instance->bus, 0x48); // Запись в EEPROM
+        unitemp_onewire_bus_select_sensor(instance);
+        unitemp_onewire_bus_send_byte(instance->bus, 0x48); // Запись в EEPROM
     }
     }
 
 
     return true;
     return true;
@@ -343,7 +351,7 @@ bool unitemp_onewire_sensor_init(Sensor* sensor) {
 
 
 bool unitemp_onewire_sensor_deinit(Sensor* sensor) {
 bool unitemp_onewire_sensor_deinit(Sensor* sensor) {
     OneWireSensor* instance = sensor->instance;
     OneWireSensor* instance = sensor->instance;
-    if(instance == NULL || instance->bus->gpio == NULL) return false;
+    if(instance == NULL || instance->bus == NULL) return false;
     unitemp_onewire_bus_deinit(instance->bus);
     unitemp_onewire_bus_deinit(instance->bus);
 
 
     return true;
     return true;
@@ -353,8 +361,8 @@ UnitempStatus unitemp_onewire_sensor_update(Sensor* sensor) {
     OneWireSensor* instance = sensor->instance;
     OneWireSensor* instance = sensor->instance;
     if(sensor->status != UT_POLLING) {
     if(sensor->status != UT_POLLING) {
         if(!unitemp_onewire_bus_start(instance->bus)) return UT_TIMEOUT;
         if(!unitemp_onewire_bus_start(instance->bus)) return UT_TIMEOUT;
-        unitemp_onewire_sensor_select(instance);
-        unitemp_onewire_send_byte(instance->bus, 0x44); // convert t
+        unitemp_onewire_bus_select_sensor(instance);
+        unitemp_onewire_bus_send_byte(instance->bus, 0x44); // convert t
         if(instance->bus->powerMode == PWR_PASSIVE) {
         if(instance->bus->powerMode == PWR_PASSIVE) {
             furi_hal_gpio_write(instance->bus->gpio->pin, true);
             furi_hal_gpio_write(instance->bus->gpio->pin, true);
             furi_hal_gpio_init(
             furi_hal_gpio_init(
@@ -368,8 +376,8 @@ UnitempStatus unitemp_onewire_sensor_update(Sensor* sensor) {
                 instance->bus->gpio->pin, GpioModeOutputOpenDrain, GpioPullUp, GpioSpeedVeryHigh);
                 instance->bus->gpio->pin, GpioModeOutputOpenDrain, GpioPullUp, GpioSpeedVeryHigh);
         }
         }
         if(!unitemp_onewire_bus_start(instance->bus)) return UT_TIMEOUT;
         if(!unitemp_onewire_bus_start(instance->bus)) return UT_TIMEOUT;
-        unitemp_onewire_sensor_select(instance);
-        unitemp_onewire_send_byte(instance->bus, 0xBE); // Read Scratch-pad
+        unitemp_onewire_bus_select_sensor(instance);
+        unitemp_onewire_bus_send_byte(instance->bus, 0xBE); // Read Scratch-pad
         uint8_t buff[9];
         uint8_t buff[9];
         unitemp_onewire_read_byteArray(instance->bus, buff, 9);
         unitemp_onewire_read_byteArray(instance->bus, buff, 9);
         if(!unitemp_onewire_CRC_check(buff, 9)) {
         if(!unitemp_onewire_CRC_check(buff, 9)) {
@@ -385,4 +393,12 @@ UnitempStatus unitemp_onewire_sensor_update(Sensor* sensor) {
     }
     }
 
 
     return UT_OK;
     return UT_OK;
+}
+
+bool unitemp_onewire_id_compare(uint8_t* id1, uint8_t* id2) {
+    if(id1 == NULL || id2 == NULL) return false;
+    for(uint8_t i = 0; i < 8; i++) {
+        if(id1[i] != id2[i]) return false;
+    }
+    return true;
 }
 }

+ 12 - 3
interfaces/OneWireSensor.h

@@ -114,7 +114,7 @@ void unitemp_onewire_send_bit(OneWireBus* bus, bool state);
  * @param bus Указатель на шину one wire
  * @param bus Указатель на шину one wire
  * @param data Записываемый байт
  * @param data Записываемый байт
  */
  */
-void unitemp_onewire_send_byte(OneWireBus* bus, uint8_t data);
+void unitemp_onewire_bus_send_byte(OneWireBus* bus, uint8_t data);
 
 
 /**
 /**
  * @brief Запись массива байт на шину one wire
  * @brief Запись массива байт на шину one wire
@@ -123,7 +123,7 @@ void unitemp_onewire_send_byte(OneWireBus* bus, uint8_t data);
  * @param data Указатель на массив, откуда будут записаны данные
  * @param data Указатель на массив, откуда будут записаны данные
  * @param len Количество байт
  * @param len Количество байт
  */
  */
-void unitemp_onewire_send_byteArray(OneWireBus* bus, uint8_t* data, uint8_t len);
+void unitemp_onewire_bus_send_byteArray(OneWireBus* bus, uint8_t* data, uint8_t len);
 
 
 /**
 /**
  * @brief Чтение бита на шине one wire
  * @brief Чтение бита на шине one wire
@@ -171,7 +171,7 @@ bool unitemp_oneWire_sensor_readID(OneWireSensor* instance);
  * @brief Команда выбора определённого датчка по его ID
  * @brief Команда выбора определённого датчка по его ID
  * @param instance Указатель на датчик one wire
  * @param instance Указатель на датчик one wire
  */
  */
-void unitemp_onewire_sensor_select(OneWireSensor* instance);
+void unitemp_onewire_bus_select_sensor(OneWireSensor* instance);
 
 
 /**
 /**
  * @brief Инициализация процесса поиска адресов на шине one wire
  * @brief Инициализация процесса поиска адресов на шине one wire
@@ -185,5 +185,14 @@ void unitemp_onewire_enum_init(void);
  */
  */
 uint8_t* unitemp_onewire_enum_next(OneWireBus* bus);
 uint8_t* unitemp_onewire_enum_next(OneWireBus* bus);
 
 
+/**
+ * @brief Сравнить ID датчиков
+ * 
+ * @param id1 Указатель на адрес первого датчика
+ * @param id2 Указатель на адрес второго датчика
+ * @return Истина если ID индентичны
+ */
+bool unitemp_onewire_id_compare(uint8_t* id1, uint8_t* id2);
+
 extern const SensorType DS18x2x;
 extern const SensorType DS18x2x;
 #endif
 #endif

+ 2 - 1
unitemp.c

@@ -11,7 +11,8 @@
 //TODO: Проверка корректности параметров датчика перед аллокацией
 //TODO: Проверка корректности параметров датчика перед аллокацией
 //TODO: Не выкидывать датчик в ошибку при первом же неудачном опросе
 //TODO: Не выкидывать датчик в ошибку при первом же неудачном опросе
 //TODO: Запускать преобразование DS18x2x разом, затем поочерёдно считывать
 //TODO: Запускать преобразование DS18x2x разом, затем поочерёдно считывать
-//TODO: Запрет сохранения DS18x2x с пустым адресом
+//TODO: При выходе из меню добавления DS18x2x полностью отваливается шина, исправить
+//TODO: Мигание DS18x2x при его отсутствии на шине
 
 
 /* Переменные */
 /* Переменные */
 //Данные приложения
 //Данные приложения

+ 32 - 7
views/SensorEdit_view.c

@@ -21,17 +21,37 @@ static VariableItem* onewire_type_item;
 
 
 #define VIEW_ID SENSOREDIT_VIEW
 #define VIEW_ID SENSOREDIT_VIEW
 
 
-void scan(void) {
-    OneWireSensor* ow_sensor = editable_sensor->instance;
+bool _onewire_id_exist(uint8_t* id) {
+    if(id == NULL) return false;
+    for(uint8_t i = 0; i < app->sensors_count; i++) {
+        if(app->sensors[i]->type == &DS18x2x) {
+            if(unitemp_onewire_id_compare(
+                   id, ((OneWireSensor*)(app->sensors[i]->instance))->deviceID)) {
+                return true;
+            }
+        }
+    }
+    return false;
+}
 
 
+static void _onewire_scan(void) {
+    OneWireSensor* ow_sensor = editable_sensor->instance;
+    FURI_LOG_D(
+        APP_NAME,
+        "devices on wire %d: %d",
+        ow_sensor->bus->gpio->num,
+        ow_sensor->bus->device_count);
     //Сканирование шины one wire
     //Сканирование шины one wire
     unitemp_onewire_bus_init(ow_sensor->bus);
     unitemp_onewire_bus_init(ow_sensor->bus);
-    uint8_t* id = unitemp_onewire_enum_next(ow_sensor->bus);
+    unitemp_onewire_enum_init();
+    uint8_t* id;
+    do {
+        id = unitemp_onewire_enum_next(ow_sensor->bus);
+    } while(_onewire_id_exist(id));
 
 
     if(id == NULL) {
     if(id == NULL) {
-        unitemp_onewire_enum_init();
         id = unitemp_onewire_enum_next(ow_sensor->bus);
         id = unitemp_onewire_enum_next(ow_sensor->bus);
-        if(id == NULL) {
+        if(id == NULL || _onewire_id_exist(id)) {
             memset(ow_sensor->deviceID, 0, 8);
             memset(ow_sensor->deviceID, 0, 8);
             ow_sensor->familyCode = 0;
             ow_sensor->familyCode = 0;
             unitemp_onewire_bus_deinit(ow_sensor->bus);
             unitemp_onewire_bus_deinit(ow_sensor->bus);
@@ -115,6 +135,11 @@ static void _enter_callback(void* context, uint32_t index) {
     //Сохранение
     //Сохранение
     if((index == 3 && editable_sensor->type->interface != &ONE_WIRE) ||
     if((index == 3 && editable_sensor->type->interface != &ONE_WIRE) ||
        (index == 4 && editable_sensor->type->interface == &ONE_WIRE)) {
        (index == 4 && editable_sensor->type->interface == &ONE_WIRE)) {
+        //Выход если датчик one wire не имеет ID
+        if(editable_sensor->type->interface == &ONE_WIRE &&
+           ((OneWireSensor*)(editable_sensor->instance))->familyCode == 0) {
+            return;
+        }
         app->sensors[app->sensors_count++] = editable_sensor;
         app->sensors[app->sensors_count++] = editable_sensor;
         unitemp_sensors_save();
         unitemp_sensors_save();
         unitemp_sensors_reload();
         unitemp_sensors_reload();
@@ -123,7 +148,7 @@ static void _enter_callback(void* context, uint32_t index) {
     }
     }
     //Адрес устройства на шине one wire
     //Адрес устройства на шине one wire
     if(index == 3 && editable_sensor->type->interface == &ONE_WIRE) {
     if(index == 3 && editable_sensor->type->interface == &ONE_WIRE) {
-        scan();
+        _onewire_scan();
     }
     }
 }
 }
 
 
@@ -174,7 +199,7 @@ static void _name_change_callback(VariableItem* item) {
  */
  */
 static void _onwire_addr_change_callback(VariableItem* item) {
 static void _onwire_addr_change_callback(VariableItem* item) {
     variable_item_set_current_value_index(item, 0);
     variable_item_set_current_value_index(item, 0);
-    scan();
+    _onewire_scan();
 }
 }
 
 
 /**
 /**