AnsweredAssumed Answered

DMA reads data from DR register even with RXNE cleared. Why?

Question asked by Ferreira on Nov 20, 2012
Latest reply on Dec 7, 2012 by Ferreira
Hi,

I have the following Usart interrupt request handler: (simplified version, but has all the necessary information)



void USART1_IRQHandler(void)
{
  if(USART_GetITStatus(COM1_PC, USART_IT_RXNE) != RESET)
  {
    data = (USART_ReceiveData(COM1_PC) & 0xfF);

    if (data == DATA_READ)
    {
    
       //Disable the Usart interrupt request because from this point,
       //I want to use the DMA to store the incoming data at a specified address!
       USART_ITConfig(COM1_PC, USART_IT_RXNE, DISABLE);
      
       //make sure that the DMA is not transferring any data before configuring it with new parameters
       while (DMA_GetCmdStatus(RS232_DMA_RX_STREAM) != DISABLE)
       {
       }

       //Configure the DMA to store usNumOfBytes bytes to memory, starting at address pStartAddress

       RS232_DMA_RX_STREAM->NDTR = usNumOfbytes;
       RS232_DMA_RX_STREAM->M0AR = (uint32_t)pStartAddress;

       //Clear some flags before enable the DMA
       DMA_ClearFlag(RS232_DMA_RX_STREAM, RS232_RX_DMA_FLAG_HTIF | RS232_RX_DMA_FLAG_TCIF);

       /* Enable DMA Stream Transfer Complete interrupt */
       DMA_ITConfig(RS232_DMA_RX_STREAM, DMA_IT_TC, ENABLE);

      //Only for debugging to make sure that it no data has been stored until now!
      RXcounter=DMA_GetCurrDataCounter(RS232_DMA_RX_STREAM);
      
      //make sure that the RXNE bit is cleared before activating the DMA
      while(USART_GetITStatus(COM1_PC, USART_IT_RXNE) != RESET);

      //Activate the DMA
      DMA_Cmd(RS232_DMA_RX_STREAM, ENABLE);

     //only for debugging, but at this point the DMA, has read the old data stored in the DR register, and RXcounter is equal to usNumOfbytes - 1!
     RXcounter=DMA_GetCurrDataCounter(RS232_DMA_RX_STREAM);
   }
  }
}

With this interrupt handler I want to implement the following:
Whenever it receives a DATA_READ command, it should:
-Disable the USART RX interrupt request;
-Configure the DMA to read data coming from a host PC via RS232 and store it at the specified address.
-Enable the DMA for that propose.

Surprisingly (for me), the DMA stores the old received data at the specified address, as soon as, it is enabled. Even with the RXNE bit cleared.

But, on page 786 of the reference manual RM0008 (Doc ID 13902 Rev 14), subtitle "Reception using DMA", it states that "The data will be loaded from USART_DR to this memory area after each
RXNE event."
So, I would like to know, what really forces the DMA to read data from the DR register to the specified memory!
It doesn't seems that it is the RXNE event, because this bit is cleared by reading data from the DR register, and I have forced to make sure that this bit was cleared before enabling the DMA.

Thank you all for any help,

Best regards,

A. Paiva

Outcomes