Parcourir la source

[ds18b20]add in project

balbekova il y a 5 ans
Parent
commit
00e4171034

+ 32 - 5
config/board_bt6710.h

@@ -34,8 +34,8 @@ X( DOUT1,      GPIOC,  2, GPIO_OUT)\
 X( DOUT2,      GPIOC,  3, GPIO_OUT)
 
 #define ONEWIRE_DATA_TABLE(X) \
-X( WDATA1,      GPIOA,  0, GPIO_OUT)\
-X( WDATA2,      GPIOC,  12, GPIO_OUT)
+X( WDATA1,      GPIOA,  0,  AF_UART4)\
+X( WDATA2,      GPIOC,  12, AF_UART5)
 
 #define LEDS(X) \
 X( LED_INIT_R,  GPIOA,  4,  GPIO_OUT | GPIO_INV) \
@@ -82,9 +82,9 @@ WDG_PIN(X)
 #define SNMP_ENABLE                 //SNMP протокол
 #define UPS_ENABLE                  //UPS
 #define PORTGW_ENABLE               //Прозрачный порт
+#define DALLAS_SENSOR_ENABLE        //DS18B20
 //#define DEBUG_FREERTOS            //Мониторинг FreeRtos
 
-
 #define SETTINGS_TABLE \
 XSETTING( SNMP_t,	sSnmp, SETTINGS_SetSnmpDef, ALL_DEFAULT ) \
 XSETTING( AUTH_t,	sAuth[MAX_WEB_USERS], SETTINGS_SetServiceDef, PART_DEFAULT_2 ) \
@@ -107,12 +107,21 @@ XSETTING( PORTGW_t, sPortGw, SETTINGS_SetPortGwDef, ALL_DEFAULT ) \
   XJSON_SETTINGS_TAG("managerIP4",         GetManagerIp4,                             SetManagerIp4) \
   XJSON_SETTINGS_TAG("managerIP5",         GetManagerIp5,                             SetManagerIp5) \
   XJSON_SETTINGS_TAG("di1",                GetDINTypeActStr,                          SetDINTypeActStr) \
-  XJSON_SETTINGS_TAG("ro1",                GetROTypeActStr,                           SetROTypeActStr) \
-  XJSON_SETTINGS_TAG("ro2",                GetROTypeActStr,                           SetROTypeActStr) \
+  XJSON_SETTINGS_TAG("di_name1",           GetROTypeActStr,                           SetROTypeActStr) \
+  XJSON_SETTINGS_TAG("di2",                GetDINTypeActStr,                           SetROTypeActStr) \
+  XJSON_SETTINGS_TAG("di_name2",           GetROTypeActStr,                           SetROTypeActStr) \
+  XJSON_SETTINGS_TAG("type_ts1",           GetROTypeActStr,                           SetROTypeActStr) \
+  XJSON_SETTINGS_TAG("type_ts2",           GetROTypeActStr,                           SetROTypeActStr) \
   XJSON_SETTINGS_TAG("ipaddr",             GetIpStr,                                  SetIPStr) \
   XJSON_SETTINGS_TAG("gw",                 GetGatewayStr,                             SetGatewayStr) \
   XJSON_SETTINGS_TAG("mask",               GetMaskStr,                                SetMaskStr) \
   XJSON_SETTINGS_TAG("dhcp",               GetDhcpStateStr,                           SetDhcpStateStr) \
+  XJSON_SETTINGS_TAG("pgw_en",             GetPortGwEnabledStr,                       SetPortGwEnabledStr) \
+  XJSON_SETTINGS_TAG("pgw_port",           GetPortGwPortnumStr,                       SetPortGwPortnumStr) \
+  XJSON_SETTINGS_TAG("pgw_baud",           GetPortGwBaudStr,                          SetPortGwBaudStr) \
+  XJSON_SETTINGS_TAG("pgw_par",            GetPortGwParityStr,                        SetPortGwParityStr) \
+  XJSON_SETTINGS_TAG("pgw_ndata",          GetPortGwDatabitsStr,                      SetPortGwDatabitsStr) \
+  XJSON_SETTINGS_TAG("pgw_nstop",          GetPortGwStopbitsStr,                      SetPortGwStopbitsStr) \
   XJSON_SETTINGS_TAG("date",               GetDateStr,                                SetDateStr) \
   XJSON_SETTINGS_TAG("time",               GetTimeStr,                                SetTimeWebStr) \
   XJSON_SETTINGS_TAG("ntp",                GetSntpStateStr,                           SetSntpStateStr) \
@@ -128,6 +137,9 @@ XSETTING( PORTGW_t, sPortGw, SETTINGS_SetPortGwDef, ALL_DEFAULT ) \
   XJSON_SETTINGS_TAG("temp_high",          GetTemperatureAlarmHighRangeStr,           SetTemperatureAlarmHighRangeStr) \
   XJSON_SETTINGS_TAG("temp_low",           GetTemperatureAlarmLowRangeStr,            SetTemperatureAlarmLowRangeStr) \
   XJSON_SETTINGS_TAG("temp_hist",          GetTemperatureAlarmHisteStr,               SetTemperatureAlarmHisteStr) \
