Electrical – STM DMA won’t continuously transmit on UART line

dmastm32uart

I am using an STM32L4R5 board and am trying to configure the DMA on the UART2 line. I have managed to get the RX line to operate how I want, but when I follow "Transmission Using DMA" in section 44.5.19 of the "RM0432 Reference Manual" only one byte is transmitted and nothing else.
This byte only gets sent when I explicitly write a byte to the TDR register. Afterwards, I can see the TC flag is cleared and the first byte of my DMA register is affected. How do I get the DMA to continously send out the data to the TDR for transmission?

Note: this problem seems to be simliar to an unanswered question here

The steps mentioned in the datasheet are as shown:

  1. Write the USART_TDR register address in the DMA control register to configure it as the destination of the transfer. The data is moved to this address from memory after each TXE (or TXFNF if FIFO mode is enabled) event.
  2. Write the memory address in the DMA control register to configure it as the source of the transfer. The data is loaded into the USART_TDR register from this memory area after each TXE (or TXFNF if FIFO mode is enabled) event.
  3. Configure the total number of bytes to be transferred to the DMA control register.
  4. Configure the channel priority in the DMA register
  5. Configure DMA interrupt generation after half/ full transfer as required by the application.
  6. Clear the TC flag in the USART_ISR register by setting the TCCF bit in the USART_ICR register.
  7. Activate the channel in the DMA register.

My code is here:

    //filling in dummy info into my DMA TX buffer
    memset((void*)DMA_USB_TXbuf, 0x55, 16);

    //ensuring my UART is configured for DMA Transfer
    huart2.Instance->CR3 |= USART_CR3_DMAT;

    //steps 1-4 taken care of within this funciton
    HAL_DMA_Start_IT(&hdma_usart2_tx, (uint32_t)&huart2.Instance->TDR, (uint32_t)&DMA_USB_TXbuf[0], DMA_USB_TX_SIZE);

    //step 5 (just ensuring that we have the flags we want after the previous function)
    __HAL_DMA_DISABLE(&hdma_usart2_tx);
    __HAL_DMA_ENABLE_IT(&hdma_usart2_tx, DMA_IT_HT);
    __HAL_DMA_ENABLE_IT(&hdma_usart2_tx, DMA_IT_TC);

    //step 6
    __HAL_UART_CLEAR_FLAG(&huart2, UART_CLEAR_TCF);

    //step 7
    __HAL_DMA_ENABLE(&hdma_usart2_tx);

    //I shouldn't need to do this, but this seems to be the only way
    // I get even 1 trasmission from DMA register
    WRITE_REG(huart2.Instance->TDR, 0x55);

Best Answer

There were two parts to why this was not working as it should.

  1. As per comment by Codo, simply using this function worked for setting up and transmitting the UART DMA on the UART line
  2. My UART is configured with RTS/CTS flow control and my receiving line was not ready which was preventing more characters to be sent out.

Thank you Codo

Related Topic