AnsweredAssumed Answered

UART Transmit with DMA Issues

Question asked by Fan.Tool on Jan 8, 2017
Latest reply on Jan 10, 2017 by Fan.Tool

Edit: compilable example code posted below in comments. The problem now with this code is that too many messages are being sent in addition to the wrong data being sent.

 

I am using VisualGDB and a STM32F303RET6.

 

I am having trouble trying to get the UART transmitter to work with the DMA controller. The UART transmitter works fine when I do a single transmission by manually updating the TDR. But, when I use the DMA controller, the data that is transmitted is not what is expected.

 

It appears to me that the data being sent is coming from a memory address other than the address that I have told the DMA controller to point to in CMAR. But, when looking at the address of the data and the address in the CMAR, it matches. So, I am not sure what the problem is but I do wonder if the problem is something I am not understanding with C and C++. Since VisualGDB operates in C++ files, I write C++ wrappers for the C functions that do the heavy lifting with modifying the registers. When, I tried using a data pointer for the memory address to read from that was compiled under the C compiler, I could not get the DMA controller to operate correctly. When I pass the DMA controller a memory address from a pointer that was compiled under the C++ compiler, it works but sends the wrong data.

 

Hopefully, someone can help me.

 

Here is my code to setup the DMA controller for UART1.

 

void c_uart_setup_dma(uint8_t port, uint8_t * data)
{
    uint16_t reg;
    uint32_t * tmp;
    volatile uint32_t src_address;
    volatile uint32_t dest_address;
    DMA_TypeDef * dma;
    DMA_Channel_TypeDef * dma_chan;
    USART_TypeDef * uart;
    
    // Assign the DMA channel and DMA controller based on the UART port
    c_uart_setdma(port, dma, dma_chan);
    // Assign the pointer for the UART port based on which one we want to modify
    c_uart_setport(port, uart);
    
    // set the source and destination address locations
    tmp = (uint32_t*)&data;
    src_address = *(uint32_t*)tmp;
    dest_address = (uint32_t)&uart->TDR;
    
// test to see if this changes the data at the correct location
    *data = 0;
    *(data + 1) = 0;
    *(data + 2) = 0;
    
    // configure the DMA channel
    // set the RCC clock for the DMA controller
    RCC->AHBENR |= 0x01; // enable DMA1
    RCC->AHBENR |= 0x02; // enable DMA2
    
    // set the peripheral register address data will be read from/written to
    dma_chan->CPAR = dest_address;

    // set the memory address data will be read from/written to
    dma_chan->CMAR = src_address;
    
    // configure the total number of data items to be transferred
    dma_chan->CNDTR = (uint16_t)0x03;
    
    // configure the channel priority, data transfer direction, mode, data size, and interrupt
    reg = DMA_CCR_PL | DMA_CCR_DIR | DMA_CCR_TEIE | DMA_CCR_TCIE | DMA_CCR_MINC;
    dma_chan->CCR |= reg;
    
    // activate the DMA channel
    dma_chan->CCR |= DMA_CCR_EN;
    
    // clear the TC flag
    uart->ICR |= USART_ICR_TCCF;
    
    // enable the DMA transmitter in the UART
    //uart->CR3 |= USART_CR3_DMAT;
    
    // enable the DMA IRQ
    c_uart_set_dma_irq(port);
}

 

And here is what the debug shows when stopped at the end of this setup function:

 

Here is the code for my transmit function:

void c_uart_transmit_dma(uint8_t port)
{
    uint32_t * source;
    uint32_t address;
    USART_TypeDef * uart;
    DMA_TypeDef * dma;
    DMA_Channel_TypeDef * dma_chan;

    // set the UART port
    c_uart_setport(port, uart);
    // set the DMA channel
    c_uart_setdma(port, dma, dma_chan);

    // disable the DMA channel
    dma_chan->CCR &= ~DMA_CCR_EN;

    // set the number of bytes to transfer
    dma_chan->CNDTR |= 0x03;

    // activate the DMA channel
    dma_chan->CCR |= DMA_CCR_EN;

    // clear the TC flag by writing the TCCF bit in ICR
    uart->ICR |= USART_ICR_TCCF;

    // enable the DMA transmitter in the UART
    uart->CR3 |= USART_CR3_DMAT;
}

 

Any help would be greatly appreciated!

Outcomes