AnsweredAssumed Answered

Polling for Circular DMA completion and resetting to zero

Question asked by mccarty.michael on Mar 26, 2014
I refactored my interrupt based circular buffer into a dma RX stream coming from the USART2.

I frequently read how many bytes the dma stream has read and then reset it back to zero. For example.

DMA_Send("do command");
Delay(some time);
DMA_Count()
if (dmaCount == sizeof("ok"))
   //success
else
   // something went wrong

I hope you get the gist of what I do from the above pseudo code.

The thing is, can I poll the dma stream to know when it compleats instead of having a static delay. The delay does not work unless I have it for worst case scenario. For example the time to rx 1 byte is much less than the timeto rx 1000 bytes.

I'm confused with things like RXNE on the usart, and TC. I dont know which flags are good to read for the RX side and which apply to the TX side.

I've posted the two functions that do these sort of operations below, any suggestions ?

/**
  * @brief set dma buffer back to moar and set everything back to 0
  * @param  dmaBuff buffer to use
  * @note this will also update the internal count of the struct
  * @retval count of buffer
  */
int dmaBuffCount(DMABuffer *dmaBuff)
{
    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET){
        Delay(1);
    }
    dmaBuff->count = dmaBuff->size - dmaBuff->DMAStr->NDTR;
    return dmaBuff->count;
}
 
/**
  * @brief set dma buffer back to moar and set everything back to 0
  * @param  dmaBuff buffer to use
  * @retval None
  */
void dmaBuffFlush(DMABuffer *dmaBuff)
{
    // WAIT FOR RX TO FINISH
    while(USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET)
    {
        Delay(1);
    }
     
    DMA_Cmd(dmaBuff->DMAStr, DISABLE);
    // wait for it to become disabled
    while(DMA_GetCmdStatus(dmaBuff->DMAStr) != DISABLE)
    {
       Delay(1);
    }
    DMA_SetCurrDataCounter(dmaBuff->DMAStr, dmaBuff->size);
    dmaBuff->mark = 0;
    dmaBuff->count = 0;
    DMA_Cmd(dmaBuff->DMAStr, ENABLE);
    USART_DMACmd(USART2, USART_DMAReq_Tx, ENABLE);
    // wait for it to be enabled again
    while(DMA_GetCmdStatus(dmaBuff->DMAStr) != ENABLE)
    {
       Delay(1);
    }
 
}

Thanks !

Outcomes