2014-05-06 03:11 AM
Hi community,
I use the USART1 in STM32F100C4 to receive serial data in DMA mode. Because the data comes in packets with less than 16 bytes I start the DMA mode every time, when new data is expected. This works most of the time well. But in some cases, DMA is not new started, because data is not of interest and DMA reads only 16 bytes to the memory. then DMA stops the transfer. Next time data is expected, DMA is new started in the same manner like before: DMA_Cmd(DMAChannel_USART1_RX, DISABLE); DMAChannel_USART1_RX->CNDTR = 16; DMA_Cmd(DMAChannel_USART1_RX, ENABLE); But now immediatly after DMA is enabled, the last data in USART1_DR is read to the memory althougt RXNE is cleared! It seems, this undesirable data is only read after DMAChannel_USART1_RX->CNDTR has count to 0 in last DMA session and more data is unread received. A resolution to that problem is allmost when I restart DMA mode like above. But I prefer to know the reason for this problem rather I solve it in this kind. Thanks for your help, Best reards, Herbert #usart1-dma-rx2014-05-11 11:35 AM
> Two other members of the forum had seemingly similar problems: waclaweek.jan (8/16/12)You mean
[fixed ]Yes this appears to be an undocumented 'feature' - a borderline bug, if you ask me - of the DMA controller - an 'event latch' which won't get cleared by disabling the respective DMA stream.I reported this it through the ST support, but as I buy in the <1Mpcs cathegory I was ignored as expected.I worked it around by deliberately triggering it *before* enabling the DMA and ignoring the first transferred data. Nasty, but works.Can you please be more specific with your workaround?Thanks,Jan Waclawek2014-05-12 02:49 AM
Hello Jan,
yes, your error appeares with timer in DMA mode but is comparibel. A. Paiva but has exactly the same problem then I had. Like you said, it seems, that the DMA controller saves the event in an internal latch and this can't be cleared with disable of DMA. I have tried some work around without success before this solution: USART_DMAReq_Rx is disabled after each receive of a string. And then before awaiting a new string: USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE); // Enable usart1 DMA Rx request DMA_Cmd(DMAChannel_USART1_RX, DISABLE); DMAChannel_USART1_RX->CNDTR = RXBUFFSIZEU1; // refresh DMA counter DMA_Cmd(DMAChannel_USART1_RX, ENABLE); USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE); // Enable usart1 DMA Tx request This solution works! I have also reported the problem to ST support like you, but I made a greater mistake then you: < 1000 pcs ... I await a answer until now ;-). Greetings Herbert2014-05-12 03:19 AM
I assume you have enabled DMA before the snippet you posted (as you disable it explicitly in the 2nd line). So, in case there is a ''hanging'' DMA ''trigger'', it will perform the extra one transfer before you disable and re-initialize it again, isn't it?
JW2014-05-12 06:55 AM
Sorry Jan,
I forgot, before the snippet i send: USART1->CR1 |= USART_CR1_UE | USART_CR1_RE | USART_CR1_TE; // USART1 freigeben (RX, TX und UE) and after receiving of the answers: DMA_Cmd(DMAChannel_USART1_RX, DISABLE); // DMA-Transfer Empfang stoppen DMA_Cmd(DMAChannel_USART1_TX, DISABLE); // DMA-Transfer Senden stoppen With this configuration no undesirable characters land in my buffer. Greetings Herbert2014-05-12 08:44 AM
I made a couple of experiments, results summed up in the above [DEAD LINK /public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx?RootFolder=/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/How%20to%20clear%20pending%20DMA%20request]thread.
I don't know whether (and if so, how) it is pertinent to the case of USART. JW2014-05-12 10:36 AM
Hi Jan,
the errors (USART, Timer) seems to correspond. If I disable and enable the USART_DMAReq_Rx my error disappeares. If you disable and enable TIMx_DIER_CC1DE your error disappeares. In both cases DMA request enable is switched off/on. Ok, this should be the solution, but I wished ST would confirm that or tell us the correkt reason for it. Greetings Herbert2014-06-23 08:36 AM
Ok, this should be the solution, but I wished ST would confirm that or tell us the correkt reason for it.
The workaround that you have already suggested is correct: in fact you have to disable the DMA request on peripheral side. If there is a DMA request pending, it will be served as soon as the DMA is enabled. The pending DMA request is cleared if you reset the DMAR bit in the USART_CR3 register. In case of a timer, it will be the reset of CC1DE bit in TIM_DIER register. This is not a limitation, but it needs to be clarified. This will be done in the next release of . Thanks for reporting this case & sorry for answer's delay. Best Regards -Mayla-To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.