+  XJSON_SETTINGS_TAG("case_temp_high",     GetTemperatureAlarmHighRangeStr,           SetTemperatureAlarmHighRangeStr) \
+  XJSON_SETTINGS_TAG("case_temp_low",      GetTemperatureAlarmLowRangeStr,            SetTemperatureAlarmLowRangeStr) \
+  XJSON_SETTINGS_TAG("case_temp_hist",     GetTemperatureAlarmHisteStr,               SetTemperatureAlarmHisteStr) \
   XJSON_SETTINGS_TAG("netsettings_changed",GetWebReinitFlag,                          SetEmptyFuncStr) \
 
 #define WEB_PARAMS_TAGS_TABLE \
@@ -139,7 +151,11 @@ XSETTING( PORTGW_t, sPortGw, SETTINGS_SetPortGwDef, ALL_DEFAULT ) \
   XJSON_PARAMS_TAG("bat_rem_cap",        GetBatCapacityStr) \
   XJSON_PARAMS_TAG("inner_temp",         GetInternalTempStr) \
   XJSON_PARAMS_TAG("bat_time_left",      GetRuntimeStr) \
+  XJSON_PARAMS_TAG("case_temp",          GetInternalTempStr) \
   XJSON_PARAMS_TAG("di1",                GetDINStatusStr) \
+  XJSON_PARAMS_TAG("di_name1",           GetDINStatusStr) \
+  XJSON_PARAMS_TAG("di2",                GetDINStatusStr) \
+  XJSON_PARAMS_TAG("di_name2",           GetDINStatusStr) \
   XJSON_PARAMS_TAG("m_alarm",            GetAlarmMonitorStr) \
   XJSON_PARAMS_TAG("u_alarm",            GetAlarmStr) \
   XJSON_PARAMS_TAG("netsettings_changed",GetWebReinitFlag) \
@@ -217,4 +233,15 @@ typedef enum {
 	LOG_NONE,
 } log_type_t;
 
+typedef enum
+{
+  T_SENSOR_1 = 0,
+  T_SENSOR_2,
+  MAX_T_SENSORS
+} t_sensor_list_t;
+
+#define T_SENSOR_TABLE \
+  XTSENSOR(T_SENSOR_1,      WDATA1,     DALLAS_SENSOR_1_USART) \
+  XTSENSOR(T_SENSOR_2,      WDATA2,     DALLAS_SENSOR_2_USART) \
+
 #endif /* BOARD_PRS_H */

+ 15 - 0
modules/Makefile

@@ -49,6 +49,7 @@ INCLUDES += -Ilog
 INCLUDES += -Itesting
 ifeq ($(HARDWARE), bt6710)
 INCLUDES += -Iportgw
+INCLUDES += -Ids18b20
 endif
 ifeq ($(HARDWARE), bt6709)
 INCLUDES += -Iwhitelist
