2017-04-11 05:50 PM
Hi All,
Which flag in the UART DMA can be checked to indicate that I received a new byte. I also would like to check the DMA of my UART while its receiving, and if I receive a special character say '\r',I want to start processing the received buffer and reset dma. I am using the HAL library. Is it possible to do something like RxQuarterCplt instead of HAL_UART_RxHalfCpltCallback?
Many thanks
2017-04-11 06:40 PM
No, but you could colour the buffer and check occasionally. ie USART reads as 16-bit half-word, high order bits zero, you mark the word(s) you've already taken.
Check the Address Pointer
2017-04-11 08:29 PM
The DMA controller has a register called NDTR. This register holds the outstanding transfer count.
If you set up a DMA transfer of 1000 bytes, NDTR will start at 1000 and get decremented on each transfer.
If you want to see if something came in, keep track of the value of NDTR, and poll it periodically to see if it has changed. It will also give you an idea of where in your buffer to look for \r characters.
Andrei
2017-04-11 08:48 PM
I do this with a recurring timer. The DMA RX buffer is circular and generates no interrupts. I poll NDTR every millisecond or so, compare NDTR to its previous value, and deal with any new bytes. Timing is not critical, so I use a software timer based on SysTick, but a TIM interrupt could do the same.
I would decouple the processing from the receiving. I always pass the bytes asynchronously to a simple state machine which reconstructs packets from the byte stream. In your case, this means accumulating bytes in a buffer until you see a line end (reset the buffer if it fills up), and then parsing the line. I would try to avoid doing this work in an ISR.
2017-04-11 11:52 PM
Thank you all for the ideas you've given.
Ill try continuously polling the NDTR and see if this can solve my problem. I'll be back in touch and see what worked for me.
2017-04-12 06:25 AM
I am polling the NDTR now with a freertos thread every 1ms and can see its value changing. Now i am if I am continuously transmitting (polling) different commands from the uart port, the connected device will transmit back different responses with various lengths and these all are terminated with \r. So if I
decouple the processing from the receiving how can I know that reply 1 belongs to command 1 and reply 2 belongs to command 2? the device might for example not respond for command 1 and respond for command 2. in such case, response from command 2 will be assumed as reponse to command 1. there is no way to tell, am I correct?. I was doing something trivial, which I would like to avoid, is after every transmission I wait using vtaskdelay before i process the buffer and that works just fine. But this is not ideal and no one likes delays even if they are non blocking. Vtaskdealy is a non blocking delay it allows other threads to run. So I like the idea of watching the NDTR but can not figure out a sensible way to make use of it.
2017-04-12 11:44 AM
You have now problem with the general application logic and this has nothing to do with the original subject.
What would you do if you would have only simple polled Tx, and then polled Rx, in a plain no-OS application, how would you handle the behaviour of the connected device?
JW
2017-04-12 11:53 AM
There is a
https://community.st.com/0D50X00009XkhAxSAJ
with reading NDTR and then reading from the buffer, namely, that - contrary to documentation - NDTR is decremented *before* the transfer happens. Now many users won't notice as there is usually enough program to do between reading NDTR and reading the actual data from memory, but in cases of high optimization this might bite. I know of no simple solution to this problem, as it involves latencies on the AHB/ABP bridge, arbitration within DMA and then latencies on the target AHB/memory.Also note that there are two distinct DMA implementations in the STM32s, a rather complex one in 'F2/'F4/'F7 and a simpler one in the rest, and they may behave slightly differently in this regard. My experience is with 'F4 only.
JW