Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

STM32 DMA Receive Uart | GPS Neo-7m Module

Status
Not open for further replies.

mettiblack72

Junior Member level 1
Junior Member level 1
Joined
Jun 4, 2018
Messages
19
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
150
Hello,
My MCU is Stm32f407vet6 and I run Ublox GPS Module Neo-6m with DMA ,
My Module is connected to USART2 of MCU , I received 140 Bytes of GPS data every 100ms and saved GPRMC data ,
All things is OK in normal operation, sometimes GPS module can't find satellites and send invalid data to MCU about 15 minutes or disconnect completely
when GPS module reconnect to satelite and send valid data again to mcu, In this case MCU can't recover again to receive gps data and I should reset MCU to operate !
can anyone help me ?
 

Hi,

without seeing your gode it´s like a look into a crystal ball ... wild guessing.

I guess it´s a problem of frame sync.

Klaus
 
Hi,

without seeing your gode it´s like a look into a crystal ball ... wild guessing.

I guess it´s a problem of frame sync.

Klaus
Hi , thank you for your reply

1) at the first variables
/* GPS Variables */
uint8_t GPSData_GPRMC[140] = {0};

2) and then initilization of peripherals
/* Initialize all configured peripherals */
MX_DMA_Init();
MX_USART2_UART_Init();

3) and then receive data from gps with dma
HAL_UART_Receive_DMA(&huart2, GPSData_GPRMC, sizeof(GPSData_GPRMC)); // Receive GPS Data with DMA
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, DMA_IT_HT) ; //Disable half transfer complete interrupt

4) after dma receive 140 bytes of gps, mcu go to this function
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART2)
{
GPSDataValidFlag = 1;
}
HAL_UART_Receive_DMA(&huart2, GPSData_GPRMC, sizeof(GPSData_GPRMC)); // Run DMA again
}

In this function we call receive gps data again
 

Hi,

my guess was right ...

if you ever receive any other count of message size than 140 you loose the sync

Example:
you expect:each message to have 5 bytes.
12345 12345 12345 12345
but if you get an (erroneous) message with just 3 bytes; 12345 12345 123 12345 12345
the the DMA output will be: 12345 12345 12312 34512 345...

If I´m not mistaken the STM32 provides a "UART_IDLE" interrupt (or similar naming) when it sees the bus to be idle for more than 8 bit lengths (maybe adjustable). Use this as synchronizer to stop DMA_receive (maybe dismiss the data) and start a new DMA_receive.

Generally it´s not very fault tolerant to expect the GPS and the STM to stay byte sync forever...

Klaus
 

My guess is that the GPS module outputs NMEA sentences which end with '\r\n' sequences.
I'd not use DMA for this but rather use an interrupt and get the ISR to check for the terminator after putting the characters into a ring buffer. On seeing the terminator, the ISR sets a (volatile) flag for the main loop to then parse the sentence.
If you get a 'corrupted' sentence then the ISR will still continue to work and you will still get the termination sequence (eventually) and the sentence parser (of which there are many examples) can handle it appropriately.
Susan
 

Hi,

my guess was right ...

if you ever receive any other count of message size than 140 you loose the sync

Example:
you expect:each message to have 5 bytes.
12345 12345 12345 12345
but if you get an (erroneous) message with just 3 bytes; 12345 12345 123 12345 12345
the the DMA output will be: 12345 12345 12312 34512 345...

If I´m not mistaken the STM32 provides a "UART_IDLE" interrupt (or similar naming) when it sees the bus to be idle for more than 8 bit lengths (maybe adjustable). Use this as synchronizer to stop DMA_receive (maybe dismiss the data) and start a new DMA_receive.

Generally it´s not very fault tolerant to expect the GPS and the STM to stay byte sync forever...

Klaus
thank you so much , I'll examine and report as soon as possible
--- Updated ---

My guess is that the GPS module outputs NMEA sentences which end with '\r\n' sequences.
I'd not use DMA for this but rather use an interrupt and get the ISR to check for the terminator after putting the characters into a ring buffer. On seeing the terminator, the ISR sets a (volatile) flag for the main loop to then parse the sentence.
If you get a 'corrupted' sentence then the ISR will still continue to work and you will still get the termination sequence (eventually) and the sentence parser (of which there are many examples) can handle it appropriately.
Susan
thank you for your reply
Yes GPS module outputs NMEA sentences, and I want to extract GPRMC sentences , It has lots of bytes of data that interrupts mcu again and again every second , this is reason that I use DMA
 
Last edited:

In that case you have another issue: if the GPS module outputs more than 1 NMEA sentence then you need to take the varying lengths of the sentences into account.

Let's beak the supposed problem with using an ISR down a bit.
Firstly you have a processor that can run at a system clock of 168MHz - not too bad for an MCU.

Looking at what an ISR needs to do for each character received, it must:
- save the current processor contact (1 hardware instruction)
- copy the character from the UART to the current ring buffer location
- check if the character is '\n' and set a flag (variable) if it is
- check to see if we are at the end of the ring buffer and reset the pointer if we are, or increment the pointer if not
- restore the processor context (1 hardware instruction)
With an MCU running at that speed that all takes less than a microsecond.

However let's assume that it takes (say) 25 microseconds to process each character. Also let's say there are 200 character in a sentence. That means you will need 5 milliseconds to input each sentence. (I'm exaggerating here to make a point.)

That is 0.5% of the processor time each second used for the input and it leaves you 99.5% of the processor to interpret the sentence.

Let's face it, if you can't process a sentence with that much of the processor available to you, then something is terribly wrong.

Of course, as we have seen, you can reduce the time taken for the input by at least one order of magnitude, possibly 2, which leaves you even more time for the sentence parsing and whatever else you need the MCU to do.

Bottom line: there is nothing wrong with using an ISR and you will save yourself a lot of trouble with trying to use DMA when the input string length can vary.

I suspect this is a case of 'premature optimisation' where you are trying to get around a problem (excessive time taken by the ISR) that doesn't actually exist.

Susan
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top