cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L0x1, trying to get UART2 interrupts working. UART2 on PA2/3 is selected Tx interrupt is working, Rx is not, intermittent results. Modes: Microprocessor Communication and Asynchronous act the same. Details below.

MStev.4
Associate II

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???

2 REPLIES 2

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.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
TDK
Guru

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)

If you feel a post has answered your question, please click "Accept as Solution".