|
|
@@ -1,4 +1,4 @@
|
|
|
-//Использован код Погребняка Дмитрия: https://aterlux.ru/article/1wire
|
|
|
+//Использован код Дмитрия Погребняка: https://aterlux.ru/article/1wire
|
|
|
|
|
|
#include "OneWireSensor.h"
|
|
|
#include <furi.h>
|
|
|
@@ -9,11 +9,15 @@ const SensorType DS18x2x = {
|
|
|
.typename = "DS18x2x",
|
|
|
.interface = &ONE_WIRE,
|
|
|
.pollingInterval = 250,
|
|
|
- .allocator = unitemp_OneWire_sensor_alloc,
|
|
|
- .mem_releaser = unitemp_OneWire_sensor_free,
|
|
|
- .initializer = unitemp_OneWire_sensor_init,
|
|
|
- .deinitializer = unitemp_OneWire_sensor_deinit,
|
|
|
- .updater = unitemp_OneWire_sensor_update};
|
|
|
+ .allocator = unitemp_onewire_sensor_alloc,
|
|
|
+ .mem_releaser = unitemp_onewire_sensor_free,
|
|
|
+ .initializer = unitemp_onewire_sensor_init,
|
|
|
+ .deinitializer = unitemp_onewire_sensor_deinit,
|
|
|
+ .updater = unitemp_onewire_sensor_update};
|
|
|
+
|
|
|
+// Переменные для хранения промежуточного результата поиска
|
|
|
+uint8_t onewire_enum[8]; // найденный восьмибайтовый адрес
|
|
|
+uint8_t onewire_enum_fork_bit; // последний нулевой бит, где была неоднозначность (нумеруя с единицы)
|
|
|
|
|
|
OneWireBus* uintemp_onewire_bus_alloc(const GPIO* gpio) {
|
|
|
if(gpio == NULL) {
|
|
|
@@ -34,7 +38,7 @@ OneWireBus* uintemp_onewire_bus_alloc(const GPIO* gpio) {
|
|
|
bus->gpio = gpio;
|
|
|
bus->powerMode = PWR_ACTIVE;
|
|
|
|
|
|
- FURI_LOG_D(APP_NAME, "One wire bus (port %d) allocated", unitemp_GPIO_toInt(gpio->pin));
|
|
|
+ FURI_LOG_D(APP_NAME, "one wire bus (port %d) allocated", unitemp_gpio_toInt(gpio));
|
|
|
|
|
|
return bus;
|
|
|
}
|
|
|
@@ -93,7 +97,7 @@ bool unitemp_onewire_bus_start(OneWireBus* bus) {
|
|
|
return status;
|
|
|
}
|
|
|
|
|
|
-static void oneWire_send_bit(OneWireBus* bus, bool state) {
|
|
|
+void unitemp_onewire_send_bit(OneWireBus* bus, bool state) {
|
|
|
if(state) {
|
|
|
// write 1
|
|
|
furi_hal_gpio_write(bus->gpio->pin, false);
|
|
|
@@ -108,30 +112,24 @@ static void oneWire_send_bit(OneWireBus* bus, bool state) {
|
|
|
uint32_t t = furi_get_tick();
|
|
|
while(!furi_hal_gpio_read(bus->gpio->pin)) {
|
|
|
//Выход если шина не поднялась
|
|
|
- if(furi_get_tick() - t > 100) return;
|
|
|
+ if(furi_get_tick() - t > 10) return;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * @brief Запись байта на шину One Wire
|
|
|
- *
|
|
|
- * @param instance Указатель на инстанс датчика
|
|
|
- * @param data Записываемый байт
|
|
|
- */
|
|
|
-static void oneWire_write(OneWireBus* bus, uint8_t data) {
|
|
|
+void unitemp_onewire_send_byte(OneWireBus* bus, uint8_t data) {
|
|
|
for(int i = 0; i < 8; i++) {
|
|
|
- oneWire_send_bit(bus, (data & (1 << i)) != 0);
|
|
|
+ unitemp_onewire_send_bit(bus, (data & (1 << i)) != 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * @brief Чтение бита на шине One Wire
|
|
|
- *
|
|
|
- * @param bus Указатель на шину one wire
|
|
|
- * @return Логический уровень бита
|
|
|
- */
|
|
|
-static bool oneWire_read_bit(OneWireBus* bus) {
|
|
|
+void unitemp_onewire_send_byteArray(OneWireBus* bus, uint8_t* data, uint8_t len) {
|
|
|
+ for(uint8_t i = 0; i < len; i++) {
|
|
|
+ unitemp_onewire_send_byte(bus, data[i]);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+bool unitemp_onewire_read_bit(OneWireBus* bus) {
|
|
|
furi_hal_gpio_write(bus->gpio->pin, false);
|
|
|
furi_delay_us(2); // Длительность низкого уровня, минимум 1 мкс
|
|
|
furi_hal_gpio_write(bus->gpio->pin, true);
|
|
|
@@ -141,34 +139,22 @@ static bool oneWire_read_bit(OneWireBus* bus) {
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * @brief Чтение байта с шины One Wire
|
|
|
- *
|
|
|
- * @param bus Указатель на шину one wire
|
|
|
- * @return Байт информации
|
|
|
- */
|
|
|
-static uint8_t oneWire_read(OneWireBus* bus) {
|
|
|
+uint8_t unitemp_onewire_read_byte(OneWireBus* bus) {
|
|
|
uint8_t r = 0;
|
|
|
for(uint8_t p = 8; p; p--) {
|
|
|
r >>= 1;
|
|
|
- if(oneWire_read_bit(bus)) r |= 0x80;
|
|
|
+ if(unitemp_onewire_read_bit(bus)) r |= 0x80;
|
|
|
}
|
|
|
return r;
|
|
|
}
|
|
|
-/**
|
|
|
- * @brief Чтение массива байт с шины One Wire
|
|
|
- *
|
|
|
- * @param instance Указатель на инстанс датчика
|
|
|
- * @param data Указатель на массив, куда будут записаны данные
|
|
|
- * @param len Количество байт
|
|
|
- */
|
|
|
-static void oneWire_readBytes(OneWireBus* bus, uint8_t* data, uint8_t len) {
|
|
|
+
|
|
|
+void unitemp_onewire_read_byteArray(OneWireBus* bus, uint8_t* data, uint8_t len) {
|
|
|
for(uint8_t i = 0; i < len; i++) {
|
|
|
- data[i] = oneWire_read(bus);
|
|
|
+ data[i] = unitemp_onewire_read_byte(bus);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static uint8_t onewire_CRC_update(uint8_t crc, uint8_t b) {
|
|
|
+uint8_t onewire_CRC_update(uint8_t crc, uint8_t b) {
|
|
|
for(uint8_t p = 8; p; p--) {
|
|
|
crc = ((crc ^ b) & 1) ? (crc >> 1) ^ 0b10001100 : (crc >> 1);
|
|
|
b >>= 1;
|
|
|
@@ -176,7 +162,7 @@ static uint8_t onewire_CRC_update(uint8_t crc, uint8_t b) {
|
|
|
return crc;
|
|
|
}
|
|
|
|
|
|
-static bool onewire_CRC_check(uint8_t* data, uint8_t len) {
|
|
|
+bool unitemp_onewire_CRC_check(uint8_t* data, uint8_t len) {
|
|
|
uint8_t crc = 0;
|
|
|
for(uint8_t i = 0; i < len; i++) {
|
|
|
crc = onewire_CRC_update(crc, data[i]);
|
|
|
@@ -184,30 +170,11 @@ static bool onewire_CRC_check(uint8_t* data, uint8_t len) {
|
|
|
return !crc;
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * @brief Запись массива байт на шину One Wire
|
|
|
- *
|
|
|
- * @param instance Указатель на инстанс датчика
|
|
|
- * @param data Указатель на массив, откуда будут записаны данные
|
|
|
- * @param len Количество байт
|
|
|
- */
|
|
|
-static void oneWire_writeBytes(OneWireBus* bus, uint8_t* data, uint8_t len) {
|
|
|
- for(uint8_t i = 0; i < len; i++) {
|
|
|
- oneWire_write(bus, data[i]);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * @brief Чтение индификатора единственного датчика. ID запишется в инстанс датчика
|
|
|
- *
|
|
|
- * @param instance Указатель на инстанс датчика
|
|
|
- * @return Истина, если код успешно прочитан, ложь если устройство отсутствует или устройств на шине больше одного
|
|
|
- */
|
|
|
-bool oneWire_sensor_readID(OneWireSensor* instance) {
|
|
|
+bool unitemp_onewire_sensor_readID(OneWireSensor* instance) {
|
|
|
if(!unitemp_onewire_bus_start(instance->bus)) return false;
|
|
|
- oneWire_write(instance->bus, 0x33); // Чтение ПЗУ
|
|
|
- oneWire_readBytes(instance->bus, instance->deviceID, 8);
|
|
|
- if(!onewire_CRC_check(instance->deviceID, 8)) {
|
|
|
+ unitemp_onewire_send_byte(instance->bus, 0x33); // Чтение ПЗУ
|
|
|
+ unitemp_onewire_read_byteArray(instance->bus, instance->deviceID, 8);
|
|
|
+ if(!unitemp_onewire_CRC_check(instance->deviceID, 8)) {
|
|
|
memset(instance->deviceID, 0, 8);
|
|
|
return false;
|
|
|
}
|
|
|
@@ -215,11 +182,6 @@ bool oneWire_sensor_readID(OneWireSensor* instance) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-// Переменные для хранения промежуточного результата поиска
|
|
|
-uint8_t onewire_enum[8]; // найденный восьмибайтовый адрес
|
|
|
-uint8_t onewire_enum_fork_bit; // последний нулевой бит, где была неоднозначность (нумеруя с единицы)
|
|
|
-
|
|
|
-// Инициализирует процедуру поиска адресов устройств
|
|
|
void unitemp_onewire_enum_init(void) {
|
|
|
for(uint8_t p = 0; p < 8; p++) {
|
|
|
onewire_enum[p] = 0;
|
|
|
@@ -230,12 +192,11 @@ void unitemp_onewire_enum_init(void) {
|
|
|
uint8_t* unitemp_onewire_enum_next(OneWireBus* bus) {
|
|
|
furi_delay_ms(10);
|
|
|
if(!onewire_enum_fork_bit) { // Если на предыдущем шаге уже не было разногласий
|
|
|
- FURI_LOG_D(
|
|
|
- APP_NAME, "All devices on wire %d is found", unitemp_GPIO_toInt(bus->gpio->pin));
|
|
|
+ FURI_LOG_D(APP_NAME, "All devices on wire %d is found", unitemp_gpio_toInt(bus->gpio));
|
|
|
return 0; // то просто выходим ничего не возвращая
|
|
|
}
|
|
|
if(!unitemp_onewire_bus_start(bus)) {
|
|
|
- FURI_LOG_D(APP_NAME, "Wire %d is empty", unitemp_GPIO_toInt(bus->gpio->pin));
|
|
|
+ FURI_LOG_D(APP_NAME, "Wire %d is empty", unitemp_gpio_toInt(bus->gpio));
|
|
|
return 0;
|
|
|
}
|
|
|
uint8_t bp = 8;
|
|
|
@@ -244,11 +205,11 @@ uint8_t* unitemp_onewire_enum_next(OneWireBus* bus) {
|
|
|
uint8_t next = 0;
|
|
|
|
|
|
uint8_t p = 1;
|
|
|
- oneWire_write(bus, 0xF0);
|
|
|
+ unitemp_onewire_send_byte(bus, 0xF0);
|
|
|
uint8_t newfork = 0;
|
|
|
for(;;) {
|
|
|
- uint8_t not0 = oneWire_read_bit(bus);
|
|
|
- uint8_t not1 = oneWire_read_bit(bus);
|
|
|
+ uint8_t not0 = unitemp_onewire_read_bit(bus);
|
|
|
+ uint8_t not1 = unitemp_onewire_read_bit(bus);
|
|
|
if(!not0) { // Если присутствует в адресах бит ноль
|
|
|
if(!not1) { // Но также присустствует бит 1 (вилка)
|
|
|
if(p <
|
|
|
@@ -269,12 +230,11 @@ uint8_t* unitemp_onewire_enum_next(OneWireBus* bus) {
|
|
|
if(!not1) { // Присутствует единица
|
|
|
next |= 0x80;
|
|
|
} else { // Нет ни нулей ни единиц - ошибочная ситуация
|
|
|
- FURI_LOG_D(
|
|
|
- APP_NAME, "Wrong wire %d situation", unitemp_GPIO_toInt(bus->gpio->pin));
|
|
|
+ FURI_LOG_D(APP_NAME, "Wrong wire %d situation", unitemp_gpio_toInt(bus->gpio));
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
- oneWire_send_bit(bus, next & 0x80);
|
|
|
+ unitemp_onewire_send_bit(bus, next & 0x80);
|
|
|
bp--;
|
|
|
if(!bp) {
|
|
|
*pprev = next;
|
|
|
@@ -294,12 +254,12 @@ uint8_t* unitemp_onewire_enum_next(OneWireBus* bus) {
|
|
|
return &onewire_enum[0];
|
|
|
}
|
|
|
|
|
|
-void unitemp_OneWire_sensor_select(OneWireSensor* instance) {
|
|
|
- oneWire_write(instance->bus, 0x55);
|
|
|
- oneWire_writeBytes(instance->bus, instance->deviceID, 8);
|
|
|
+void unitemp_onewire_sensor_select(OneWireSensor* instance) {
|
|
|
+ unitemp_onewire_send_byte(instance->bus, 0x55);
|
|
|
+ unitemp_onewire_send_byteArray(instance->bus, instance->deviceID, 8);
|
|
|
}
|
|
|
|
|
|
-bool unitemp_OneWire_sensor_alloc(Sensor* sensor, uint8_t* anotherValues) {
|
|
|
+bool unitemp_onewire_sensor_alloc(Sensor* sensor, char* args) {
|
|
|
OneWireSensor* instance = malloc(sizeof(OneWireSensor));
|
|
|
if(instance == NULL) {
|
|
|
FURI_LOG_E(APP_NAME, "Sensor %s instance allocation error", sensor->name);
|
|
|
@@ -309,7 +269,7 @@ bool unitemp_OneWire_sensor_alloc(Sensor* sensor, uint8_t* anotherValues) {
|
|
|
//Очистка адреса
|
|
|
memset(instance->deviceID, 0, 8);
|
|
|
|
|
|
- instance->bus = uintemp_onewire_bus_alloc(unitemp_GPIO_getFromInt(anotherValues[0]));
|
|
|
+ instance->bus = uintemp_onewire_bus_alloc(unitemp_gpio_getFromInt(args[0]));
|
|
|
if(instance != NULL) {
|
|
|
return true;
|
|
|
}
|
|
|
@@ -318,7 +278,7 @@ bool unitemp_OneWire_sensor_alloc(Sensor* sensor, uint8_t* anotherValues) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-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);
|
|
|
@@ -328,7 +288,7 @@ bool unitemp_OneWire_sensor_free(Sensor* sensor) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool unitemp_OneWire_sensor_init(Sensor* sensor) {
|
|
|
+bool unitemp_onewire_sensor_init(Sensor* sensor) {
|
|
|
OneWireSensor* instance = sensor->instance;
|
|
|
if(instance == NULL || instance->bus->gpio == NULL) {
|
|
|
FURI_LOG_E(APP_NAME, "Sensor pointer is null!");
|
|
|
@@ -340,24 +300,24 @@ bool unitemp_OneWire_sensor_init(Sensor* sensor) {
|
|
|
if(instance->familyCode == FC_DS18B20 || instance->familyCode == FC_DS1822) {
|
|
|
//Установка разрядности в 10 бит
|
|
|
if(!unitemp_onewire_bus_start(instance->bus)) return false;
|
|
|
- unitemp_OneWire_sensor_select(instance);
|
|
|
- oneWire_write(instance->bus, 0x4E); // Запись в память
|
|
|
+ unitemp_onewire_sensor_select(instance);
|
|
|
+ unitemp_onewire_send_byte(instance->bus, 0x4E); // Запись в память
|
|
|
uint8_t buff[3];
|
|
|
buff[0] = 0x4B; //Значение нижнего предела
|
|
|
buff[1] = 0x46; //Значение высшего предела
|
|
|
buff[2] = 0x3F; //10 бит разрядность преобразования
|
|
|
- oneWire_writeBytes(instance->bus, buff, 3);
|
|
|
+ unitemp_onewire_send_byteArray(instance->bus, buff, 3);
|
|
|
|
|
|
//Сохранение значений в EEPROM для автоматического восстановления после сбоев питания
|
|
|
if(!unitemp_onewire_bus_start(instance->bus)) return false;
|
|
|
- unitemp_OneWire_sensor_select(instance);
|
|
|
- oneWire_write(instance->bus, 0x48); // Запись в EEPROM
|
|
|
+ unitemp_onewire_sensor_select(instance);
|
|
|
+ unitemp_onewire_send_byte(instance->bus, 0x48); // Запись в EEPROM
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-bool unitemp_OneWire_sensor_deinit(Sensor* sensor) {
|
|
|
+bool unitemp_onewire_sensor_deinit(Sensor* sensor) {
|
|
|
OneWireSensor* instance = sensor->instance;
|
|
|
if(instance == NULL || instance->bus->gpio == NULL) return false;
|
|
|
unitemp_onewire_bus_deinit(instance->bus);
|
|
|
@@ -365,12 +325,12 @@ bool unitemp_OneWire_sensor_deinit(Sensor* sensor) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-UnitempStatus unitemp_OneWire_sensor_update(Sensor* sensor) {
|
|
|
+UnitempStatus unitemp_onewire_sensor_update(Sensor* sensor) {
|
|
|
OneWireSensor* instance = sensor->instance;
|
|
|
if(sensor->status != UT_POLLING) {
|
|
|
if(!unitemp_onewire_bus_start(instance->bus)) return UT_TIMEOUT;
|
|
|
- unitemp_OneWire_sensor_select(instance);
|
|
|
- oneWire_write(instance->bus, 0x44); // convert t
|
|
|
+ unitemp_onewire_sensor_select(instance);
|
|
|
+ unitemp_onewire_send_byte(instance->bus, 0x44); // convert t
|
|
|
if(instance->bus->powerMode == PWR_PASSIVE) {
|
|
|
furi_hal_gpio_write(instance->bus->gpio->pin, true);
|
|
|
furi_hal_gpio_init(
|
|
|
@@ -384,11 +344,11 @@ UnitempStatus unitemp_OneWire_sensor_update(Sensor* sensor) {
|
|
|
instance->bus->gpio->pin, GpioModeOutputOpenDrain, GpioPullUp, GpioSpeedVeryHigh);
|
|
|
}
|
|
|
if(!unitemp_onewire_bus_start(instance->bus)) return UT_TIMEOUT;
|
|
|
- unitemp_OneWire_sensor_select(instance);
|
|
|
- oneWire_write(instance->bus, 0xBE); // Read Scratch-pad
|
|
|
+ unitemp_onewire_sensor_select(instance);
|
|
|
+ unitemp_onewire_send_byte(instance->bus, 0xBE); // Read Scratch-pad
|
|
|
uint8_t buff[9];
|
|
|
- oneWire_readBytes(instance->bus, buff, 9);
|
|
|
- if(!onewire_CRC_check(buff, 9)) {
|
|
|
+ unitemp_onewire_read_byteArray(instance->bus, buff, 9);
|
|
|
+ if(!unitemp_onewire_CRC_check(buff, 9)) {
|
|
|
FURI_LOG_D(APP_NAME, "Failed CRC check: %s", sensor->name);
|
|
|
return UT_TIMEOUT;
|
|
|
}
|