Skip to main content
VPras
Associate III
August 26, 2019
Solved

why i couldn't receive continuous data of GPS over UART?

  • August 26, 2019
  • 22 replies
  • 3586 views

Hi,

I am trying to get the NMEA data over UART and print it over another uart .But when i try read in loop after writing data to PC ,I'm not receiving any data. what could be the issue?

any ideas ??

This topic has been closed for replies.
Best answer by Trevor Jones

I use this method,

never miss abyte, make your buffer 1024bytes at least,

uint32_t U1RxBufferPtrIN =0;
uint32_t U1RxBufferPtrOUT =0;
void initUart1RxDMABuffer(void) {
 if (HAL_UART_Receive_DMA(&huart1, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK)
 {
 sprintf(string, "initUart1RxDMABuffer Failed\n");
 puts1(string); 
 }
 else
 {
 sprintf(string, "initUart1RxDMABuffer OK!\n");
 puts1(string);
 }
}
char peekRxU1(int offset) {
 // offset of zero returns the next byte to be read
 int relativePtr = (U1RxBufferPtrOUT + offset) & (U1RxBufSize - 1); 
 char PeekRx = Usart1RxDMABuffer[relativePtr]; // just looking Don't increment pointer
return PeekRx;
}
char readU1(void) {
 char readByte = Usart1RxDMABuffer[U1RxBufferPtrOUT++];
 if (U1RxBufferPtrOUT >= U1RxBufSize) U1RxBufferPtrOUT = 0;
 return readByte;
}
char readableU1(void) {
 U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;
 return U1RxBufferPtrIN - U1RxBufferPtrOUT;
} 
void clearRxBuffer(void) {
 U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;
 U1RxBufferPtrOUT = U1RxBufferPtrIN;
}

22 replies

Trevor Jones
Trevor JonesBest answer
Senior
August 28, 2019

I use this method,

never miss abyte, make your buffer 1024bytes at least,

uint32_t U1RxBufferPtrIN =0;
uint32_t U1RxBufferPtrOUT =0;
void initUart1RxDMABuffer(void) {
 if (HAL_UART_Receive_DMA(&huart1, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK)
 {
 sprintf(string, "initUart1RxDMABuffer Failed\n");
 puts1(string); 
 }
 else
 {
 sprintf(string, "initUart1RxDMABuffer OK!\n");
 puts1(string);
 }
}
char peekRxU1(int offset) {
 // offset of zero returns the next byte to be read
 int relativePtr = (U1RxBufferPtrOUT + offset) & (U1RxBufSize - 1); 
 char PeekRx = Usart1RxDMABuffer[relativePtr]; // just looking Don't increment pointer
return PeekRx;
}
char readU1(void) {
 char readByte = Usart1RxDMABuffer[U1RxBufferPtrOUT++];
 if (U1RxBufferPtrOUT >= U1RxBufSize) U1RxBufferPtrOUT = 0;
 return readByte;
}
char readableU1(void) {
 U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;
 return U1RxBufferPtrIN - U1RxBufferPtrOUT;
} 
void clearRxBuffer(void) {
 U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;
 U1RxBufferPtrOUT = U1RxBufferPtrIN;
}

VPras
VPrasAuthor
Associate III
September 3, 2019

Thanks Trevor,

Now i can able to get seamless data .now i wanted to clear the Usart1RxDMABuffer once it gets full and start filling the new data to that buffer.

is that possible without reinitialize again??

Trevor Jones
Senior
September 3, 2019

just use this function to make the pointers the same

void clearRxBuffer(void) {

U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR;

U1RxBufferPtrOUT = U1RxBufferPtrIN;

}

then readable will return a zero, until a byte is received.

T J
Senior III
September 3, 2019

actually, you should never clear the buffer.. just keep reading bytes from the circular DMA buffer like this:

I use this to check a frame... initialise haveGPSstringbytes = false;

if( ! haveGPSstringbytes){
 int length = readableU1(); 
 if (length >= 2)
 {
 char firstByte = peekRxU1(0);
 char secondByte = peekRxU1(1);
 
 char readByte = readU1(); // read and dump byte if not start of frame
 
 if ((firstByte == '$') && (secondByte == 'G'))
 {
 GPSlength = 0;
 haveGPSstringbytes = true;
 GPSstring[GPSlength++] = readByte; 
 }
 } 
 }else{ 
 char readByte = readU1();
 GPSstring[GPSlength++] = readByte;
 
 //read in frame to end 
 // when you have a complete frame
 haveGPSstringbytes = false; //start new frame detector
 flagGPSFrameReceived = true;
 }

VPras
VPrasAuthor
Associate III
September 3, 2019

Thanks TJ,

code is working ,before i was using normal mode instead of circular mode.