2021-09-04 11:28 AM
I've run into another hurdle I don't seem to be able to solve myself while trying to learn embedded STM32 programming. I have a simple test program that transmits characters over a UART with the RX and TX pins looped together and receives them using interrupts. When I transmit the data using HAL_UART_Transmit, I can process the received characters in my IRQHandler fine. But when I use HAL_UART_Transmit_IT, my IRQHandler puts 2 characters in my receive buffer for every character I transmit. I'm pretty sure this is because my IRQHandler is getting called for every character transmitted and every character received. You can see how I tried to only process received characters in my IRQHandler below but it hangs up after a few characters. Any ideas on what I'm doing wrong or any ideas on a better way to do this will be greatly appreciated.
Thanks
PS In the long run, I'd like to make this work with DMA and end the transfer using the character match interrupt. I've got that working on a STM32H7A3 Nucleo board but not on the STM32H7B3Discovery board that I need to use. So I'm working on this IT method for now.
initUART4();
uint8_t txBuffer[] = { "$PUBX,00*33\r\n" };
memset(rxBuffer, 0, sizeof(rxBuffer));
memset(gpsMessage, 0, sizeof(gpsMessage));
msgReceivedUART4 = false;
HAL_UART_Receive_IT(&uart4Handle, rxBuffer, 1);
HAL_UART_Transmit(&uart4Handle, txBuffer, sizeof(txBuffer), 2000); //This works
//HAL_UART_Transmit_IT(&uart4Handle, txBuffer, sizeof(txBuffer)); //This doesn't work
while (1)
{
//Do other stuff
if(msgReceivedUART4)
{
//process UART4msg
HAL_Delay(1);
}
}
}
void UART4_IRQHandler()
{
HAL_UART_IRQHandler(&uart4Handle);
// if (__HAL_UART_GET_FLAG(&uart4Handle, UART_FLAG_RXNE))
// {
if (rxBuffer[0] != 0)
{
gpsMessage[gpsMsgCount] = rxBuffer[0];
gpsMsgCount++;
}
if (rxBuffer[0] == '\n')
{
fifoEnqueue(rxBuffer);
msgReceivedUART4 = true;
}
else
HAL_UART_Receive_IT(&uart4Handle, rxBuffer, 1);
// }
}
Solved! Go to Solution.
2021-09-04 12:29 PM
Use the HAL callbacks, which only get called if the relevant flags are set. In this case, HAL_UART_RxCpltCallback.
The flags are checked and cleared within HAL_UART_IRQHandler, so checking for them after that will not be useful.
2021-09-04 12:29 PM
Use the HAL callbacks, which only get called if the relevant flags are set. In this case, HAL_UART_RxCpltCallback.
The flags are checked and cleared within HAL_UART_IRQHandler, so checking for them after that will not be useful.
2021-09-04 03:16 PM
> HAL_UART_Receive_IT(&uart4Handle, rxBuffer, 1)
Using HAL_UART_Receive_IT to receive one byte is a terrible idea because it disables RX interrupt immediately after receive, so there's a window when incoming bytes can be lost . @Piranha and other prominent anti-HALers pointed this out many times.
If you cannot get DMA workng, write your own interrupt handler without calling any HAL stuff, and try to enable FIFO
(this works well for me on H743/753).
--pa
2021-09-04 03:56 PM
@TDK That worked like a charm. I can't express how much I appreciate your help. It's still amazes me that a novice like me can get near real time help from an expert like you and on a Saturday no less.
@Pavel A. This is an interim step so I can make progress elsewhere. The problem is the devices I need to talk to over UARTs do not send messages with a known, repeatable packet length. They do all terminate their messages with a CRLF so that's why I'm doing it this way. I am trying to keep my IRQ handlers as short as possible so I don't drop bytes. All I can say is it seems to be working for now at the low baud rates my devices work at. It will be interesting to see how many devices and how high a baud rate this approach will work at. As you noted, I'm working on the DMA approach with character match (hence the STM32H7 family) and idle detection but haven't gotten it working yet on the H7B3 Discovery board yet. I'm well aware of how nearly unworkable and painful the STM HAL is and I'd love to dump it but I just don't know enough to take that step yet. At this point, I think it's still more time effective for me to bumble through the learning curve using HAL than stop progress entirely trying to figure out how to do this stuff without HAL.
@TDK , @Pavel A. , @Piranha I do have a full time job designing and building Oceanographic research equipment and this is just a background task for now. I hope porting my existing hardware and software to STM32 and C/C++ will fit into my foreground schedule for next year and I am absolutely in the market for a competent STM32 consultant. If you're interested or know someone, please let me know.