2019-08-26 04:11 AM
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 ??
Solved! Go to Solution.
2019-08-27 07:34 PM
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;
}
2019-08-26 04:31 AM
Since you presented no relevant code, and my Magic Crystal Ball is under repair, I make a guess.
You probably use Cube-generated code, call the PC output from the interrupt callback (i.e. in interrupt context), and cause a Rx overflow error in the GPS reception which you do not handle.
2019-08-26 06:26 AM
A pair of blocking functions in a loop are apt to drop data.
2019-08-26 11:32 AM
Hi Thanks,
This is my code
while(1)
{
HAL_UART_Receive(&huart2, (uint8_t *)UARTRxBuffer, 700,1000);
HAL_UART_Transmit(&huart3, (uint8_t *)UARTRxBuffer, strlen(UARTRxBuffer), 1000);
}
here uart2 is for GPS Data and uart3 is to transmit data to PC.
How to find Rx overflow is happening? and how do i handle it?
2019-08-26 11:36 AM
Hi Clive,
I understand blocking functions in a loop drop data but my GPS module sends every second. Even after transmitting i couldn't receive any data. Not even a single data!!
any other issues??
2019-08-26 11:44 AM
If the UART3 baudrate is same or higher than USART2, use the USART2 Receive interrupt method and in the callback simply send the received byte.
It's simple, not elegant, but it may get you moving on.
UART receiving by polling (blocking) is definitely simple and wrong = misleading.
2019-08-26 01:35 PM
Is there any good reason to assume that the UARTRxBuffer would have a properly formatted C string in it? Where does the NULL terminator come from? How about on the second call, what is in the buffer and where does the new NULL terminator come from?
What do the return status codes tell you?
What is in the buffer? Does it contain appropriate data for strlen to work properly?
What happens in the receive function the second time it is called? Which parts did you trace through, and which parts are being executed?
2019-08-26 02:12 PM
strlen() has a dependency on the string data being NUL terminated, GPS receivers don't send NUL bytes.
Assuming same rates, otherwise use ring-buffers
#ifdef USART_CR1_TXEIE_TXFNFIE // FIFO Support
#define USART_CR1_RXNEIE USART_CR1_RXNEIE_RXFNEIE
#define USART_CR1_TXEIE USART_CR1_TXEIE_TXFNFIE
#define USART_ISR_RXNE USART_ISR_RXNE_RXFNE
#define USART_ISR_TXE USART_ISR_TXE_TXFNF
#endif
void Forward(void)
{
while(1)
{
if((USART2->ISR & USART_ISR_RXNE) == 0) // Wait for Char
{
if (USART2->ISR & USART_ISR_ORE) // Overrun Error
USART2->ICR = USART_ICR_ORECF;
if (USART2->ISR & USART_ISR_NE) // Noise Error
USART2->ICR = USART_ICR_NCF;
if (USART2->ISR & USART_ISR_FE) // Framing Error
USART2->ICR = USART_ICR_FECF;
}
else
{
uint8_t Data = USART2->RDR; // Read Char;
while((USART3->ISR & USART_ISR_TXE) == 0);
USART3->TDR = Data; // Send Char
}
if((USART3->ISR & USART_ISR_RXNE) == 0) // Wait for Char
{
if (USART3->ISR & USART_ISR_ORE) // Overrun Error
USART3->ICR = USART_ICR_ORECF;
if (USART3->ISR & USART_ISR_NE) // Noise Error
USART3->ICR = USART_ICR_NCF;
if (USART3->ISR & USART_ISR_FE) // Framing Error
USART3->ICR = USART_ICR_FECF;
}
else
{
uint8_t Data = USART3->RDR; // Read Char
while((USART2->ISR & USART_ISR_TXE) == 0);
USART2->TDR = Data; // Send Char
}
}
}
2019-08-26 09:53 PM
Hi Clive,
Thanks
I used this USART2->ICR = USART_ICR_ORECF; to clear the overrun.Now i can get the data continuously.But issue is i'm missing more data inbetween.
How do i reduce the occurrence of overrun or is there any way to increase the buffer size ??
2019-08-26 09:55 PM
Thanks Ozone(O3),
I can get data continuously but i'm missing more data in mean time.is there any way to increase the buffer ??