Search code examples
stm32uartdma

Triggering Interrupt for any byte received


I'm trying to get a code to work that triggers an interrupt for a variable data size coming to a RX input of a STM32 board (not discovery) in DMA Circular mode. ex.:CONNECTED\r\nDATAREQUEST\r\n

So far so good, I'm being able to receive data and all, while also triggering the DMA interrupt.

I will then create a sub RX message processing buffer breaking down each \r\n to a different char array pointer.

msgProcessingBuffer[0] = "COM_OK"

msgProcessingBuffer[1] = "DATAREQUEST"

msgProcessingBuffer[n] = "BlahBlahBlah"

My problem comes actually from the trigger of the interrupt. I would like to trigger the interrupt from any amount of data and processing any data received.

If I use the interrupt request bellow:

HAL_UART_Receive_DMA(&huart1,uart1RxMsgBuffer, 30);

The input buffer will take 30 bytes to trigger the interrupt, but that's too much time to wait because I would like to process the RX data as soon as a \r\n is found in the string. So I cannot wait for the full buffer to fill to begin processing it.

If I use the interrupt request bellow:

HAL_UART_Receive_DMA(&huart1,uart1RxMsgBuffer, 1;

It will trigger as I want, but there is no point on using DMA in this case because it will trigger the interrupt for every byte and will create a buffer of just 1 byte (duh) just like in "polling mode".

So my question is, how do I trigger the DMA for the first byte received but still receive/process all data that might come after it in a single interrupt? I believe I might be missing some basic concept here.

Best regards, Blukrr


Solution

  • I was taking a look at some other forums and I've found there a work around for this problem.

    I'm using a DMA in circular mode and then I monitor the NDTR which updates its value every time a byte is received through the UART interface. Then I cyclically call a function (in while 1 loop or in a cyclic interrupt handler) that break down each message part always looking for /n /r chars. This function also saves the current NDTR value for comparison if it has changed since the last "while 1" cycle. If the NDTR has changed since last cycle I wait a couple milliseconds to receive the remaining message (UART it's too slow to transmit) and then save those received messages in a char buffer array for post processing.

    If you create a circular DMA buffer of about 50 bytes (HAL_UART_Receive_DMA(&huart1,uart1RxMsgBuffer, 50)) I think it's enough to compensate any fluctuations in the program cycle.