2022-03-15 01:49 PM
Intermittent results during a loopback (same processor, Tx to Rx) test. Happens the same on both STM32L041G6 and STM32L051K8U6 processors.
STM32CubeIDE (recent version) used to enable Uart2, Interrupt enabled, no DMA, 9600 baud, 8bit, 1 stop, no parity. 16 Sample oversampling. Everything else is default.. Clock rate is default selected by the STM32cube, 2.097 MHz.
No compiler errors or warnings.
Adding delay to the HAL calls breaks things. Adding delay before and after the calls breaks things. Adding a check for the callback flag to be set hangs.... (never hits the callback).
Below is a graphic of looping back data. The code that executes is a basic loop:
1) Load a pattern of 2 characters into a byte array.
2) Transmit to UART2
3) Load a different 2 character pattern into the array just used (other data should have been sent)
4) Verify that the 2 array locations have actually changed.
5) Read the UART2 Rx port
6) Verify that the original data showed up.
7) Loop to #1.
The code used for this:
...
while (1) {
resultStr[0] = 'v'; // Lower case v character
resultStr[1] = '\r'; // ASCII return character
HAL_UART_Transmit_IT(&huart2, resultStr, 2);
// while (Uart2TxReady != SET) {;} // Stops working
Uart2TxReady = RESET; // Reset the UART receive flag
// HAL_Delay(4); // Stops working
resultStr[0] = '2';
resultStr[1] = '1';
if ((resultStr[0] != '2') ) {
debugPrint(&huart1, " 2! ");
}
// HAL_Delay(4); // Stops working
// while (Uart2RxReady != SET) {;}/ Stops working
HAL_UART_Receive_IT(&huart2, resultStr, 2);
// while (Uart2TxReady != SET) {;}/ Stops working
Uart2RxReady = RESET;
if (resultStr[0] == 'v') {
debugPrint(&huart1, "v ");
}
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *UartHandle)
{
/* Set transmission flag: transfer complete */
if (UartHandle == &huart1) {
Uart1TxReady = SET;
} else if (UartHandle == &huart2) {
Uart2TxReady = SET;
} else {
Error_Handler();
}
}
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
{
/* Set receive flag: transfer complete */
if (UartHandle == &huart1) {
Uart1RxReady = SET;
} else if (UartHandle == &huart2) {
Uart2RxReady = SET;
} else {
Error_Handler();
}
}
The data comes back a mix of 'v' and '2' characters. There doesn't seem to be any consistency in the data pattern. Tx is wired to Rx.
What am I not doing right???
2022-03-15 02:02 PM
Make sure things that need to be volatile, are.
Use separate buffering, have the call-back start the reception for the next character after you've save data to a buffer. Request single bytes, UART interrupts for every one in any case, only does callback once it has all bytes requested.
Sporadically initiating the reception leaves gaps in service, receiver could underrun.
>>No compiler errors or warnings.
Yeah, they only complain for syntactical errors, not flaws in logic and algorithms.
Also doesn't understand interrupt/callbacks occur outside of normal program flow, so again volatile where need be.
2022-03-15 02:11 PM
In addition to volatile qualifiers...
> Tx is wired to Rx.
In which case you need to ensure the RX is ready to receive before TX data is sent. You're doing it backwards.
Would recommend implementing RX with interrupts and using blocking TX calls until you get it working, then graduate to interrupts on both sides.
Pseudocode:
Start reception
Start transmission of 2 bytes
Wait for reception to complete
Wait for transmission to complete (not really needed in this example)