Тема: OneWire на STM32 за допомоги HAL USART та DMA
Закортіло мені, аж засвербіло, сабжику.
Та не склалось як гадалось.
Щось дані які читаю з датчика більше схожі на випадкові.
Схема підключення:
http://we.easyelectronics.ru/uploads/im … 234939.png
Сутність 1-wire через USART:
Передача: на швидкості 115200 передаємо байт 0x00 це буде біт - "1", а передавши байт 0xFF отримаємо біт - "0". Тому для передачі одного байту по 1-wire треба вдути по UART 8 байтів які складаються з 0xFF та 0x00.
Прийом: Дуємо в UART байт 0xFF і якщо прочитується той же ж 0xFF то це датчик надсилає нам біт - "1". Як не 0xFF, то це буде біт - "0". Тому щоб прийняти байт з пристрою, теж треба надіслати 8 разів 0xFF і прийняти 8 байтів, а потім проаналізувавши байти на наявність 0xFF і !0xFF скласти один байт.
Нашкрябав такі функції:
Функцію reset - перевірити наявність на шині якихось пристроїв:
OneWire_TypeDef OneWire_Reset(void)
{
    uint8_t ow_presence = ONEWIRE_BYTE_RESET;
    OneWire_UARTInit(9600);
    //HAL_UART_Transmit_DMA(&HUARTx, &ow_presence, 1);
    HAL_UART_Transmit(&HUARTx, &ow_presence, 1, 100);
    //HAL_UART_Receive_DMA(&HUARTx, &ow_presence, 1);
    HAL_UART_Receive(&HUARTx, &ow_presence, 1, 100);
    //OneWire_UARTInit(115200);
    if (ow_presence != ONEWIRE_BYTE_RESET)
    {
        return OneWire_OK;
    }
    return OneWire_No_Device;
}Ця функція працює нормально саме без DMA, але для пересилки одного байту DMA особливо і не треба. Грець з ним.
Функція надсилання та прийому байтів:
OneWire_TypeDef OneWire_WriteRead(uint8_t* buffTX, uint8_t lenTX, uint8_t* buffRX, uint8_t lenRX)
{
    if(OneWire_Reset() == OneWire_No_Device)
    {
        return OneWire_No_Device;
    }
    OneWire_UARTInit(115200);
    if (lenTX != 0)
    {
        for (uint8_t i = 0; i < lenTX; i++)
        {
            for (uint8_t j = 0; j < 8; j++)
            {
                internal_Buffer[i * 8 + j] = ((buffTX[i] >> j) & 0x01) ? 0xff : 0x00;
            }
        }
        //HAL_UART_Transmit_DMA(&HUARTx, &(internal_Buffer[0]), lenTX * 8);
        //HAL_UART_Receive_DMA(&HUARTx, &(internal_Buffer[0]), lenTX * 8);
        HAL_UART_Transmit(&HUARTx, &(internal_Buffer[0]), lenTX * 8, 100);
        HAL_UART_Receive(&HUARTx, &(internal_Buffer[0]), lenTX * 8, 100);
    }
    if (lenRX != 0)
    {
        for (uint8_t i = 0; i <= lenRX * 8; i++)
        {
            internal_Buffer[i] = 0xff;
        }
        //HAL_UART_Transmit_DMA(&HUARTx, &(internal_Buffer[0]), lenRX * 8);
        //HAL_UART_Receive_DMA(&HUARTx, &(internal_Buffer[0]), lenRX * 8);
        HAL_UART_Transmit(&HUARTx, &(internal_Buffer[0]), lenRX * 8, 100);
        HAL_UART_Receive(&HUARTx, &(internal_Buffer[0]), lenRX * 8, 100);
    }
    if (lenRX != 0)
    {
        for (uint8_t i = 0; i < lenRX; i++)
        {
            for (uint8_t j = 0; j < 8; j++)
            {
                buffRX[i] = (buffRX[i]) + (((internal_Buffer[i * 8 + j] == 0xff) ? 0x01 : 0x00) << j);
            }
        }
    }
    return OneWire_OK;
}Перед кожним запитом робимо ресет, перевіряємо наявність хоч когось на лінії. 
Потім формуємо буфер згідно правил "0" це 0xFF, а "1" це 0x00.
Далі весь буфер женемо в UART.
Якщо передбачається щось прийняти, то на час прийому женемо в UART 0xFF (кількість байт прийому * 8 біт), і слухаємо як відповідає пристрій на наше кожне 0xFF. 
Потім прийомний  буфер аналізуємо, та формуємо з байтів біти, а з бітів складаємо вже реальні байти.
Спочатку даю запит "міряй", а через дві секунди, даю запит "віддай байти":
OneWire_WriteRead((uint8_t*) "\xcc\x44", 2, NULL, 0);
HAL_Delay(2000);
uint8_t buff[2];
OneWire_WriteRead((uint8_t*) "\xcc\xbe", 2, buff, 2);Теоретично наче все правильно. Але в buff якась хрінь.
Коли використовую HAL_UART_Transmit_DMA та HAL_UART_Receive_DMA то buff[0] та buff[1] однакові між собою і зменшуються з кожним запитом на 1 від 0xFF.
Коли використовую HAL_UART_Transmit та HAL_UART_Receive (без DMA), то байти в buff[0] та buff[1] більш рандомні і плавають незалежно один від одного.
Може в кого є позитивний досвід по сабжику? Чи може в коді щось не правильно? Які є ідеї як проаналізувати хто винен і що робити? Будь що?