Skip to main content
Associate
February 21, 2024
Question

UART RX interrupt

  • February 21, 2024
  • 10 replies
  • 7528 views

Hello,

I'm trying trying to setup an interrupt receive on the U5 MCU using the STM32U5GJ-DK2 development kit. The USART1_IRQHandler does not get triggered at all. Here's my CubeMX config for the USART1:

Dobrev_0-1708518829438.png

Dobrev_1-1708518864347.png

I've sniffed the RX line, so I'm sure it's working as expected.

Here's my main() code:

 

 

 

int main(void)
{
 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* Configure the System Power */
 SystemPower_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_GPDMA1_Init();
 MX_ICACHE_Init();
 MX_DCACHE1_Init();
 MX_DCACHE2_Init();
 MX_CRC_Init();
 MX_LTDC_Init();
 MX_DMA2D_Init();
 MX_GPU2D_Init();
 MX_HSPI1_Init();
 MX_I2C2_Init();
 MX_JPEG_Init();
 MX_USART1_UART_Init();
 // MX_TouchGFX_Init();
 /* Call PreOsInit function */
 // MX_TouchGFX_PreOSInit();
 /* USER CODE BEGIN 2 */

 HAL_UARTEx_ReceiveToIdle_IT(&huart1, RxBuffer, RxBuffer_Size);
 __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);

 printf("OS kernel initialized\n");
 /* USER CODE END 2 */

 /* Init scheduler */
 // osKernelInitialize();

 /* Call init function for freertos objects (in freertos.c) */
 // MX_FREERTOS_Init();

 /* Start scheduler */
 // osKernelStart();

 /* We should never get here as control is now taken by the scheduler */
 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

 

 

 

and here's my redefined Callback as per the HAL's instructions:

 

 

 

int len = 0;
#define RxBuffer_Size 20
#define TxBuffer_Size 20

uint8_t RxBuffer[RxBuffer_Size];
uint8_t TxBuffer[TxBuffer_Size];
extern uint8_t ComCommand[RxBuffer_Size];
extern uint8_t polled;

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
 if (huart->Instance == USART1)
 {
 memset(ComCommand, 0, sizeof(ComCommand));
 len = strlen(RxBuffer);
 strncpy(TxBuffer, RxBuffer, len);
 strncpy(ComCommand, RxBuffer, len);
 polled = 0;
 // HAL_UART_Transmit(&huart1,TxBuffer,len,HAL_MAX_DELAY); //transmit the full sentence again
 memset(TxBuffer, 0, sizeof(TxBuffer));
 memset(RxBuffer, 0, sizeof(RxBuffer));
 printf("UART transfer complete\n");
 HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuffer, RxBuffer_Size);
 __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
 }
}

 

 

 

 I've been using the same technique on the f7, where it was working flawlessly, but on the u5 the interrupt never gets triggered, so the callback never gets called. What am I missing?

This topic has been closed for replies.

10 replies

Andrew Neil
Super User
February 21, 2024

Before getting on to interrupts, does work for a simple polled read?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
DobrevAuthor
Associate
February 21, 2024

Just tried it, yes it does work.

mƎALLEm
Technical Moderator
February 21, 2024

Not related to your issue but too many code to execute in the callback (interrupt) including a printf(). Not recommended to do so ..

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
 if (huart->Instance == USART1)
 {
 memset(ComCommand, 0, sizeof(ComCommand));
 len = strlen(RxBuffer);
 strncpy(TxBuffer, RxBuffer, len);
 strncpy(ComCommand, RxBuffer, len);
 polled = 0;
 // HAL_UART_Transmit(&huart1,TxBuffer,len,HAL_MAX_DELAY); //transmit the full sentence again
 memset(TxBuffer, 0, sizeof(TxBuffer));
 memset(RxBuffer, 0, sizeof(RxBuffer));
 printf("UART transfer complete\n");
 HAL_UARTEx_ReceiveToIdle_DMA(&huart1, RxBuffer, RxBuffer_Size);
 __HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
 }

 

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
Tesla DeLorean
Guru
February 21, 2024

+1 avoid any blocking function in interrupts / callbacks.

The use of string functions is also a bit problematic. Yes, array fills with NUL's but needs to have a trailing NUL in maximal case.

Variables changing under interrupt context or callbacks should be marked as volatile if you're reliant on them elsewhere.

Random use of sizeof() vs strlen(). Please just make a string subroutine wrapper for HAL_UART_Transmit() you can use consistently. It will improve code readability significantly. Thanks for using Code Formatting tools </>

Try to present more complete code rather than key hole view. Cube hides a lot of the important code in the MSP layers, making main.c highly superficial. Posting complete examples in GitHub might help convey important detail and interrelationships. 

Mix of sprintf() and printf(), also remember that sprintf() implicitly returns the string length

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
DobrevAuthor
Associate
February 21, 2024

I realize that, most of this code is for debug purposes. However my problem here is that the RXNE interrupt, which I have explicitly enabled, does not get triggered.

mƎALLEm
Technical Moderator
February 21, 2024

And if you activate the UART interrupt with HAL_UART_Receive_IT() instead of HAL_UARTEx_ReceiveToIdle_IT()

and use HAL_UART_RxCpltCallback() instead of HAL_UARTEx_RxEventCallback(), what happens? 

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
DobrevAuthor
Associate
February 21, 2024

Same behavior. Interrupt not triggered.

mƎALLEm
Technical Moderator
February 21, 2024

What is the value of RxBuffer_Size? Does your UART is receiving the same amount of data?

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
DobrevAuthor
Associate
February 21, 2024

RXBuffer is 20. I've tried with 10 and a whole bunch of different values. I've also measured the data with a logic analyzer to ensure consistency. The interrupt RXNE, which should get triggered when the FIFO is not empty, simply doesn't get triggered.

mƎALLEm
Technical Moderator
February 21, 2024

If you set RXBuffer = 20, do you send at least 20 bytes from the sender?

Did you try RXBuffer = 1?

To give better visibility on the answered topics, please click "Best answer" on the reply which solved your issue or answered your question.
DobrevAuthor
Associate
February 21, 2024

Yes, I do. I send 20 and all kinds of data, just to check if the interrupt gets triggered. It doesn't.

Technical Moderator
April 2, 2024

Hello @Dobrev 

Is the UART global interrupt enabled? If not try to add the line bellow in HAL_UART_MspInit.

 

HAL_NVIC_EnableIRQ(UART4_IRQn);

 

Best regards

Omar

"In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question.Saket_Om"
Karl Yamashita
Lead III
April 2, 2024

You're starting off using HAL_UARTEx_ReceiveToIdle_IT before main while loop, then start using HAL_UARTEx_ReceiveToIdle_DMA in the callback. Not sure why you're mixing it up?

 

Not sure the size of your buffer and the amount of data you're expecting but more than likely you're going to get a half complete callback so you maybe saving only half of your expected string. Another thing is that you're doing too much copying in the interrupt. You should just set a flag to indicate 

 

 

You haven't shown a screen shot of the DMA settings. If you didn't assign a DMA channel then you're not going to get an interrupt.

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source