title: Using DMA with two UART peripherals - is it possible?
body: <p>I want to connect two UART peripherals using STM32G0 microcontroller via <strong>DMA</strong>. Not knowing the length of the messages in forward, I'm using function <code>HAL_UARTEx_ReceiveToIdle_DMA()</code> in order to receive them. Here is the part of my code:</p>
  <p><strong>main.h</strong></p>
  <pre><code>.
  .
  .
      StartDMAReceptionOverUART1();
      StartDMAReceptionOverUART4();
    /* USER CODE END 2 */
  
    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    while (1)
    {
      /* USER CODE END WHILE */
          
      /* USER CODE BEGIN 3 */
          HAL_Delay(10);  
      }
  .
  .
  .
  void StartDMAReceptionOverUART1(void)
  {
      if (HAL_UARTEx_ReceiveToIdle_DMA(m_modulePort.huart, m_modulePort.rxBuffer, m_modulePort.rxBufferSize) != HAL_OK)
    {
      Error_Handler();
    }
      __HAL_DMA_DISABLE_IT(&amp;hdma_usart1_rx, DMA_IT_HT);
      __HAL_DMA_DISABLE_IT(&amp;hdma_usart1_rx, DMA_IT_TC);
  }
  void StartDMAReceptionOverUART4(void)
  {
      if (HAL_UARTEx_ReceiveToIdle_DMA(m_meterPort.huart, m_meterPort.rxBuffer, m_meterPort.rxBufferSize) != HAL_OK)
    {
      Error_Handler();
    }
      __HAL_DMA_DISABLE_IT(&amp;hdma_usart4_rx, DMA_IT_HT);
      __HAL_DMA_DISABLE_IT(&amp;hdma_usart4_rx, DMA_IT_TC);
  }
  .
  .
  .
  </code></pre>
  <p>These functions are similar: first <code>HAL_UARTEx_ReceiveToIdle_DMA()</code> is checked, then <em>Half Transfer</em> and <em>Transfer Complete</em> interrupts are disabled in order to relieve processor (I need only IDLE interrupt). The <strong>problem</strong> is inside <code>StartDMAReceptionOverUART1()</code> function, <code>HAL_UARTEx_ReceiveToIdle_DMA()</code> never returns <code>HAL_OK</code> and program jumps on <code>Error_Handler()</code>. On the other hand, <code>StartDMAReceptionOverUART4()</code> works perfectly fine. What could be the problem?
  Also, here is the receive callback function, also written inside <strong>main.h</strong>:</p>
  <pre><code>void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
  {
      if(huart-&gt;Instance == m_meterPort.huart-&gt;Instance)                                // huart == UART4
      {
          memcpy(m_modulePort.txBuffer, m_meterPort.rxBuffer, Size);
          HAL_UART_Transmit_DMA(m_modulePort.huart, m_modulePort.txBuffer, Size);
          StartDMAReceptionOverUART4();
      }
      else if (huart-&gt;Instance == m_modulePort.huart-&gt;Instance)                        // huart == UART1                      
      {
          memcpy(m_meterPort.txBuffer, m_modulePort.rxBuffer, Size);
          HAL_UART_Transmit_DMA(m_meterPort.huart, m_meterPort.txBuffer, Size);                                                                       
      }
      else
      {
          return;
      }
  }
  </code></pre>
  <p>Callback function, in dependence of the periphery, will copy received data to a buffer and send it to the other periphery (functions <code>memcpy()</code> and <code>HAL_UART_Transmit_DMA()</code>). DMA over UART4 is in <strong>Normal</strong> mode, therefore <code>StartDMAReceptionOverUART4()</code> is called, inside which is <code>HAL_UARTEx_ReceiveToIdle_DMA()</code>. On the other hand, DMA over UART1 is in <strong>Circular</strong> mode, so there is no need for calling <code>StartDMAReceptionOverUART4()</code>.</p>