@@ -68,6 +69,7 @@ CSRC += $(wildcard log/*.c)
 CSRC += $(wildcard testing/*.c)
 ifeq ($(HARDWARE), bt6710)
 CSRC += $(wildcard portgw/*.c)
+CSRC += $(wildcard ds18b20/*.c)
 endif
 ifeq ($(HARDWARE), bt6709)     
 CSRC += $(wildcard whitelist/*.c)
@@ -193,6 +195,10 @@ ifeq ($(HARDWARE), bt6709)
 BUILDDIR = ../build/bt6709/$(TARGET)
 endif
 
+ifeq ($(HARDWARE), bt6710)
+BUILDDIR = ../build/bt6710/$(TARGET)
+endif
+
 FW_FLASH_START = $(shell awk '/USER_FLASH_FIRST_PAGE_ADDRESS/{print $$3}' ../config/common_config.h )
 FW_FLASH_CRC = $(shell awk '/USER_FLASH_CRC_ADDRESS/{print $$3}' ../config/common_config.h )
 
@@ -208,9 +214,18 @@ ifeq ($(HARDWARE), bt6709)
 FW_NAME = BT_6709xx
 endif
 
+ifeq ($(HARDWARE), bt6710)
+FW_NAME = BT_6710xx
+endif
+
 -include ../Makefile.inc.stm32
 
 #Building Web UI FS
+ifeq ($(HARDWARE), bt6710)
+	WUI_DIR = ../web_interface/dist/wui-10
+	FSDATA_DIR = ./HTTP_Server/bt6710_fs
+endif
+
 ifeq ($(HARDWARE), bt6707)
 	WUI_DIR = ../web_interface/dist/wui-7
 	FSDATA_DIR = ./HTTP_Server/bt6707_fs

+ 356 - 0
modules/ds18b20/onewire.c

@@ -0,0 +1,356 @@
+/********************************* (C) РОТЕК ***********************************
+ * @module  onewire
+ * @file    onewire.c
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   DS18B20 temperature sensor driver
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+#include "common_config.h"
+#include "stm32f2xx.h"
+#include "stm32f2xx_dma.h"
+#include "usart.h"
+#include "gpio.h"
+#include "onewire.h"
+
+/* Force remove debug output */
+#undef DBG
+#define DBG if(0)
+
+/**
+  * @brief  Размер буфера для отправки данных датчикам
+  */
+#define DALLAS_BUF_SIZE   8
+
+#define DALLAS_TIME_OUT   1500000
+
+#define DALLAS_0    0x00
+#define DALLAS_1    0xff
+#define DALLAS_R_1  0xff
+
+typedef struct {
+  gpio_t ow_pin;
+  USART_TypeDef *uart_addr;
+  DMA_InitTypeDef DMA_InitStructureTx;
+  DMA_InitTypeDef DMA_InitStructureRx;
+  sensorBuf[DALLAS_BUF_SIZE];
+}ow_sensor_t;
+
+ow_sensor_t ow_sensor[MAX_T_SENSORS];
+
+#define T_SENSOR_ADD(sensor_num, ow_line, uart_addr) \
+  do { \
+    ow_sensor[sensor_num].ow_pin = ow_line; \
+    ow_sensor[sensor_num].uart_addr = uart_addr; \
+  } while (0);
+
+/**
+  * @brief  Настройка USART
+  * @retval
+  */
+void DALLAS_Init()
+{
+  for (uint8_t i = 0; i < MAX_T_SENSORS; i ++) {
+#define XTSENSOR(sensor_num, ow_line, uart_addrm) T_SENSOR_ADD(sensor_num, ow_line, uart_addr);
+      T_SENSOR_TABLE
+#undef XTSENSOR
+    uart_hw_init(ow_sensor[i].uart_addr, DALLAS_SENSOR_UART_BAUD, DALLAS_SENSOR_UART_WORD_LEN,
+        DALLAS_SENSOR_UART_PARITY, DALLAS_SENSOR_UART_STOP_BIT);
+  }
+  DALLAS_DmaInit();
+}
+
+/**
+  * @brief  Настройка DMA
+  * @retval
+  */
+void DALLAS_DmaInit(void)
+{
+  DMA_Stream_TypeDef *RxDMA_Stream = NULL;
+  DMA_Stream_TypeDef *TxDMA_Stream = NULL;
+  uint32_t RxDMA_Channel = 0;
+  uint32_t TxDMA_Channel = 0;
+
+  for (uint8_t i = 0; i < MAX_T_SENSORS; i ++) {
+    if (ow_sensor[i].uart_addr == USART1) {
+      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
+      RxDMA_Stream = DMA1_Stream2;
+      TxDMA_Stream = DMA1_Stream7;
+      RxDMA_Channel = DMA_Channel_4;
+      TxDMA_Channel = DMA_Channel_4;
+    } else if (ow_sensor[i].uart_addr == USART2) {
+      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
+      RxDMA_Stream = DMA1_Stream5;
+      TxDMA_Stream = DMA1_Stream6;
+      RxDMA_Channel = DMA_Channel_4;
+      TxDMA_Channel = DMA_Channel_4;
+    } else if (ow_sensor[i].uart_addr == USART3) {
+      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
+      RxDMA_Stream = DMA1_Stream1;
+      TxDMA_Stream = DMA1_Stream3;
+      RxDMA_Channel = DMA_Channel_4;
+      TxDMA_Channel = DMA_Channel_4;
+    } else if (ow_sensor[i].uart_addr == UART4) {
+      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
+      RxDMA_Stream = DMA1_Stream2;
+      TxDMA_Stream = DMA1_Stream4;
+      RxDMA_Channel = DMA_Channel_4;
+      TxDMA_Channel = DMA_Channel_4;
+    } else if (ow_sensor[i].uart_addr == UART5) {
+      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
+      RxDMA_Stream = DMA1_Stream0;
+      TxDMA_Stream = DMA1_Stream7;
+      RxDMA_Channel = DMA_Channel_4;
+      TxDMA_Channel = DMA_Channel_4;
+    } else if (ow_sensor[i].uart_addr == USART6) {
+      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);
+      RxDMA_Stream = DMA1_Stream1;
+      TxDMA_Stream = DMA1_Stream6;
+      RxDMA_Channel = DMA_Channel_5;
+      TxDMA_Channel = DMA_Channel_5;
+    }
+  
+      /* DMA на чтение */
+      DMA_DeInit(RxDMA_Stream);
+      ow_sensor[i].DMA_InitStructureRx.DMA_Channel = RxDMA_Stream;
+      ow_sensor[i].DMA_InitStructureRx.DMA_PeripheralBaseAddr = (uint32_t)&ow_sensor[i].uart_addr->DR;
+      ow_sensor[i].DMA_InitStructureRx.DMA_Memory0BaseAddr = (uint32_t)&ow_sensor[i].sensorBuf;
+      ow_sensor[i].DMA_InitStructureRx.DMA_DIR = DMA_DIR_PeripheralToMemory;
+      ow_sensor[i].DMA_InitStructureRx.DMA_BufferSize = DALLAS_BUF_SIZE;
+      ow_sensor[i].DMA_InitStructureRx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+      ow_sensor[i].DMA_InitStructureRx.DMA_MemoryInc = DMA_MemoryInc_Enable;
+      ow_sensor[i].DMA_InitStructureRx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+      ow_sensor[i].DMA_InitStructureRx.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+      ow_sensor[i].DMA_InitStructureRx.DMA_Mode = DMA_Mode_Normal;
+      ow_sensor[i].DMA_InitStructureRx.DMA_Priority = DMA_Priority_Medium;
+
+      DMA_Init(RxDMA_Stream, &ow_sensor[i].DMA_InitStructureRx);
+
+      /* DMA на запись */
+      DMA_DeInit(TxDMA_Stream);
+      ow_sensor[i].DMA_InitStructureTx.DMA_Channel = TxDMA_Stream;
+      ow_sensor[i].DMA_InitStructureTx.DMA_PeripheralBaseAddr = &ow_sensor[i].uart_addr->DR;
+      ow_sensor[i].DMA_InitStructureTx.DMA_Memory0BaseAddr = (uint32_t)&Dow_sensor[i].sensorBuf;
+      ow_sensor[i].DMA_InitStructureTx.DMA_DIR = DMA_DIR_MemoryToPeripheral;
+      ow_sensor[i].DMA_InitStructureTx.DMA_BufferSize = DALLAS_BUF_SIZE;
+      ow_sensor[i].DMA_InitStructureTx.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
+      ow_sensor[i].DMA_InitStructureTx.DMA_MemoryInc = DMA_MemoryInc_Enable;
+      ow_sensor[i].DMA_InitStructureTx.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
+      ow_sensor[i].DMA_InitStructureTx.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
+      ow_sensor[i].DMA_InitStructureTx.DMA_Mode = DMA_Mode_Normal;
+      ow_sensor[i].DMA_InitStructureTx.DMA_Priority = DMA_Priority_Medium;
+
+      DMA_Init(TxDMA_Stream, &ow_sensor[i].DMA_InitStructureTx.);
+  }
+}
+
+/**
+  * @brief  Настроить TX пин как питающий выход
+  * @retval
+  */
+void DALLAS_OutSetAsPower(t_sensor_list_t sensor)
+{
+    gpio_pindef_t *pin = &gpio_pins[ow_sensor[sensor].ow_pin];
+    gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_OUT_CFG | GPIO_TYPE_PP_CFG) |
+    GPIO_SPEED_HIGH_CFG));
+    gpio_set(id, GPIO_SET);
+}
+
+/**
+  * @brief  Настроить TX пин как передатчик
+  * @retval
+  */
+void DALLAS_OutSetAsTX(t_sensor_list_t sensor)
+{
+    gpio_pindef_t *pin = &gpio_pins[ow_sensor[sensor].ow_pin];
+    uint8_t af_n = (uint8_t)(pin->flags >> _GPIO_AF_SHIFT);
+    gpio_connect_af(id, af_n);
+    gpio_hw_config_pin(pin->port, pin->pin, GPIO_MODE_AF_CFG |
+        GPIO_SPEED_HIGH_CFG);
+}
+
+/**
+  * @brief  Сброс и проверка наличия устройства на шине 1-wire
+  * @retval
+  */
+uint8_t DALLAS_SensorReset(t_sensor_list_t sensor)
+{
+    uint8_t presence;
+
+    uart_hw_init(ow_sensor[sensor].uart_addr, DALLAS_SENSOR_RST_UART_BAUD,
+        DALLAS_SENSOR_UART_WORD_LEN, DALLAS_SENSOR_UART_PARITY, DALLAS_SENSOR_UART_STOP_BIT);
+
+    // отправляем 0xf0 на скорости 9600
+    USART_ClearFlag(ow_sensor[sensor].uart_addr, USART_FLAG_TC);
+    USART_SendData(ow_sensor[sensor].uart_addr, 0xf0);
+
+    while (USART_GetFlagStatus(ow_sensor[sensor].uart_addr, USART_FLAG_TC) == RESET) { }
+
+    presence = USART_ReceiveData(ow_sensor[sensor].uart_addr);
+
+    uart_hw_init(ow_sensor[sensor].uart_addr, DALLAS_SENSOR_UART_BAUD, DALLAS_SENSOR_UART_WORD_LEN,
+              DALLAS_SENSOR_UART_PARITY, DALLAS_SENSOR_UART_STOP_BIT);
+
+    if (presence != 0xf0) {
+        DBG printf("DALLAS_SensorReset: DALLAS_OK\r\n");
+        return DALLAS_OK;
+    }
+
+    DBG printf("DALLAS_SensorReset: DALLAS_NO_DEVICE\r\n");
+    return DALLAS_NO_DEVICE;
+}
+
+/**
+  * @brief   Отправка и прием данных
+  * @param   sendReset посылать RESET в начале общения.
+  *          OW_SEND_RESET
+  *          OW_NO_RESET
+  * @param   *command - массив байт, отсылаемых в шину.
+  *          Если нужно чтение - отправляем OW_READ_SLOTH
+  * @param   cLen - длина буфера команд, столько байт отошлется в шину
+  * @param   *data - если требуется чтение, то ссылка на буфер для чтения
+  * @param   dLen - длина буфера для чтения. Прочитается не более этой длины
+  * @param   readStart - с какого символа передачи начинать чтение (нумеруются с 0)
+  *          можно указать OW_NO_READ, тогда можно не задавать data и dLen
+  * @retval
+  */
+uint8_t DALLAS_Send(t_sensor_list_t sensor, uint8_t sendReset, uint8_t *command,
+    uint8_t cLen, uint8_t *data, uint8_t dLen, uint8_t readStart)
+{
+    uint32_t timeOutCounter = 0;
+    DMA_Stream_TypeDef *RxDMA_Stream = NULL;
+    DMA_Stream_TypeDef *TxDMA_Stream = NULL;
+
+    if (ow_sensor[sensor].uart_addr == USART1) {
+      RxDMA_Stream = DMA1_Stream2;
+      TxDMA_Stream = DMA1_Stream7;
+    } else if (ow_sensor[sensor].uart_addr == USART2) {
+      RxDMA_Stream = DMA1_Stream5;
+      TxDMA_Stream = DMA1_Stream6;
+    } else if (ow_sensor[sensor].uart_addr == USART3) {
+      RxDMA_Stream = DMA1_Stream1;
+      TxDMA_Stream = DMA1_Stream3;
+    } else if (ow_sensor[sensor].uart_addr == UART4) {
+      RxDMA_Stream = DMA1_Stream2;
+      TxDMA_Stream = DMA1_Stream4;
+    } else if (ow_sensor[sensor].uart_addr == UART5) {
+      RxDMA_Stream = DMA1_Stream0;
+      TxDMA_Stream = DMA1_Stream7;
+    } else if (ow_sensor[sensor].uart_addr == USART6) {
+      RxDMA_Stream = DMA1_Stream1;
+      TxDMA_Stream = DMA1_Stream6;
+    }
+
+    /* если требуется сброс - сбрасываем и проверяем на наличие устройств */
+    if (sendReset == DALLAS_SEND_RESET) {
+        DBG printf("_Send: DALLAS_SEND_RESET\r\n");
+        if (DALLAS_SensorReset(sensor) == DALLAS_NO_DEVICE) {
+            DBG printf("_Send: DALLAS_NO_DEVICE\r\n");
+            return DALLAS_NO_DEVICE;
+        }
+    }
+
+    while (cLen > 0) {
+        DALLAS_ToBits(*command, ow_sensor[sensor].sensorBuf);
+        command++;
+        cLen--;
+
+        /* DMA на чтение */
+        DMA_DeInit(RxDMA_Stream);
+        DMA_Init(RxDMA_Stream, &ow_sensor[sensor].DMA_InitStructureRx);
+
+        /* DMA на запись */
+        DMA_DeInit(TxDMA_Stream);
+        DMA_Init(TxDMA_Stream, &ow_sensor[sensor].DMA_InitStructureTx);
+
+        /* старт цикла отправки */
+        USART_ClearFlag(ow_sensor[sensor].uart_addr, USART_FLAG_RXNE | USART_FLAG_TC );
+        USART_DMACmd(ow_sensor[sensor].uart_addr, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
+        DMA_Cmd(RxDMA_Stream, ENABLE);
+        DMA_Cmd(TxDMA_Stream, ENABLE);
+
+
+        while (DMA_GetFlagStatus(RxDMA_Stream, DMA_FLAG_TCIF5) == RESET) {
+
+            timeOutCounter++;
+            if (timeOutCounter > DALLAS_TIME_OUT) {
+                DBG printf("_Send: return DALLAS_ERROR\r\n");
+                return DALLAS_ERROR;
+            }
+        }
+        DBG printf("timeOutCounter: %u\r\n", (unsigned int)timeOutCounter);
+
+
+        /* отключаем DMA */
+        DMA_Cmd(RxDMA_Stream, DISABLE);
+        DMA_Cmd(TxDMA_Stream, DISABLE);
+        USART_DMACmd(ow_sensor[sensor].uart_addr, USART_DMAReq_Tx | USART_DMAReq_Rx, DISABLE);
+
+        /* если прочитанные данные кому-то нужны - выкинем их в буфер */
+        DBG printf("_Send: readStart = %d, dLen = %d\r\n", readStart, dLen);
+        if (readStart == 0 && dLen > 0) {
+            *data = DALLAS_ToByte(ow_sensor[sensor].sensorBuf);
+            data++;
+            dLen--;
+            DBG printf("_Send: Copy\r\n");
+        } else {
+            if (readStart != DALLAS_NO_READ) {
+                readStart--;
+                DBG printf("_Send: readStart--\r\n");
+            }
+            DBG printf("_Send: else state\r\n");
+        }
+    }
+
+    DBG printf("_Send: return DALLAS_OK\r\n");
+
+    return DALLAS_OK;
+}
+
+/**
+  * @brief  Функция преобразует один байт в восемь, для передачи через USART
+  * @param  ow_byte - байт, который надо преобразовать
+  * @param  ow_bits - ссылка на буфер, размером не менее 8 байт
+  * @retval
+  */
+void DALLAS_ToBits(uint8_t ow_byte, uint8_t *ow_bits)
+{
+    uint8_t i;
+
+    for (i = 0; i < 8; i++) {
+        if (ow_byte & 0x01) {
+            *ow_bits = DALLAS_1;
+        } else {
+            *ow_bits = DALLAS_0;
+        }
+
+        ow_bits++;
+        ow_byte = ow_byte >> 1;
+    }
+}
+
+/**
+  * @brief  Обратное преобразование - из того, что получено через USART опять собирается байт
+  * @param  ow_bits - ссылка на буфер, размером не менее 8 байт
+  * @param  ow_byte - собранный байт данных
+  * @retval
+  */
+uint8_t DALLAS_ToByte(uint8_t *ow_bits)
+{
+    uint8_t ow_byte, i;
+    ow_byte = 0;
+
+    for (i = 0; i < 8; i++) {
+        ow_byte = ow_byte >> 1;
+        if (*ow_bits == DALLAS_R_1) {
+            ow_byte |= 0x80;
+        }
+
+        ow_bits++;
+    }
+    return ow_byte;
+}

+ 88 - 0
modules/ds18b20/onewire.h

@@ -0,0 +1,88 @@
+/********************************* (C) РОТЕК ***********************************
+ * @module  onewire
+ * @file    onewire.h
+ * @version 1.0.0
+ * @date    XX.XX.XXXX
+ * $brief   DS18B20 temperature sensor driver
+ *******************************************************************************
+ * @history     Version  Author         Comment
+ * XX.XX.XXXX   1.0.0    Telenkov D.A.  First release.
+ *******************************************************************************
+ */
+
+#ifndef ONEWIRE_H
+#define ONEWIRE_H
+
+#include <stdint.h>
+#include "common_config.h"
+
+//#define DALLAS_TWO_LINE_SWITCH  //двупроводное подключение
+
+/* Первый параметр функции OW_Send */
+#define DALLAS_SEND_RESET 1
+#define DALLAS_NO_RESET   2
+
+/* Статус возврата функций */
+#define DALLAS_OK         1
+#define DALLAS_ERROR      2
+#define DALLAS_NO_DEVICE  3
+
+#define DALLAS_NO_READ    0xff
+#define DALLAS_READ_SLOT  0xff
+
+/**
+  * @brief  Настройка USART
+  */
+void DALLAS_Init();
+
+/**
+  * @brief  Настройка DMA
+  */
+void DALLAS_DmaInit(void);
+
+/**
+  * @brief  Сброс и проверка наличия устройства на шине 1-wire 
+  */
+uint8_t DALLAS_SensorReset(t_sensor_list_t sensor);
+
+/**
+  * @brief  Настроить TX пин как питающий выход
+  */
+void DALLAS_OutSetAsPower(t_sensor_list_t sensor);
+
+/**
+  * @brief  Настроить TX пин как передатчик
+  */
+void DALLAS_OutSetAsTX(t_sensor_list_t sensor);
+
+/**
+  * @brief   Отправка и прием данных
+  * @param   sendReset посылать RESET в начале общения.
+  *          OW_SEND_RESET
+  *          OW_NO_RESET
+  * @param   *command - массив байт, отсылаемых в шину. 
+  *          Если нужно чтение - отправляем OW_READ_SLOTH
+  * @param   cLen - длина буфера команд, столько байт отошлется в шину
+  * @param   *data - если требуется чтение, то ссылка на буфер для чтения
+  * @param   dLen - длина буфера для чтения. Прочитается не более этой длины
+  * @param   readStart - с какого символа передачи начинать чтение (нумеруются с 0)
+  *          можно указать OW_NO_READ, тогда можно не задавать data и dLen
+  */
+uint8_t DALLAS_Send(t_sensor_list_t sensor, uint8_t sendReset, uint8_t *command,
+                    uint8_t cLen, uint8_t *data, uint8_t dLen, uint8_t readStart);
+
+/**
+  * @brief  Функция преобразует один байт в восемь, для передачи через USART
+  * @param  ow_byte - байт, который надо преобразовать
+  * @param  ow_bits - ссылка на буфер, размером не менее 8 байт
+  */
+void DALLAS_ToBits(uint8_t ow_byte, uint8_t *ow_bits);
+
+/**
+  * @brief  Обратное преобразование - из того, что получено через USART опять собирается байт
+  * @param  ow_bits - ссылка на буфер, размером не менее 8 байт
+  * @param  ow_byte - собранный байт данных
+  */
+uint8_t DALLAS_ToByte(uint8_t *ow_bits);
+
+#endif /* ONEWIRE_H */

+ 227 - 0
modules/ds18b20/temper.c

@@ -0,0 +1,227 @@
+/*
+ * temper.c
+ *
+ *  Created on: 22.04.2016
+ *      Author: pavel
+ */
+#include "common_config.h"
+#include "onewire.h"
+#include "gpio.h"
+#include "temper.h"
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#ifdef PRINTF_STDLIB
+#include <stdio.h>
+#endif
+#ifdef PRINTF_CUSTOM
+#include "tinystdio.h"
+#endif
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+#define ERRORS_LIMIT    5
+
+#undef DBG
+#define DBG if(0)
+
+
+const unsigned char crc_table[] = {
+    0, 94,188,226, 97, 63,221,131,194,156,126, 32,163,253, 31, 65,
+    157,195, 33,127,252,162, 64, 30, 95, 1,227,189, 62, 96,130,220,
+    35,125,159,193, 66, 28,254,160,225,191, 93, 3,128,222, 60, 98,
+    190,224, 2, 92,223,129, 99, 61,124, 34,192,158, 29, 67,161,255,
+    70, 24,250,164, 39,121,155,197,132,218, 56,102,229,187, 89, 7,
+    219,133,103, 57,186,228, 6, 88, 25, 71,165,251,120, 38,196,154,
+    101, 59,217,135, 4, 90,184,230,167,249, 27, 69,198,152,122, 36,
+    248,166, 68, 26,153,199, 37,123, 58,100,134,216, 91, 5,231,185,
+    140,210, 48,110,237,179, 81, 15, 78, 16,242,172, 47,113,147,205,
+    17, 79,173,243,112, 46,204,146,211,141,111, 49,178,236, 14, 80,
+    175,241, 19, 77,206,144,114, 44,109, 51,209,143, 12, 82,176,238,
+    50,108,142,208, 83, 13,239,177,240,174, 76, 18,145,207, 45,115,
+    202,148,118, 40,171,245, 23, 73, 8, 86,180,234,105, 55,213,139,
+    87, 9,235,181, 54,104,138,212,149,203, 41,119,244,170, 72, 22,
+    233,183, 85, 11,136,214, 52,106, 43,117,151,201, 74, 20,246,168,
+    116, 42,200,150, 21, 75,169,247,182,232, 10, 84,215,137,107, 53
+};
+
+static uint8_t  tBufExt[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0};
+static uint16_t tempInt = 0;
+
+/**
+  * @brief Cтруктура датчиков температуры (измерения, состояния, счетчики ошибок)
+  */
+TEMPERATURE_SENSORS_t sTemperSensors[MAX_T_SENSORS];
+
+/**
+  * @brief Временные флаги инициализации данных
+  */
+static bool fReady[MAX_T_SENSORS];
+
+/**
+  * @brief Глобальный флаг инициализации данных температурных датчиков
+  */
+bool fTemperDataReady = false;
+
+
+uint8_t CheckCRC(uint8_t *data, uint8_t len)
+{
+    uint8_t crc = 0;
+
+    while (len--) crc = crc_table[crc ^ *data++];
+    return crc;
+}
+
+/**
+  * @brief  Чтение температуры из датчика
+  */
+bool GetTemperature(uint8_t sensor)
+{
+    float temperature = 85.0;
+    static uint8_t  state;
+    bool dataReady = false;
+
+
+    /* Запускаем преобразование температуры */
+#ifdef DALLAS_TWO_LINE_SWITCH
+    DALLAS_OutSetAsTX(sensor);
+#endif
+    state = DALLAS_Send(sensor, DALLAS_SEND_RESET, (uint8_t *)"\xcc\x44", 2, NULL, 0, DALLAS_NO_READ);
+
+    if ((state == DALLAS_ERROR) || (state == DALLAS_NO_DEVICE)) {
+      sTemperSensors[sensor].ErrorCounter++;
+    }
+#ifdef DALLAS_TWO_LINE_SWITCH
+    DALLAS_OutSetAsPower(sensor);
+#endif
+    /* Ждем пока датчики закончат преобразование */
+    vTaskDelay(800);
+
+    /* Clear CRC byte */
+    tBufExt[8] = 0;
+
+    /* Чтение температуры */
+#ifdef DALLAS_TWO_LINE_SWITCH
+    DALLAS_OutSetAsTX(sensor);
+#endif
+    state = DALLAS_Send(sensor, DALLAS_SEND_RESET,
+            (uint8_t *)"\xcc\xbe\xff\xff\xff\xff\xff\xff\xff\xff\xff", 11, tBufExt, 9, 2);
+
+    if ((state == DALLAS_ERROR) || (state == DALLAS_NO_DEVICE)) {
+      sTemperSensors[sensor].ErrorCounter++;
+    }
+
+    /* Check CRC */
+    if (state == DALLAS_OK) {
+
+        /* Sometimes we get DALLAS_OK, and empty tBufExt,
+         * while sensor surely not connected. For zero filled tBufExt
+         * CRC is always ok. To detect this, furst check if buffer is empty */
+        uint8_t sum = 0;
+        for  (uint8_t i = 0; i < sizeof(tBufExt); i++) {
+            sum |= tBufExt[i];
+        }
+
+        uint8_t crc = CheckCRC(tBufExt, 9);
+        if ((crc != 0) || (sum == 0)) {
+            sTemperSensors[sensor].ErrorCounter++;
+        }
+        DBG { printf("Sensor %d: ", sensor);
+            for (uint8_t i = 0; i < 9; i++) printf("0x%X ", tBufExt[i]);
+            crc ? printf("CRC Fail\r\n") : printf("CRC OK\r\n"); }
+    }
+
+    /* ---------------------------------------------------------------------- */
+    /* Расчет температуры датчика */
+    if (!sTemperSensors[sensor].ErrorCounter)
+    {
+      tempInt = tBufExt[0];
+      tempInt |= tBufExt[1] << 8;
+
+      /* Если число в дополнительном коде */
+      if ((tempInt & 0x8000))
+      {
+        tempInt = ~tempInt + 1;
+        temperature = -1*(tempInt/16.0);
+      }
+      else {
+        temperature = tempInt/16.0;
+      }
+
+      DBG printf("temperature: %0.1f\r\n", temperature);
+
+      if ((temperature != 85.0) && (temperature != -0.0625)) {
+           sTemperSensors[sensor].Temperature = temperature;
+           sTemperSensors[sensor].SensorState = 0;
+           dataReady = true;
+      }
+      sTemperSensors[sensor].ErrorCycle = 0;
+    }
+    /* Если были ошибки, то показания тепературы не обновляем */
+    else
+    {
+      sTemperSensors[sensor].ErrorCycle++;
+      sTemperSensors[sensor].ErrorCounter = 0;
+
+      /* Произошло несколько ошибочных циклов общения с датчиком */
+      /* Выставляем признак отказа датчика */
+      if (sTemperSensors[sensor].ErrorCycle == ERRORS_LIMIT)
+      {
+        sTemperSensors[sensor].SensorState = 1;  // Неисправность!
+        sTemperSensors[sensor].ErrorCycle = 0;
+        dataReady = true;
+      }
+    }
+
+    DBG printf("Temperature sensor %d: %0.1f State = %d\r\n\r\n", sensor,
+            sTemperSensors[sensor].Temperature, sTemperSensors[sensor].SensorState);
+
+    return dataReady;
+}
+
+/**
+  * @brief  Опрос датчиков температуры
+  */
+void RequestSensors(void) {
+    bool ready = true;
+
+    for (uint8_t i = 0; i < MAX_T_SENSORS; i++) {
+      ready &= GetTemperature(i);
+    }
+
+    /* Установка глобального флага готовности данных */
+    if (ready) {
+      fTemperDataReady = true;
+    }
+}
+
+/**
+  * @brief  Задача чтения температуры 1-wire
+  */
+void vTaskOwire(void *pvParameters)
+{
+  (void)pvParameters;
+  uint8_t i;
+
+  for (i = 0; i < MAX_T_SENSORS; i++) {
+    sTemperSensors[i].Temperature  = 0.0;
+    sTemperSensors[i].ErrorCounter = 0;
+    sTemperSensors[i].ErrorCycle   = 0;
+    sTemperSensors[i].SensorState  = 1;  // По умолчанию устанавливаем признак неисправности
+  }
+
+  DALLAS_Init();
+
+  for (;;)
+  {
+      RequestSensors();
+      vTaskDelay(1000);
+  }
+}
+
+void OW_Init(void) {
+    xTaskCreate(vTaskOwire, "vTaskOwire", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
+}

+ 38 - 0
modules/ds18b20/temper.h

@@ -0,0 +1,38 @@
+/*
+ * temperature.h
+ *
+ *  Created on: 22.04.2016
+ *      Author: pavel
+ */
+
+#ifndef TEMPERATURE_H_
+#define TEMPERATURE_H_
+
+#include <stdbool.h>
+#include "onewire.h"
+
+
+typedef struct
+{
+  float   Temperature;  // Значение температуры
+  uint8_t ErrorCounter; // Счетчик ошибок связи с датчиком
+  uint8_t ErrorCycle;   // Счетчик ошибок циклов преобразования температуры
+  uint8_t SensorState;  // Состояние датчика (0 - датчик работает, 1 - неисправность)
+} TEMPERATURE_SENSORS_t;
+
+/**
+  * @brief Cтруктура датчиков температуры (измерения, состояния, счетчики ошибок)
+  */
+TEMPERATURE_SENSORS_t sTemperSensors[MAX_T_SENSORS];
+
+/**
+  * @brief Флаг инициализации данных температурных датчиков
+  */
+bool fTemperDataReady;
+
+/**
+  * @brief  Инициализация датчиков температуры 1-wire
+  */
+void OW_Init(void);
+
+#endif /* TEMPERATURE_H_ */

+ 14 - 0
peripheral_modules/inc/usart.h

@@ -15,6 +15,7 @@
 #define USART_H
 
 #include <stdint.h>
+#include "stm32f4xx.h"
 
 #include "FreeRTOS.h"
 #include "queue.h"
@@ -50,7 +51,20 @@ QueueHandle_t rs485TxQ, rs485RxQ;
 SemaphoreHandle_t rs485mutex;
 #endif
 
+#ifdef DALLAS_SENSOR_ENABLE
+#define DALLAS_SENSOR_1_USART              UART4
+#define DALLAS_SENSOR_2_USART              UART5
+#define DALLAS_SENSOR_UART_BAUD            115200
+#define DALLAS_SENSOR_RST_UART_BAUD        9600
+#define	DALLAS_SENSOR_UART_WORD_LEN        8
+#define	DALLAS_SENSOR_UART_PARITY          USART_Parity_No
+#define DALLAS_SENSOR_UART_STOP_BIT        USART_StopBits_1
+#endif
+
 void init_ups_rbuf(void);
+
+void uart_hw_init(USART_TypeDef *uart, uint32_t baud, uint16_t wordlen, uint16_t parity, uint16_t stop);
+
 /**
   * @brief  
   */

+ 18 - 0
user/init_task.c

@@ -38,6 +38,12 @@
 #elif defined SSL_SERVER_ENABLE
 #include "my_ssl_server.h"
 #endif
+#ifdef PORTGW_ENABLE
+#include "portgw.h"
+#endif
+#ifdef DALLAS_SENSOR_ENABLE
+#include "temper.h"
+#endif
 #include "sntp_api.h"
 #include "settings_api.h"
 #include "main.h"
@@ -136,6 +142,12 @@ void InitTask(void *params)
 #endif
 // -----------------------------------------------------------------------------  
   
+// -----------------------------------------------------------------------------  
+#ifdef DALLAS_SENSOR_ENABLE
+    OW_Init();
+#endif
+// -----------------------------------------------------------------------------  
+
 // -----------------------------------------------------------------------------    
 /* Random number generator */
   RNG_Init();
@@ -186,6 +198,12 @@ void InitTask(void *params)
   xTaskCreate(vTaskPeriodicSynchro, "sntpPeriodicSinhro", 2*configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL);
 // -----------------------------------------------------------------------------  
 
+// -----------------------------------------------------------------------------  
+// Прозрачный порт
+#ifdef PORTGW_ENABLE
+  portgw_init();
+#endif
+
 // -----------------------------------------------------------------------------  
 // Тестирование