cancel
Showing results for 
Search instead for 
Did you mean: 

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

tecnico23
Associate II
Posted on November 20, 2012 at 17:15

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

#usart #dma #rxne
12 REPLIES 12
Posted on November 26, 2012 at 18:02

Perhaps

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Nickname12657_O
Associate III
Posted on November 27, 2012 at 16:04

Hi,

Just to check: is DMA configured like this?

DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

Cheers,

STOne-32
tecnico23
Associate II
Posted on December 07, 2012 at 13:24

Hi,

Sorry for my late reply.

Yes they are both configured with one byte data size.

Thank you very much,

A. Paiva