Search code examples
uartstm32f4discoveryhal

Receiving data from 2 UARTs, STM32F4-Discovery, HAL drivers


I want to receive data from 2 sensors connected to my STM32F4-Discovery via 2 UARTs. Transmitting data from STM32 to sensors works but receiving doesn´t. Guarantee it isn´t a hardware problem. I found tutorials for 1 connected UART but not for 2 at once. I would like to use new HAL drivers and DMA for receiving. Thanks for help.

 UART_HandleTypeDef huart4;
 UART_HandleTypeDef huart5;
 DMA_HandleTypeDef hdma_uart4_rx;
 DMA_HandleTypeDef hdma_uart5_rx;
 uint8_t rxBuffer4 = '\000';
 uint8_t rxBuffer5 = '\000';

 void initGPIOs_UART4(void){
        __HAL_RCC_GPIOC_CLK_ENABLE();

        GPIO_InitTypeDef GPIO_InitStructure;
        GPIO_InitStructure.Pin = GPIO_PIN_10 | GPIO_PIN_11;
        GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
        GPIO_InitStructure.Pull = GPIO_NOPULL;
        GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
        GPIO_InitStructure.Alternate = GPIO_AF8_UART4;
        HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);
    }

void initGPIOs_UART5(void){
    __HAL_RCC_GPIOC_CLK_ENABLE();
    __HAL_RCC_GPIOD_CLK_ENABLE();

    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.Pin = GPIO_PIN_12;
    GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStructure.Pull = GPIO_NOPULL;
    GPIO_InitStructure.Speed = GPIO_SPEED_MEDIUM;
    GPIO_InitStructure.Alternate = GPIO_AF8_UART5;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = GPIO_PIN_2;
    HAL_GPIO_Init(GPIOD, &GPIO_InitStructure);
}

void initUART4(void){
    initGPIOs_UART4();

    __HAL_RCC_UART4_CLK_ENABLE();
    huart4.Instance = UART4;
    huart4.Init.BaudRate = 9600;
    huart4.Init.WordLength = UART_WORDLENGTH_8B;
    huart4.Init.StopBits = UART_STOPBITS_1;
    huart4.Init.Parity = UART_PARITY_NONE;
    huart4.Init.Mode = UART_MODE_TX_RX;
    huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart4.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart4);
    __HAL_UART_FLUSH_DRREGISTER(&huart4);
}

void initUART5(void){
    initGPIOs_UART5();
    __HAL_RCC_UART5_CLK_ENABLE();
    huart5.Instance = UART5;
    huart5.Init.BaudRate = 9600;
    huart5.Init.WordLength = UART_WORDLENGTH_8B;
    huart5.Init.StopBits = UART_STOPBITS_1;
    huart5.Init.Parity = UART_PARITY_NONE;
    huart5.Init.Mode = UART_MODE_TX_RX;
    huart5.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    huart5.Init.OverSampling = UART_OVERSAMPLING_16;
    HAL_UART_Init(&huart5);
    __HAL_UART_FLUSH_DRREGISTER(&huart5);
}

void receive_start_UART4(void){
    HAL_UART_Receive_DMA(&huart4, &rxBuffer4, 1);
}

void receive_start_UART5(void){
    HAL_UART_Receive_DMA(&huart5, &rxBuffer5, 1);
}

void print_UART4(uint8_t string[], uint8_t length){
    HAL_UART_Transmit(&huart4, (uint8_t*)string, length, 5);
}

void print_UART5(uint8_t string[], uint8_t length){
    HAL_UART_Transmit(&huart5, (uint8_t*)string, length, 5);
}

void initDMA1_UART4(void){
    __HAL_RCC_DMA1_CLK_ENABLE();

    hdma_uart4_rx.Instance = DMA1_Stream2;
    hdma_uart4_rx.Init.Channel = DMA_CHANNEL_4;
    hdma_uart4_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_uart4_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_uart4_rx.Init.MemInc = DMA_MINC_DISABLE;
    hdma_uart4_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_uart4_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_uart4_rx.Init.Mode = DMA_CIRCULAR;
    hdma_uart4_rx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_uart4_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    HAL_DMA_Init(&hdma_uart4_rx);

    __HAL_LINKDMA(&huart4, hdmarx, hdma_uart4_rx);

    HAL_NVIC_SetPriority(DMA1_Stream2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(DMA1_Stream2_IRQn);
}

void initDMA1_UART5(void){
    __HAL_RCC_DMA1_CLK_ENABLE();

    hdma_uart5_rx.Instance = DMA1_Stream1;
    hdma_uart5_rx.Init.Channel = DMA_CHANNEL_5;
    hdma_uart5_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
    hdma_uart5_rx.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_uart5_rx.Init.MemInc = DMA_MINC_DISABLE;
    hdma_uart5_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_uart5_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
    hdma_uart5_rx.Init.Mode = DMA_CIRCULAR;
    hdma_uart5_rx.Init.Priority = DMA_PRIORITY_LOW;
    hdma_uart5_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    HAL_DMA_Init(&hdma_uart5_rx);

    __HAL_LINKDMA(&huart5, hdmarx, hdma_uart5_rx);

    HAL_NVIC_SetPriority(DMA1_Stream1_IRQn, 1, 0);
    HAL_NVIC_EnableIRQ(DMA1_Stream1_IRQn);
}

void DMA1_Stream2_IRQHandler(void){
    HAL_NVIC_ClearPendingIRQ(DMA1_Stream2_IRQn);
    HAL_DMA_IRQHandler(&hdma_uart4_rx);
}

void DMA1_Stream1_IRQHandler(void){
    HAL_NVIC_ClearPendingIRQ(DMA1_Stream1_IRQn);
    HAL_DMA_IRQHandler(&hdma_uart5_rx);
}

    void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
        __HAL_UART_FLUSH_DRREGISTER(&huart4);
        __HAL_UART_FLUSH_DRREGISTER(&huart5);
        trace_printf("%d - %d\n",rxBuffer4,rxBuffer5);

        //Here I´m able to receive only from UART4

}

Solution

  • Wrong DMA Stream/Channel

    DMA1_Stream1 DMA_CHANNEL_5 is assigned to UART7_TX. The stream/channel for UART5_RX should be DMA1_Stream0 DMA_CHANNEL_4.

    See Reference Manual RM0090 page 308