cancel
Showing results for 
Search instead for 
Did you mean: 

UART Transmission Using DMA Can Only Transfer Once (Not Using Interrupts)

EGold.3
Associate II

I am working on a project that requires UART transmission using DMA. I am attempting to do this solely through register manipulation. Currently I am only able to transmit data using DMA transfer once, but when I try and send again, the UART sends nothing. Monitoring the watch windows indicates the data is indeed being transferred into the TDR register of UART5 (If, on my second transmission try, I transfer a new message, the final byte of that message is transferred into TDR).

The method for sending is the following:

void sendFrame()
{
    //disable DMA channel during preparation
    DMA2_Channel1->CCR &= ~DMA_CCR_EN;
    //peripheral memory address for transmission is the Tramsission Data register for UART5
    DMA2_Channel1->CPAR = (uint32_t)&(UART5->TDR);
    //memory address in SRAM that data will be sent from to the peripheral memory address is parameter 1
    uint8_t *pTxBuffer = (uint8_t *)&txFrame.rawBytes;
    DMA2_Channel1->CMAR = (uint32_t)pTxBuffer;
    //sending msg length (body length) + (CRC (2 bytes) + EOF (1 byte) + SOF(1 byte) + ID(1 byte) //+ length of body (1 byte)) = body length + 6
//(this sets the CNDTR register value to the total length of the msg I'm sending)
    DMA2_Channel1->CNDTR = txFrame.msgLength + 6;
    //clear TC bit so I can transmit again after initial transmission
    UART5->ICR |= USART_ICR_TCCF;
//enable the DMA peripheralnow that setup is complete
    DMA2_Channel1->CCR |= DMA_CCR_EN;
//enable DMA transfer for the UART
    UART5->CR3 |= USART_CR3_DMAT;
    //wait until the transfer has completed to continue(TC bit set when the Transmit Data register has become empty)
    while((UART5->ISR & (1 << 6)) == 0);
}

2 REPLIES 2
TDK
Guru

If you write to UART5->TDR instead of using DMA for the second transfer, do you get a signal? If not, solve that first. Print out UART and DMA status flags prior to start of second transfer.

If you feel a post has answered your question, please click "Accept as Solution".

Solved the issue. I disabled the dma transfer bit set in the UART5->CR3 register after I disable the DMA channel on line 4 and then re-enable on line 18 (as it is now). This allows me to execute multiple transmissions. I think it's because never disabling it was doing something weird if transmission was constantly enabled during the transfer of bytes from the DMA