2018-08-16 07:09 AM
I'm transmitting 1 byte of data via HAL_UART_Transmit_IT(). After this byte is being fed to the UART HAL via the abovementioned method, the HAL_UART_TxCpltCallback() callback is being fired (which is completely normal). The problem comes during the consequent operation - I want to try to receive 1 byte of data via HAL_UART_Receive_IT(). After calling HAL_UART_Receive_IT() I don't expect firing the HAL_UART_RxCpltCallback() callback, because the serial port is totally disconnected and there's no way data to be present on it's RX line. But this is what actually happens - the HAL_UART_RxCpltCallback() is being called without any reason. And there is no error detected if I check the same UART's state by HAL_UART_GetError() in HAL_UART_RxCpltCallback() callback.
Any ideas what may cause this very strange behavior?
2018-08-16 08:14 AM
>>Any ideas what may cause this very strange behavior?
Are you inspecting the UART registers in the debugger?
2018-08-16 08:27 AM
It happens no matter if I inspect the HAL flow and the registers or not. If I put just a single breakpoint in the reception callback (HAL_UART_RxCpltCallback()) I see it being called, even so there's totally no data on the RX line (explicitly checked this line with oscilloscope as well).
2018-08-16 08:44 AM
Disabling UART_IT_RXNE before HAL_UART_Transmit_IT() and reenabling it after some explicit delay in HAL_UART_TxCpltCallback() workarounded the problem. I guess HAL ISR support is not coded by the greatest genius in the world.... Indeed, I plan to avoid using HAL from now on.
2018-08-16 06:58 PM
did you read out the RxFifos before you enabled the interrupt ?
much better to use the DMAs
if you want the best solution for an interrupt for each char,
set the DMA circular buffer to 2 bytes,
you will get both halfFull and Full Callbacks
2018-08-16 07:06 PM
but the easiest way toi use the Uarts is with DMA buffer set to 256bytes or more (1k), giving you time to get there...
you can easily check if a single byte has arrived:
U1RxBufferPtrIN = U1RxBufSize - huart1.hdmarx->Instance->CNDTR; //next byte received will go here
....
char readByte = Usart1RxDMABuffer[U1RxBufferPtrOUT++];
...
#define U1RxBufSize 256
#define U1TxBufSize 4096
char Usart1TxDMABuffer[U1TxBufSize];
char Usart1RxDMABuffer[U1RxBufSize];
int16_t U1RxBufferPtrIN, U1RxBufferPtrOUT, U1TxBufferPtrIN, U1TxBufferPtrOUT;
char TxDMA1BufHasData, DMA1BufAlmostFull;
void initUart1RxDMABuffer(void) {
if (HAL_UART_Receive_DMA(&huart1, (uint8_t *)Usart1RxDMABuffer, U1RxBufSize) != HAL_OK)
// Transfer error in reception process
printf"initUart1RxDMABuffer Failed\n");
else
printf( "initUart1RxDMABuffer OK!\n");
}