Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DMA Rx Complete event split data output #8

Open
FPSUsername opened this issue Jan 30, 2020 · 4 comments
Open

DMA Rx Complete event split data output #8

FPSUsername opened this issue Jan 30, 2020 · 4 comments

Comments

@FPSUsername
Copy link

FPSUsername commented Jan 30, 2020

I adapted your code for my workspace and found an issue regarding the data length when the callback reaches a DMA Rx complete event.

The DMA_BUF_SIZE is 64 bytes and the incoming data is 5 bytes long.
Once the DMA buffer is filled, I see that the start position is 60 (so it received 12 messages already).

The problem now occures at:
length = DMA_BUF_SIZE - start;

This means that the length is set to 4 bytes. The next time it fires the callback it checks the remaining byte(s).

@FPSUsername
Copy link
Author

FPSUsername commented Jan 31, 2020

I solved the issue by expanding the struct with a data length memory and another flag (I called it the dma_flag).

If the DMA Rx Complete event happens, it sets the dma flag. Then it writes the first couple of bytes to the uart buffer. Finally it saves the current data length.
The next run it triggers, it sets the "i" variable with the saved data length. Now it will write the remaining byte(s) at the end of the uart buffer.

At the end of the callback function you can add a something like if (dma_uart_rx.dma_flag == 0) in order to trigger an action with the uart buffer (when it's completed)

@FPSUsername FPSUsername changed the title DMA Rx Complete event wrong data length DMA Rx Complete event split data output Jan 31, 2020
@akospasztor
Copy link
Owner

Hi,

first let me clarify your issue a bit ore in detail, because it's not entirely clear for me where lies the actual problem. So based on your first comment, the following happens:

  • Buffer size is 64 and there is a message consisting of 5 bytes that is received time to time.
  • 12 messages are already received, thus we have only 4 bytes remaining in the buffer.
  • The question is what happens when you receive the 13th message?

If yes, then the following happens: we have 4 empty bytes in the dma buffer, and 5 bytes are coming. Right after receiving the 4th byte, the DMA complete interrupt fires and calls the callback. In the meantime, we receive the remaining, 5th byte which is written by the dma peripheral into the very first byte of the array (overflow happened). The callback processes the incoming 4 bytes, then returns. After receiving the 5th byte, the transmission stops and after a timeout (described in README), the same callback is called again to process the remaining bytes that are overflown (in this case, only one byte).

This should work like this. Can you please elaborate more where lies your issue?

PS: when messages are arriving in a periodic way and data processing within a time bound becomes crucial, the buffer should consists of two parts and half-transfer interrupt should be utilized. Thus, the application can process safely the first part of the buffer while the dma writes new incoming data into the second half.

Best,
Akos

@FPSUsername
Copy link
Author

The problem I had is with the copying of the DMA buffer to the UART buffer. In this case, only the first 4 bytes of the 13th message were copied to the UART buffer (because of the DMA complete interrupt). Upon the next interrupt (timeout), the 5th byte is written in the UART buffer, at the wrong location (written at position 0 instead of 4). This is why I added a variable that keeps track of the data length so that I could use it as the starting point for the 5th byte.

In order not to trigger any further action (in my case, send the data over the CAN bus) with an incomplete UART buffer, I simply used the extra flag.

@akospasztor
Copy link
Owner

Ohh okay, now i get it. Yeah, you're right but this "issue" is rather how the data is being processed after the dma reception (and not the reception itself). Obviously, applications need appropriate and further data processing methods to correctly handle the data, depending on the needs. This is only a demo about the dma reception itself - it just flushes the received bytes (regardless of message re-construction or any byte handling) through the USB VCP :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants