Skip to main content
John Hite
Associate III
January 27, 2017
Question

DMA uart transfers

  • January 27, 2017
  • 6 replies
  • 1371 views
Posted on January 27, 2017 at 20:06

I have been thrust into a situation where I realize I am in over my head. Eventually I think I will figure it out but could use a leg up with this STM32F437 device. I know little about it and especially it’s dma.

The project I have been assigned to uses DMA to communicate with the debug port UART8.

The DMAChannel is set to DMA_Channel_5, and from the table transmission for uart 8 is set for stream 0  and rx is stream6.

We are using Micrium uC/OS-III and in the interrupt vector table I see no interrupts setup for the UART but I do see an RxISR and a TxISR. From this should I assume that there is some smart linkage that lets the DMA know there are characters available at the UART.

AT startup the welcome banner is splashed. However when a character is entered to start the login process the system hangs up. Looking at the registers we see a transmit transfer error bit that will not clear.

My co-worker suspects that maybe it is due to dma transmit and receive happening at the same time but the documentation does not prohibit this as far as I know. So could this be a problem?

Thanks,

jh

    This topic has been closed for replies.

    6 replies

    Tesla DeLorean
    Guru
    January 27, 2017
    Posted on January 27, 2017 at 22:40

    Uses DMA1, UART8_TX Stream 0 Channel 5, UART8_RX Stream 6 Channel 5

    You have to program the DMA controller to initiate any transfer. RX could be in circular mode, interrupting via the DMA HT/TC interrupts.

    RX and TX can occur concurrently. You'd need to make sure buffers are not transient (local/auto), and one TX completes before starting another.

    What are you looking for? Code that demonstrates DMA functionality? Using what pins?

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    John Hite
    John HiteAuthor
    Associate III
    January 28, 2017
    Posted on January 28, 2017 at 18:31

    Thanks for the post. 

    Yes, I would definitely like some good DMA/UART example code. The pins are UART8, PE0 & PE1.

    Thanks,

    jh

    Tesla DeLorean
    Guru
    January 31, 2017
    Posted on January 31, 2017 at 20:22

    Quick blind UART8 TX example

    // STM32 UART8 DMA TX (Tx PE.1, Rx PE.0) STM32F437 - sourcer32@gmail.com
    #include 'stm32f4xx.h'
    /**************************************************************************************/
    void RCC_Configuration(void)
    {
     /* --------------------------- System Clocks Configuration -----------------*/
     /* UART8 clock enable */
     RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART8, ENABLE);
     /* GPIOE clock enable */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
     /* DMA1 clock enable */
     RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1, ENABLE);
    }
    /**************************************************************************************/
    void GPIO_Configuration(void)
    {
     GPIO_InitTypeDef GPIO_InitStructure;
     /*-------------------------- GPIO Configuration ----------------------------*/
     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
     GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
     GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
     GPIO_Init(GPIOE, &GPIO_InitStructure);
     /* Connect USART pins to AF */
     GPIO_PinAFConfig(GPIOE, GPIO_PinSource0, GPIO_AF_UART8); // UART8_R
    X GPIO_PinAFConfig(GPIOE, GPIO_PinSource1, GPIO_AF_UART8); // UART8_T
    X}
    /**************************************************************************************/
    void UART8_Configuration(void)
    {
     USART_InitTypeDef USART_InitStructure;
     /* USARTx configuration ------------------------------------------------------*/
     /* USARTx configured as follow:
     - BaudRate = 115200 baud
     - Word Length = 8 Bits
     - One Stop Bit
     - No parity
     - Hardware flow control disabled (RTS and CTS signals)
     - Receive and transmit enabled
     */
     USART_InitStructure.USART_BaudRate = 115200;
     USART_InitStructure.USART_WordLength = USART_WordLength_8b;
     USART_InitStructure.USART_StopBits = USART_StopBits_1;
     USART_InitStructure.USART_Parity = USART_Parity_No;
     USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
     USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
     USART_Init(UART8, &USART_InitStructure);
     USART_Cmd(UART8, ENABLE);
    }
    /**************************************************************************************/
    char Buffer[] = 'The quick brown fox jumps over the lazy dog
    
    ';
    void DMA_Configuration(void)
    {
     DMA_InitTypeDef DMA_InitStructure;
     DMA_DeInit(DMA1_Stream0);
     DMA_InitStructure.DMA_Channel = DMA_Channel_5;
     DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral; // Transmit
     DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)Buffer;
     DMA_InitStructure.DMA_BufferSize = (uint16_t)sizeof(Buffer) - 1;
     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&UART8->DR;
     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
     DMA_InitStructure.DMA_Priority = DMA_Priority_High;
     DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Enable;
     DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
     DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single;
     DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;
     DMA_Init(DMA1_Stream0, &DMA_InitStructure);
     /* Enable the USART Tx DMA request */
     USART_DMACmd(UART8, USART_DMAReq_Tx, ENABLE);
     /* Enable DMA Stream Transfer Complete interrupt */
     DMA_ITConfig(DMA1_Stream0, DMA_IT_TC, ENABLE);
     /* Enable the DMA RX Stream */
     DMA_Cmd(DMA1_Stream0, ENABLE);
    }
    /**************************************************************************************/
    void DMA1_Stream0_IRQHandler(void)
    {
     /* Test on DMA Stream Transfer Complete interrupt */
     if (DMA_GetITStatus(DMA1_Stream0, DMA_IT_TCIF0))
     {
     /* Clear DMA Stream Transfer Complete interrupt pending bit */
     DMA_ClearITPendingBit(DMA1_Stream0, DMA_IT_TCIF0);
     }
    }
    /**************************************************************************************/
    void NVIC_Configuration(void)
    {
     NVIC_InitTypeDef NVIC_InitStructure;
     /* Configure the Priority Group to 2 bits */
     NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
     /* Enable the UART8 TX DMA Interrupt */
     NVIC_InitStructure.NVIC_IRQChannel = DMA1_Stream0_IRQn;
     NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
     NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
     NVIC_Init(&NVIC_InitStructure);
    }
    /**************************************************************************************/
    int main(void)
    {
     RCC_Configuration();
     NVIC_Configuration();
     GPIO_Configuration();
     UART8_Configuration();
     DMA_Configuration();
     while(1); // Don't want to exit
    }
    /**************************************************************************************/
    #ifdef USE_FULL_ASSERT
    /**
     * @brief Reports the name of the source file and the source line number
     * where the assert_param error has occurred.
     * @param file: pointer to the source file name
     * @param line: assert_param error line source number
     * @retval None
     */
    void assert_failed(uint8_t* file, uint32_t line)
    {
     /* User can add his own implementation to report the file name and line number,
     ex: printf('Wrong parameters value: file %s on line %d
    
    ', file, line) */
     /* Infinite loop */
     while (1)
     {
     }
    }
    #endif
    /**************************************************************************************/
    �?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    yoann LBY
    Senior
    August 31, 2017
    Posted on August 31, 2017 at 11:45

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6t7&d=%2Fa%2F0X0000000bxM%2FCnTEAUdRJHMCZa6QsKuCjYJ10HCn0EnNs0WcnploPFQ&asPdf=false
    yoann LBY
    Senior
    October 9, 2017
    Posted on October 09, 2017 at 10:04

    The original post was too long to process during our migration. Please click on the provided URL to read the original post. https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I6tg&d=%2Fa%2F0X0000000bxa%2FGMOx4xc7fwiOSw_WqPTjrgSGtYTkI2CFGhNFoL1UmRw&asPdf=false