2021-06-23 3:22 AM
I am continuously calling HAL_UART_Receive_IT(), until i get some specified value in receiver buffer. But after some time HAL_UART_Receive_IT() return BUSY and after that it is not receiving any further interrupts and seems like the code is dead.
How can i get out of from BUSY state and receive further interrupts.
Please help me..
Thanks,
Jestina
2021-06-23 6:03 AM
HAL_BUSY indicates it's already busy doing something, in this case most likely waiting for bytes.
You can abort the transfer and try again if you want, but that should not be needed.
There are examples to follow in the relevant Cube repository for your chip.
2021-06-24 12:58 AM
void handleData(void)
{
int j;
if(resp == 0)
{
for(j =0; j <80; j++)
{
Serial_PutByte(status[j]);
if((status[j]== 'P' ) && (status[j+1]== 'L' ) && (status[j+2]== 'L' ) && (status[j+3]== 'R' ) && (status[j+4]== '1' ))
{
resp = 1;
}
}
}
}
void HAL_UART_AbortCpltCallback(UART_HandleTypeDef *huart)
{
Serial_PutString("ABORT COMPLETED");
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
handleData();
if(resp == 0)
{
if(HAL_UART_Receive_IT(&huart2, (uint8_t*)status, 80)==HAL_BUSY){
Serial_PutString("BUSY");
HAL_UART_AbortReceive_IT(&huart2);
}
__HAL_UART_ENABLE_IT(&huart2,UART_IT_RXNE );
HAL_UART_Receive_IT(&huart2, (uint8_t*)status, 80);
}
}
I am expecting "PLLR1" in my received data and if its not in the received value, I will continue reading data by pressing RESET key of my modem. I will continue pressing RESET, until i get "PLLR1".
At some point of time, i got a huge data ( that is more than 80 char..which i am reading), i am getting into
if(HAL_UART_Receive_IT(&huart2, (uint8_t*)status, 80)==HAL_BUSY) state. After that i am not able to receive any more data. I think overrun occurs here.
So i called HAL_UART_AbortReceive_IT() and i am getting the print from HAL_UART_AbortCpltCallback(); that is "ABORT COMPLETED".
After that i am enabling interrupt again and calling HAL_UART_Receive_IT(). But i am not able to receive any byte further.
Can you please tell how to get out from this scenario...That is... if some huge data comes which i am not reading ..after that also i am able to receive interrupts..
That is to overcome overrun scenario..
Please help me by giving a solution...Thanks in advance...
Thanks,
Jestina
2021-06-24 2:13 AM
You have set HAL_UART_Receive_IT(&huart2, (uint8_t*)status, 80); to interrupt when you receive exactly 80 bytes. So until you receive 80 bytes, HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) callback won't get called.
If you're only going to receive "PLLR1" and no other text, then write it to interrupt for 5 bytes. HAL_UART_Receive_IT(&huart2, (uint8_t*)status, 5);
If you're expecting other length of text then ideally the device that is sending text should send a Carriage Return so you know it is the end of the string.
I actually have a library for a character ring buffer but I modified it to make it a universal uart character ring buffer so that it works for STM32, TI's TM4C and Microblaze. I just verified it works for all 3 types. I'll have to make a video tutorial setting up a uart ring buffer after I finish another tutorial.
Edit: actually using strncmp() is better strncmp(&message, "PLLR1", 5);
2021-06-24 2:31 AM
Thanks for the response.
I am getting 2 types of responses from my device.. log1 and log.
I am expecting log1.txt which contains "PLLR1", which i will get if i receive 80 characters. If log1 is coming everything is working fine.
But sometimes i will get log.txt which is very big and i am receiving only 80 characters . Device is sending huge data and i am reading only 80 chars. I think at that time overrun scenario occurs and HAL_UART_Receive_IT(&huart2, (uint8_t*)status, 80)==HAL_BUSY.
After this STM32 will not respond to any interrupts and not able to receive a single data. Inorder to get out from this scenario, I called HAL_UART_AbortReceive_IT(&huart2); I think Abort is working and it is calling HAL_UART_AbortCpltCallback().
Still after this also i am not able to receive any interrupt...That is my scenario.
My requirement is: if i get into overrun scenario, how can i clear that receive further interrupts.
Thanks,
Jestina
2021-06-24 2:31 AM
2021-06-24 5:10 AM
One of the things i've noticed, but i'm not 100% sure, is that you're handling the data within the interrupt even when calling handleData(). You should save the data to a buffer and then handle the data from a polling routine outside of the interrupt HAL_UART_RxCpltCallback().
You should use the DMA so that the DMA controller will handle the saving of the uart data to your status array so the uC can process the previous data you saved in a ring buffer.
Now that i see it is a text file, each line can be saved as a message in a ring buffer by looking for a "\r\n" characters. So as the DMA is working on filling the 80 characters in the status array, you can be polling and parsing the message buffer. I think using strstr() library to look for "PLLR1" in the buffer would work. If it returns Null then it didn't find "PLLR1". The uC can process the messages faster than the DMA can fill the status array and interrupt.
I'll take your text files and work with it with my library. Other than looking for "PLLR1" and setting resp = 1, are you doing anything with the rest of the text?
2021-06-24 5:54 AM
I am doing nothing with the rest of the text
2021-06-24 4:45 PM
I have taken one of my past projects and added some code to look for "PLLR1". I had a little issue at first of it not interrupting after awhile but I was able to make some changes. It seems to work just fine now. I haven't had it not interrupt after sending log.txt with the large amount of text. For Log1.txt, I can parse and indicate the text "PLLR1" has been found. I've uploaded the project to github. You'll of course need to port the code over to your project.
https://github.com/karlyamashita/STM32ParseTextFile
Let me know how it works out or if there are any issues.
2021-06-25 5:34 AM
Hi Karl,
Thanks for your great support.
Your assumption was correct. My issue was related to the handling the data within the interrupt. Now i am handling the data from a polling routine outside of the HAL_UART_RxCpltCallback(). I am able to find out "PLLR1" easily. The BUSY status for HAL_UART_Receive_IT() has also gone. Now my code is working fine for my requirement.
These changes i have made as per your explanation. Once again thank you very much for your support.
Thanks,
Jestina