cancel
Showing results for 
Search instead for 
Did you mean: 

HAL UART DMA RX - variable packet length & counter reset

Sergio Fabbrini
Associate II
Posted on April 05, 2017 at 12:48

Hello

I'm trying to read data from a GPS module that send packets with different lengths. I connected the rx line to another pin and enabled an interrupt on it, in this way I can 'timeout' the end of packet (packets are one per second, plenty of time between a pair).

I set-up DMA on UART (tried both circular and normal) because I don't need UART interrupt to read data. I would like to read data on timeout, but after the read I need to reset the state of DMA in order to empty the buffer and restart writing from index 0. I need to know the dat tranfered too.

I'm using an STM32F101 device with HAL library version 1.4.0.

No luck with examples from ST nor documentation around internet.

Thanks for your help.

Sergio

1 ACCEPTED SOLUTION

Accepted Solutions
Sergio Fabbrini
Associate II
Posted on April 10, 2017 at 14:37

Thanks for your reply.

First of all, I'm using a GPS module that send NMEA sentences, net binary one. They are array of chars to be received and parsed.

I'm pretty sure the interrupt timeout is working well, because I'm counting the number of times I enter the 'packetReady' function and is compatible with 1 pkt per second (running the serial at 38400baud I have a lot of spare time between two transmission).

UART in IRQ mode want to know the amount of data to be received, but I don't know it in advance. I tried to read the sentences one byte per time, but it's too complex. I set-up a circular DMA buffer and I can read from it.

The only thing I was not sure to do correctly is e reset of the buffer, but now it seems to work correctly. I'm using

   HAL_UART_DMAStop(&huart1);

right after the end of packet, then I precess the sentence and call

   if (HAL_UART_Receive_DMA(&huart1, (uint8_t *) dmaRxBuffer, 2048) != HAL_OK) {

      Error_Handler();

   }

again to start the DMA acquisition again. This seems to work, because DMA over-run error is not fired, so I assume the vector start from index 0 every time.

I think it should be simpler than that, but at least it works.

Thnk you all for your contribution.

Bye.

View solution in original post

6 REPLIES 6
Posted on April 05, 2017 at 16:44

GPS processing can be done quite effectively via a USART and IRQ.

If I was using DMA, I'd set up a circular buffer, interrupting on the HT and TC thresholds, have the array holding uint16_t data and marking the values I'd pulled by tagging a high order bit not set by the USART data (USARTx->DR is 16-bit wide). This way a periodic interrupt could the timeout, and determine buffer position.

Alternatively one might use the 1PPS from the GPS to trigger a one-shot timer to start processing where packet data would be complete.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
howard n2wx
Senior
Posted on April 05, 2017 at 21:54

Are the data NMEA formatted (with the leading '$')?

Posted on April 05, 2017 at 22:09

NMEA sentences yes, along with trailing <CR><LF> pairs, but binary packets like UBX or RTCM have neither.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Sergio Fabbrini
Associate II
Posted on April 10, 2017 at 14:37

Thanks for your reply.

First of all, I'm using a GPS module that send NMEA sentences, net binary one. They are array of chars to be received and parsed.

I'm pretty sure the interrupt timeout is working well, because I'm counting the number of times I enter the 'packetReady' function and is compatible with 1 pkt per second (running the serial at 38400baud I have a lot of spare time between two transmission).

UART in IRQ mode want to know the amount of data to be received, but I don't know it in advance. I tried to read the sentences one byte per time, but it's too complex. I set-up a circular DMA buffer and I can read from it.

The only thing I was not sure to do correctly is e reset of the buffer, but now it seems to work correctly. I'm using

   HAL_UART_DMAStop(&huart1);

right after the end of packet, then I precess the sentence and call

   if (HAL_UART_Receive_DMA(&huart1, (uint8_t *) dmaRxBuffer, 2048) != HAL_OK) {

      Error_Handler();

   }

again to start the DMA acquisition again. This seems to work, because DMA over-run error is not fired, so I assume the vector start from index 0 every time.

I think it should be simpler than that, but at least it works.

Thnk you all for your contribution.

Bye.

Posted on June 20, 2017 at 16:31

can you help me to implement gps on stm32f103 please

Salih
Associate

Hi,

I am Salih. This solution is great.

I have the same problem. Can you share the code with me to help? the size of the data I receive is uncertain and I need to read it in the array.

Thanks.