2023-10-06 09:45 AM
I am encountering an issue with UART receiving interrupt, where it intermittently stops receiving data after a series of AT commands have been sent to a GSM modem. The UART communication is configured to use DMA for data transfer, and we have assigned the appropriate DMA channels.
Following is the code: On initialization:
MX_USART1_UART_Init(); //UART Initialization
HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RX_Buffer1, 50); //Enable Interrupt
The below is the code for transmitting AT commands:
memset(RX_Buffer1,0,sizeof(RX_Buffer1)); //Clearing the receive buffer
memset(ATcommand,0,sizeof(ATcommand)); // clearing the transmit buffer
sprintf(ATcommand,transmit_commands[AT_command_number]); //Get command from the command array
HAL_UART_Transmit(&huart1,(uint8_t *)ATcommand,strlen(ATcommand),1000); // UART Transmit
HAL_Delay(300); ///Delay 300 msec
The issue manifests as the UART interrupt ceasing to function properly after sending a certain number of AT commands. The interrupt is designed to process the responses received from the GSM modem and trigger further actions based on those responses. However, after executing the "AT+CCLK?" command for the second time, the interrupt stops functioning.
Restarting the device by deinitializing and initializing the UART resolves the problem temporarily. However, this is not a practical solution, as we cannot reset the UART after every transmit operation.
Kindly refer to the provided log that details the sequence of AT commands transmitted and the accompanying responses received. Within this log, you can observe a noticeable interruption in the functioning of the UART interrupt, which seems to be the core of the problem.
Any insights, guidance, or solutions from the community would be greatly appreciated.
2023-10-06 10:52 AM
The log doesn't provide any real detail on timing or when the failure occurs. Or peripheral state upon failure
Handler and callback not shown. Check for errors and status reported by USART. Things like overruns, etc.
Stop using blocking functions like HAL_USART_Transmit() or HAL_Delay(). The modem can respond at anytime. Would use interrupts to receive and buffer characters. Not DMA with idle timing.
2023-10-06 11:48 AM
Do you have a HAL_UART_ErrorCallback() function? Any UART error (like @Tesla DeLorean mentioned) will abort the receive function and not call the normal "receive complete" callback.
As an aside: prefer to use snprintf() instead of sprintf() to avoid possibility of buffer overruns. Likewise strncpy() instead of strcpy() [not that you used that in the code you posted]. And you have a hard-coded "50" in the HAL_UART_ReceiveToIdle_DMA call, should be "sizeof(RXBuffer_1)". And is that buffer REALLY at least 50 bytes? The response to the AT+CCLK? command is close to that.
2023-10-06 08:19 PM
One mistake you've made is not check the HAL status when calling HAL_UARTEx_ReceiveToIdle_DMA
You haven't shown what you do in HAL_UARTEx_RxEventCallback so no telling how you're enabling interrupts again.