2024-06-28 07:19 AM - last edited on 2024-06-28 09:34 AM by SofLit
Hi, I am using STM 32 STLINK-V3. Thereis a problem with following UART receiver function.
__HAL_UART_CLEAR_FLAG(&huart5, UART_CLEAR_NEF|UART_CLEAR_OREF);
HAL_UART_Receive(&huart5, rx_buffer, ROVER_MSG_LEN, 1000);
__HAL_UART_DISABLE_IT(&huart5,UART_IT_RXNE);
. Without clearing the flag rx_buffer remains empty even though there is a data observed from hardware with oscilloscope. I stept into the function and see flag remains up constantly but now only varying few initial bits of the buffer gets the data still rest remians empty. Is this a bug does any one knows ?
2024-06-28 07:28 AM - edited 2024-06-28 07:29 AM
Please give details of your hardware setup:
@Kuttay wrote:there is a data observed from hardware with oscilloscope.
Show on your schematic where you observe that
There's been a lot of "UART can't receive" threads lately; eg,
2024-06-28 08:11 AM - edited 2024-06-28 08:32 AM
PSure, I am using two gnss which are ZED-FP9P-04B-01. They are connected to STM32H735IGKx and uart5 is used. I am attaching the pin diagram. This is how I tried to take the data as rx_buffer.
static void tcpsend_thread (void *arg)
{
MX_UART5_Init();
while (1)
{
TickType_t xLastWakeTime = xTaskGetTickCount();
//rx_buffer[1]=1;
//tcpsend(rx_buffer[1]);
osDelay(1000); //2000 or 5000
// Enter task section
//__disable_irq();
// UART reception
// __HAL_UART_ENABLE_IT(&huart5,UART_IT_RXNE); // Exit critical task section
// __HAL_UART_CLEAR_IT(&huart5, UART_CLEAR_NEF|UART_CLEAR_OREF);
// HAL_UARTEx_ReceiveToIdle_IT(&huart5, rx_buffer, ROVER_MSG_LEN);
__HAL_UART_CLEAR_FLAG(&huart5, UART_CLEAR_NEF|UART_CLEAR_OREF);
HAL_UART_Receive(&huart5, rx_buffer, ROVER_MSG_LEN, 10000);
// HAL_UART_Receive_IT(&huart5, rx_buffer, ROVER_MSG_LEN);
__HAL_UART_DISABLE_IT(&huart5,UART_IT_RXNE);
//ulTaskNotifyTake(pdTRUE , portMAX_DELAY);
if (g_rxSize <= 0)
continue;
//__HAL_UART_ENABLE_IT(&huart5,UART_IT_RXNE); // Exit critical task section
int i;
int j;
volatile int len_gpgga=0;
volatile int len_gpgst=0;
for(int x=1;x<ROVER_MSG_LEN; x++){
if(rx_buffer[x]==0x24){
len_gpgga=x;
for(int y=len_gpgga; y<ROVER_MSG_LEN;y++){
if(rx_buffer[y]==0xB5){
len_gpgst=y- len_gpgga;
break;
}
}
break;
}
}
for(i=0; i<ROVER_MSG_LEN; i++){
if (rx_buffer[i] == 0x24 && rx_buffer[i+1] == 0x47){
if (rx_buffer[i+3] == 0x47 && rx_buffer[i+4]== 0x47 ){
if(rx_buffer[i+5]== 0x41){
memcpy(&gpgga, &rx_buffer[i], len_gpgga);
gpgga[2]= 'P';
}
}
}
if (rx_buffer[i] == 0x24 && rx_buffer[i+1] == 0x47){
if (rx_buffer[i+3] == 0x47 && rx_buffer[i+4]== 0x53 ){
if(rx_buffer[i+5]== 0x54){
// Packet is valid, copy the data
memcpy(&gpgst, &rx_buffer[i], len_gpgst);
gpgst[2]= 'P';
}
}
}
if(rx_buffer[i] == 0xB5){
if(rx_buffer[i+1] == 0x62){
if(rx_buffer[i+2] == 0x01){
if(rx_buffer[i+3] == 0x3c){
if (rx_buffer[i+4] == 64){
uint8_t calculatedCK_A = 0;
uint8_t calculatedCK_B = 0;
for (j = i+2; j < i+72 - 2; j++)
{
calculatedCK_A += rx_buffer[j];
calculatedCK_B += calculatedCK_A;
}
if (calculatedCK_A == rx_buffer[i+72 - 2] && calculatedCK_B == rx_buffer[i+72 -1])
{
memcpy(&zedf9pData, &rx_buffer[i+6], sizeof(ZEDF9P_Data));
uint8_t message[100];
sprintf(message,"$GPHDT,%lu,T",zedf9pData.relPosHeading);
int crc = nmea_checksum(message);
sprintf(message+strlen(message),"*%X\r\n",crc);
sys_arch_sem_wait(&tcpsem, 500);
memset(rx_buffer, 0, sizeof(rx_buffer));
for (int e = 0; e<len_gpgst;e++){
merged[e] = gpgst[e];
}
for (int e = 0; e<300;e++){
merged[e+len_gpgst] = message[e];
}
if (gpgga[3]=='G'){
tcpsend(gpgga);
osDelay(200);
if (merged[3]=='G'){
tcpsend(merged);
osDelay(200);
}
}
memset(gpgga, 0, sizeof(gpgga));
memset(gpgst, 0, sizeof(gpgst));
memset(message, 0, sizeof(message));
break;
}
}
}
}
}
}
}
vTaskDelayUntil(&xLastWakeTime, 1000);
}
}
2024-06-28 08:19 AM - edited 2024-06-28 09:11 AM
Please show a schematic - #3 in the guidelines:
@Kuttay wrote:I am using two gnss which are ZED-FP9P-04B-01. They are connected to STM32H735IGKx and uart5 is used.
So how do you connect two GNSS units to one UART ?
The pin list doesn't show this (even if it were legible) - that's why you need to give a schematic.
2024-06-28 08:45 AM
>So how do you connect two GNSS units to one UART ?
THIS is a really good question... :)
How about: having two (expensive) GPS , giving EACH a serial / uart connection?
H735 has more than one uart - for free. :)
2024-06-28 09:04 AM - edited 2024-06-28 10:39 AM
The pin diagram isn't at a usable resolution.
This honestly is a mess, there are much better ways to do stream processing of data, especially NMEA/UBX streams from a GNSS Receiver.
The arbitrary buffer read from the serial is a problem, the content isn't likely to be aligned to your request, and the request blocks execution. Should really have some buffering via interrupt so the processing is not expected to occur within one byte's time.
Look at what HAL_UART_Receive() returns for an error/status code, and if it's not functioning check the UART register states to see why its not accepting new data that you can see on the wire.
Going off and doing TCP sends and delaying for 100's milliseconds is not conducive to catching continuous streams of data from a serial port in real time.
Would start by recommending using interrupts to acquire and queue/buffer received data, in its own thread/context, and then consume that data in this thread
2024-06-28 12:50 PM
See this project https://github.com/karlyamashita/Nucleo_G431RB_GNSS_12_Click/wiki
It'll queue each message using HAL_UART_Receive_IT by looking for the CR/LF. Then you can parse the messages in a polling routine. When you find the specific NMEA message, you can tokenize each parameter since you'll know what parameters there will be available. It also validates the checksum.
2024-06-28 08:44 PM
Can you connect the specified uart to a ttl to usb converter and see if it transmit to the specified uart5 pins. Use any terminal emulator on computer. Same say you can type in some characters and see if receive works. Receive is level sensitive.
2024-07-02 01:42 AM
One of them works as base while the other one is act as rover. These two gnss are connected to each other with uart2 but final data is taken from uart5. Taking these datas seperately breaks the rover base method and decrease the efficiency and increase the error rate of the taken data. I need nearly absolute data and the algorithm does that through uart 2.
2024-07-02 01:45 AM
Thanks I currently trying the method you recomment but still some bugs and errors occur. I am checking them. With HAL_UART_Receive I could only get one byte of data once. I believe it is because of a flag bug which I am working on.