AnsweredAssumed Answered

Kinetis (K10) UART DMA rx error handling

Question asked by Jarkko Silvasti on Oct 20, 2015
Latest reply on Oct 20, 2015 by Jarkko Silvasti

I currently have UART(0) rx running with DMA (circular buffer which is processed from task by using CITER-register to check if new data has been received) and it works ok. I am really concerned what happens if framing error (FE) or parity error (PF) appears, how it can be recognized and recovered.

 

CPU manual (http://cache.freescale.com/files/microcontrollers/doc/ref_manual/K10P144M120SF3RM.pdf?fsrch=1&sr=4&pageNum=1) does not cover that situation at all. I found a couple of discussions which by the way does not relief my concerns at all.. Some where else has been also said that manual S1+D register reading operations cannot be used during DMA and it sounds logical after reading those topics.

https://community.freescale.com/thread/301651

https://community.freescale.com/thread/301031

 

I have also tested that UART error IRQ (BSD_INT_ID_UART0_ERR) can be used together with DMA (at least in overrun (OR) case works) but "suprisingly" the S1-register is empty when that UART error handler is serviced...

 

When the DMA irq really occurs other than INTHALF & INTMAJOR cases, it looks to appear at least from overrun (OR) (not documented anywhere) error does it occur also from FE & PF?

 

For me it looks like that one solution could be to use UART error IRQ and if that occurs then discard all the data from DMA ring-buffer collected so far because it cannot be known which byte(s) have had FE or PF error (and of course do not try to do S1+D reading just use error_IRQ as an indication) - I am afraid that even this requires some bubble gum to do it so that also the task processing the ring buffer receives the information early enough. If DMA irq occurs in every uart failure then that could be used instead because currently we are not using INTMAJOR nor INTHALF (still the UART error irq sounds to be more robust...)

 

This new continuous DMA transfer shall not give OR error even though other DMA channels have higher priority especially if UART rx FIFO is used? We are currently running with 460800 but planning to rise it to 921600, and if it (OR) somehow still happens can the DMA self recover the OR bit or not? If DMA cannot ack the OR situation and it is theoretically possible how in the earth you can notice it without reading S1-register, can you somehow pause the DMA (so that you can do S1+D) and then continue the DMA where it were so that it does not require new "initialization" meaning that acquisition starts from the beginning of the ring buffer...

 

 

Short history why I am concerned:

Previously we had a little a bit different DMA approach which resulted in losing some bytes here and there without any visible uart error - do not fully understand how this is possible because the missing byte was always the one which was suppose to come first when new DMA request was given (uart fifo was also in use)... Method was "single shot" DMA uart rx transfer (with only INTMAJOR_MASK in CSR) where the used protocol itself was parsed in DMA interrupt and parser told how many bytes should be read next and new DMA rx transfer was triggered. Maybe the problem was that DREQ bit was not set in CSR (instead we disabled the uart's RIE in the DMA interrupt but there is of course delay until IRQ is served) - I don't want to go back to old code to test this assumption.

- overall this approach looked non-optimal because it required a lot of irq-time to do operations so I decided to use DMA as it should be used and that resolved also the byte missing problems...

 

Based on my brief tests with old method it looks like that at least the overrun situation gives DMA irq ("HW_DMA1_IRQ" in case  of uart0 rx) even though the required byte count for DMA transfer completition is not fullfilled (citer != biter && citer != 0) -- this is completely undocumented feature but of course it makes sense because otherwise DMA operation would be jammed because OR prevents receiving more characters...

 

 

Overall I want to say that uart error handling while using DMA is not very well covered anywhere, not in CPU manuals (where it should be) and not here in the forums, basically the issue has been raised here but not any workaround has been presented (some/all example codes does handle errors at all). I already apologize if there is topic handling this issue, I just couldn't find it...

Outcomes