title: stm32 freeRTOS UART Rx and Tx with DMA echo in Task
body: <p>I'm trying to do a kind of "terminal" interaction with my STM32L476.
  First of all I want to do a direct echo, when I recive data send it back for the same UART.
  After, I want to put the echo in a task.</p>
  
  <p>Question:
  I'm implementing a hard-real time OS and want to leave UART operations to IDLE task, or very low priority task. 
  Is this a good way of doing things? </p>
  
  <p>I can print using:</p>
  
  <p><code>void uartPrint(UART_HandleTypeDef *huart, char _out[]){
      HAL_UART_Transmit_DMA(huart, (uint8_t *) _out, strlen(_out));
  }</code></p>
  
  <p>But I don't receive, or the <code>HAL_UART_RxCpltCallback</code>is not called never.</p>
  
  <p>main.c</p>
  
  <pre><code>/
  /* Includes ------------------------------------------------------------------*/
  #include "main.h"
  #include "stm32l4xx_hal.h"
  #include "cmsis_os.h"
  #include "dma.h"
  #include "usart.h"
  #include "spi.h"
  #include "tim.h"
  #include "gpio.h"
  
  #include "display.h"
  
  SPI_HandleTypeDef hspi1;
  UART_HandleTypeDef hlpuart1;
  
  uint8_t rxData;
  
  void SystemClock_Config(void);
  void MX_FREERTOS_Init(void);
  
  int main(void)
  {
  
    HAL_Init();
    SystemClock_Config();
  
    MX_GPIO_Init();
    MX_DMA_Init();
    MX_LPUART1_UART_Init();
    MX_SPI2_Init();
    MX_TIM15_Init();
  
    MX_FREERTOS_Init();
  
    osKernelStart();
  
      while (1){
  
      }
  
  }
  
  /** System Clock Configuration*/
  void SystemClock_Config(void)
  {
  
    RCC_OscInitTypeDef RCC_OscInitStruct;
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    RCC_PeriphCLKInitTypeDef PeriphClkInit;
  
      /**Initializes the CPU, AHB and APB busses clocks 
      */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLN = 20;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
    if (HAL_RCC_OscConfig(&amp;RCC_OscInitStruct) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
      /**Initializes the CPU, AHB and APB busses clocks 
      */
    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                                |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  
    if (HAL_RCC_ClockConfig(&amp;RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPUART1;
    PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
    if (HAL_RCCEx_PeriphCLKConfig(&amp;PeriphClkInit) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
      /**Configure the main internal regulator output voltage 
      */
    if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
      /**Configure the Systick interrupt time 
      */
    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  
      /**Configure the Systick 
      */
    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  
    /* SysTick_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
  }
  
  void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
  {
    if (htim-&gt;Instance == TIM1) {
      HAL_IncTick();
    }
  }
  
  void _Error_Handler(char * file, int line)
  {
      while(1)
      {
      }
  }
  
  #ifdef USE_FULL_ASSERT
  
  void assert_failed(uint8_t* file, uint32_t line)
  {
  
  }
  
  #endif
  </code></pre>
  
  <p>usart.c</p>
  
  <pre><code>#include "usart.h"
  
  #include "gpio.h"
  #include "dma.h"
  
  /* USER CODE BEGIN 0 */
  #include "cmsis_os.h"
  #include "string.h"
  
  uint8_t Uart1RxBuf [UART3_RX_TRAMA_LONG];
  uint8_t RxBuffer;
  uint8_t rxData;
  /* USER CODE END 0 */
  
  UART_HandleTypeDef hlpuart1;
  DMA_HandleTypeDef hdma_lpuart_rx;
  DMA_HandleTypeDef hdma_lpuart_tx;
  
  /* LPUART1 init function */
  
  void MX_LPUART1_UART_Init(void)
  {
  
    hlpuart1.Instance = LPUART1;
    hlpuart1.Init.BaudRate = 115200;
    hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
    hlpuart1.Init.StopBits = UART_STOPBITS_1;
    hlpuart1.Init.Parity = UART_PARITY_NONE;
    hlpuart1.Init.Mode = UART_MODE_TX_RX;
    hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
    hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    if (HAL_UART_Init(&amp;hlpuart1) != HAL_OK)
    {
      _Error_Handler(__FILE__, __LINE__);
    }
  
  }
  
  void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
  {
  
    GPIO_InitTypeDef GPIO_InitStruct;
    if(uartHandle-&gt;Instance==LPUART1)
    {
      __HAL_RCC_LPUART1_CLK_ENABLE();
      GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
      GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
      GPIO_InitStruct.Pull = GPIO_PULLUP;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
      GPIO_InitStruct.Alternate = GPIO_AF8_LPUART1;
      HAL_GPIO_Init(GPIOC, &amp;GPIO_InitStruct);
  
      hdma_lpuart_rx.Instance = DMA2_Channel7;
      hdma_lpuart_rx.Init.Request = DMA_REQUEST_4;
      hdma_lpuart_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
      hdma_lpuart_rx.Init.PeriphInc = DMA_PINC_DISABLE;
      hdma_lpuart_rx.Init.MemInc = DMA_MINC_ENABLE;
      hdma_lpuart_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
      hdma_lpuart_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
      hdma_lpuart_rx.Init.Mode = DMA_NORMAL;
      hdma_lpuart_rx.Init.Priority = DMA_PRIORITY_LOW;
      if (HAL_DMA_Init(&amp;hdma_lpuart_rx) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
  
      __HAL_LINKDMA(uartHandle,hdmarx,hdma_lpuart_rx);
  
      /* LPUART_TX Init */
      hdma_lpuart_tx.Instance = DMA2_Channel6;
      hdma_lpuart_tx.Init.Request = DMA_REQUEST_4;
      hdma_lpuart_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
      hdma_lpuart_tx.Init.PeriphInc = DMA_PINC_DISABLE;
      hdma_lpuart_tx.Init.MemInc = DMA_MINC_ENABLE;
      hdma_lpuart_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
      hdma_lpuart_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
      hdma_lpuart_tx.Init.Mode = DMA_NORMAL;
      hdma_lpuart_tx.Init.Priority = DMA_PRIORITY_LOW;
      if (HAL_DMA_Init(&amp;hdma_lpuart_tx) != HAL_OK)
      {
        _Error_Handler(__FILE__, __LINE__);
      }
  
      __HAL_LINKDMA(uartHandle,hdmatx,hdma_lpuart_tx);
  
      /* LPUART1 interrupt Init */
      HAL_NVIC_SetPriority(LPUART1_IRQn, 5, 0);
      HAL_NVIC_EnableIRQ(LPUART1_IRQn);
    /* USER CODE BEGIN LPUART1_MspInit 1 */
          uartTaskStatus = INIT;
  
          HAL_UART_Receive_DMA(&amp;hlpuart1,&amp;rxData,1);
    /* USER CODE END LPUART1_MspInit 1 */
    }
  }
  
  void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
  {
  
    if(uartHandle-&gt;Instance==LPUART1)
    {
      __HAL_RCC_LPUART1_CLK_DISABLE();
      HAL_GPIO_DeInit(GPIOC, GPIO_PIN_0|GPIO_PIN_1);
      HAL_DMA_DeInit(uartHandle-&gt;hdmarx);
      HAL_DMA_DeInit(uartHandle-&gt;hdmatx);
      HAL_NVIC_DisableIRQ(LPUART1_IRQn);
  
    }
  } 
  
  void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
  {
      if(UartHandle -&gt; Instance == hlpuart1.Instance){
          HAL_UART_Transmit_DMA(&amp;hlpuart1,&amp;rxData,1);
      }
  }
  
  void uartPrint(UART_HandleTypeDef *huart, char _out[]){
      HAL_UART_Transmit_DMA(huart, (uint8_t *) _out, strlen(_out));
  }
  
  void UartTask(void const *argument){
      char inBuffer[8];
      for(;;){
          switch(uartTaskStatus){
          case ERR:
              break;
          case INIT:
              uartPrint(&amp;hlpuart1,"Uart Init: \r\n");
              uartTaskStatus = READ;
              break;
          case READ:
              break;
          }
          osDelay(100);
      }
  }
  </code></pre>
  
  <p>I'm not using yet the uart task, but here is where I create the task at freertos.c</p>
  
  <pre><code>osThreadDef(uartTask, UartTask, osPriorityNormal, 0, 128);
  uartTaskHandle = osThreadCreate(osThread(uartTask), NULL);
  </code></pre>
  
  <p>The <code>Uart Init:</code> appears on my terminal.</p>
  
  <p>When I debug, program never reaches the <code>HAL_UART_RxCpltCallback</code>.</p>
  
  <p>Thanks!</p>
  
  <p>EDIT 1: </p>
  
  <p>DMA init!</p>
  
  <pre><code>void MX_DMA_Init(void) 
  {
    /* DMA controller clock enable */
    __HAL_RCC_DMA2_CLK_ENABLE();
    __HAL_RCC_DMA1_CLK_ENABLE();
  
    /* DMA interrupt init */
    /* DMA1_Channel5_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);
    /* DMA2_Channel6_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(DMA2_Channel6_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(DMA2_Channel6_IRQn);
    /* DMA2_Channel7_IRQn interrupt configuration */
    HAL_NVIC_SetPriority(DMA2_Channel7_IRQn, 5, 0);
    HAL_NVIC_EnableIRQ(DMA2_Channel7_IRQn);
  
  }
  </code></pre>