UART DMA receive + FIFO: is it possible?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
MultipleMono
Level 1
Level 1
25 sign-ins 10 sign-ins 5 questions asked

Hi! I'm looking at ways to implement "infinite-length" reception for a UART port, where the port receives bytes at a high baudrate for potentially infinite duration.  I can't just use a regular UART app in DAVE set to DMA mode, as this has a limit of 4095 bytes for the longest possible DMA operation.  I did find this post about implementing multi-block DMA transfers, and this seems like it could accomplish what I need if I create a large "ring buffer" of DMA blocks that executes forever.  However, it's only possible to have two multi-block DMA transfers operating at a time, which is a disadvantage for my application, and also this is not implemented in DAVE so I'd have to do a lot of dev work myself.

What I'm wondering is, is it possible to make it so that a "regular" UART DMA is safe to pause and resume?  Looking at the current DAVE UART DMA generated code, it does not use the USIC module's FIFO; it sets the DMA to read the RBUF register directly:

 

XMC_DMA_CH_SetSourceAddress(ptr_gpdma, ptr_dma_config->dma_channel, (uint32_t)&(handle->channel->RBUF));

 

This means that if the DMA is stopped, there is only a 2 byte buffer in the USIC, and once those 2 bytes are filled data will be lost.  Therefore, it is not safe to pause the DMA for any significant length of time.  What I'm wondering is, how hard would it be to use the DMA with the RXFIFO?  If we could enable the FIFO, then it would have up to a 32 byte buffer, so you could stop the DMA for longer while you did other stuff. 

I tried to do this in DAVE, but the option to use the FIFO is greyed out while DMA is enabled.  Could one do this in code just by enabling the RXFIFO and changing the DMA to read from OUTR instead of RBUF?  Or is there a deeper reason why RXFIFO plus UART DMA receive is not a supported configuration?  Please let me know if anyone has some insight into this (or if there's a simpler way to do this that I'm missing).  Thanks!

0 Likes
1 Solution

Hi @MultipleMono ,

With your use case, you should configure the DMA for Multi block transfer with source address Auto reloaded and contiguous destination address. 

When the UART FIFO buffer is full, this will trigger a block transfer to the destination address. The destination address is increment automatically by the GPDMA to allow the next block of data to be filled. Once the number of blocks had been transferred, this shall then trigger the DMA interrupt which we can use it to restart another new round of DMA transfer. You can read about Auto Reload method in detail here.

Best Regards,

Aashita

View solution in original post

0 Likes
3 Replies
ncbs
Moderator
Moderator
Moderator
500 replies posted 50 likes received 250 sign-ins

Hi @MultipleMono,

On which device/kit are you aiming to implement the UART DMA receive + FIFO functionality?

If possible, do share the DAVE project here so that we can have a closer insight into the implementation attempted at your end.

Regards,
Nikhil

0 Likes

Oh yeah, this is on XMC4700.  I haven't really written any code for this specific application yet (though I do have some other projects that use regular UART DMA).  I was more just curious about general ways that one could implement an infinite-length UART receive of the nature I described.  Let me know if you need any more details about my application!

0 Likes

Hi @MultipleMono ,

With your use case, you should configure the DMA for Multi block transfer with source address Auto reloaded and contiguous destination address. 

When the UART FIFO buffer is full, this will trigger a block transfer to the destination address. The destination address is increment automatically by the GPDMA to allow the next block of data to be filled. Once the number of blocks had been transferred, this shall then trigger the DMA interrupt which we can use it to restart another new round of DMA transfer. You can read about Auto Reload method in detail here.

Best Regards,

Aashita

0 Likes