| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 | 
							- /********************************* (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 "stm32f4xx.h"
 
- #include "stm32f4xx_dma.h"
 
- #include "usart.h"
 
- #include "gpio.h"
 
- #include "onewire.h"
 
- #ifdef PRINTF_STDLIB
 
- #include <stdio.h>
 
- #endif
 
- #ifdef PRINTF_CUSTOM
 
- #include "tinystdio.h"
 
- #endif
 
- /* Force remove debug output */
 
- #undef DBG
 
- #define DBG if(0)
 
- #ifdef DALLAS_SENSOR_ENABLE
 
- /**
 
-   * @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;
 
-   uint8_t sensorBuf[DALLAS_BUF_SIZE];
 
- }ow_sensor_t;
 
- ow_sensor_t ow_sensor[MAX_T_SENSORS];
 
- #define T_SENSOR_ADD(sensor_num, ow_line, uart) \
 
-   do { \
 
-     ow_sensor[sensor_num].uart_addr = uart; \
 
-     ow_sensor[sensor_num].ow_pin = ow_line; \
 
-   } while (0);
 
- /**
 
-   * @brief  Настройка USART
 
-   * @retval
 
-   */
 
- void DALLAS_Init()
 
- {
 
- #define XTSENSOR(sensor_num, ow_line, uart) T_SENSOR_ADD(sensor_num, ow_line, uart);
 
-       T_SENSOR_TABLE
 
- #undef XTSENSOR
 
-   for (uint8_t i = 0; i < MAX_T_SENSORS; i ++) {
 
-     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 = DMA2_Stream1;
 
-       TxDMA_Stream = DMA2_Stream6;
 
-       RxDMA_Channel = DMA_Channel_5;
 
-       TxDMA_Channel = DMA_Channel_5;
 
-     }
 
-   
 
-       /* DMA на чтение */
 
-       DMA_DeInit(RxDMA_Stream);
 
-       ow_sensor[i].DMA_InitStructureRx.DMA_Channel = RxDMA_Channel;
 
-       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_Channel;
 
-       ow_sensor[i].DMA_InitStructureTx.DMA_PeripheralBaseAddr = &ow_sensor[i].uart_addr->DR;
 
-       ow_sensor[i].DMA_InitStructureTx.DMA_Memory0BaseAddr = (uint32_t)&ow_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(ow_sensor[sensor].ow_pin, 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(ow_sensor[sensor].ow_pin, 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_config_reinit(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_config_reinit(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;
 
-     uint32_t DMA_FLAG_TCIF = 0;
 
-     DMA_Stream_TypeDef *RxDMA_Stream = NULL;
 
-     DMA_Stream_TypeDef *TxDMA_Stream = NULL;
 
-     if (ow_sensor[sensor].uart_addr == USART1) {
 
-       DMA_FLAG_TCIF = DMA_FLAG_TCIF2;
 
-       RxDMA_Stream = DMA1_Stream2;
 
-       TxDMA_Stream = DMA1_Stream7;
 
-     } else if (ow_sensor[sensor].uart_addr == USART2) {
 
-       DMA_FLAG_TCIF = DMA_FLAG_TCIF5;
 
-       RxDMA_Stream = DMA1_Stream5;
 
-       TxDMA_Stream = DMA1_Stream6;
 
-     } else if (ow_sensor[sensor].uart_addr == USART3) {
 
-       DMA_FLAG_TCIF = DMA_FLAG_TCIF1;
 
-       RxDMA_Stream = DMA1_Stream1;
 
-       TxDMA_Stream = DMA1_Stream3;
 
-     } else if (ow_sensor[sensor].uart_addr == UART4) {
 
-       DMA_FLAG_TCIF = DMA_FLAG_TCIF2;
 
-       RxDMA_Stream = DMA1_Stream2;
 
-       TxDMA_Stream = DMA1_Stream4;
 
-     } else if (ow_sensor[sensor].uart_addr == UART5) {
 
-       DMA_FLAG_TCIF = DMA_FLAG_TCIF0;
 
-       RxDMA_Stream = DMA1_Stream0;
 
-       TxDMA_Stream = DMA1_Stream7;
 
-     } else if (ow_sensor[sensor].uart_addr == USART6) {
 
-       DMA_FLAG_TCIF = DMA_FLAG_TCIF1;
 
-       RxDMA_Stream = DMA2_Stream1;
 
-       TxDMA_Stream = DMA2_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_TCIF) == 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;
 
- }
 
- #endif
 
 
  |