AnsweredAssumed Answered

USART1 RX + DMA - stm32f030 issue

Question asked by Thomas on Dec 19, 2016

Hello,

 

I have an issue using the UART RX with DMA on my stm32f030k6t6...

The microcontroller reacts exactly like the DMA was not correctly initialized.

 

I'm using USART1 at PA10 (RX), and DMA1 channel 3. Here is the code for the GPIO, USART, DMA, and the polling function:

---------------------

#define UARTx                           USART1

#define UART_R_BUFFER       20
uint8_t bytRBuff[UART_R_BUFFER];


void UART_PinsInit(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;

 

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_Level_3;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOA, &GPIO_InitStructure);                 //
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1); //
}


void UART_Conf(void)       // Configuration for MIDI communication
{
    USART_InitTypeDef USART_InitStructure;

    UART_PinsInit();

 

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

 

    UARTx->CR1 &= ~USART_CR1_OVER8;
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;
    USART_InitStructure.USART_StopBits = USART_StopBits_1;
    USART_InitStructure.USART_Parity = USART_Parity_No;
    USART_InitStructure.USART_BaudRate = 31250;
    USART_InitStructure.USART_HardwareFlowControl = DISABLE;
    USART_Init(UARTx, &USART_InitStructure);

 

    UARTx->CR1 &= ~USART_CR1_RE;

 

    UARTx->CR1 |= USART_CR1_UE;             // Enable USART1

 

    UARTx->CR3 |= USART_CR3_DMAR;

    UART_InitDMA();

 

    UARTx->CR1 |= USART_CR1_RE;

}


void UART_InitDMA(void)
{
///////////////////////////////// With DMA1 Channel 3 for RX /////////////////////////////////
    DMA1_Channel3->CCR &= 0xFFFF8000;                         // Initializes CCR Register

 

    DMA1_Channel3->CCR |= 0b10 << 12;                         // High Priority Channel
    DMA1_Channel3->CCR |= 0b00 << 10;                         // 8-bits Memory Size
    DMA1_Channel3->CCR |= 0b00 << 8;                         // 8-bits Peripheral Size
    DMA1_Channel3->CCR |= DMA_CCR_MINC;                        // Memory Auto-Increment
    DMA1_Channel3->CCR &= ~DMA_CCR_CIRC;                    // No Circular Mode
    DMA1_Channel3->CCR &= ~DMA_CCR_DIR;                        // Read from Peripheral to Memory

 

    DMA1_Channel3->CNDTR &= 0xFFFF0000;                     //
    DMA1_Channel3->CNDTR |= UART_R_BUFFER;                     // Size of buffer

 

    DMA1_Channel3->CPAR = (uint32_t) &(USART1->RDR);         // Address for ADC_CDR
    DMA1_Channel3->CMAR = (uint32_t) bytRBuff;                 // Initial Address for Memory

 

    DMA1_Channel3->CCR |= DMA_CCR_EN;                         // Channel Enable
}

-----------------------------

 

And here is the polling function I'm calling in main() :

 

----------------------
        if ((DMA1_Channel3->CNDTR & 0x0000FFFF) < UART_R_BUFFER)        //
        {
            PWM_Laser(5); // Testing function
            for (var_i = 0 ; var_i < (UART_R_BUFFER - (DMA1_Channel3->CNDTR & 0x0000FFFF)) ; var_i ++)
            {
                // [.... Code to execute for each message received.... ]
            }
            UARTx->CR1 &= ~USART_CR1_RE;             ///////////////
            DMA1_Channel3->CCR &= ~DMA_CCR_EN;
            DMA1_Channel3->CNDTR &= 0xFFFF0000;                     //
            DMA1_Channel3->CNDTR |= UART_R_BUFFER;            //
            DMA1_Channel3->CCR |= DMA_CCR_EN;
            UARTx->CR1 |= USART_CR1_RE;             ///////////////
        }

 

-----------

 

So, the problem is that I "receive" something (the test function triggers) each time, And I can't receive the messages I'm sending to the CPU... When I disable DMA and I poll with RXNE bit, the system is working correctly (so this is not due to noise.. Plus I have controlled the signal on a scope, and nothing is wrong, no noise at all).

This is doing exactly  as if DMA1_Channel3->CNDTR was not correctly initialized...

My program is very simple, there are no other functions except this and PWMs, so nothing else is using DMA.

 

And the weird thing is that I'm using the same code on my stm32f303vct6 (I just change DMA / channel / pin / AF..), and I have no problem.

 

Plus another problem.. (a bit different) But I'm asking here just in case. When I optimize my system on speed  (O-Fast), on Atollic, a PWM function  with timer 17 is not working anymore.

 

Thank you!

Outcomes