Skip to main content
Associate III
January 21, 2025
Solved

Can't receive data on UART7 in STM32H7S78-DK while using UART4

  • January 21, 2025
  • 33 replies
  • 6884 views

Hello,

I am using the STM32H7S78-DK board and STM32CubeIDE for development. In my application, I am working with UART communication between UART4 and UART7.

Objective:

  1. I am sending data from UART4 (connected to the Virtual COM port on the board).
  2. The data is transmitted from UART4 to UART7.
  3. After sending the data, I expect a response from UART7, but I am unable to receive it.

Steps I Follow:

  1. Initially, I used the HAL_UART_Receive_IT function for UART7 reception. However, upon reviewing several posts and technical documents, I realized that HAL_UART_Receive_IT is only suitable for known-length data and not for unknown-length data.
  2. Based on the reference example provided here, I implemented HAL_UARTEx_ReceiveToIdle_IT for idle-line detection.

Issue Faced:

Despite implementing HAL_UARTEx_ReceiveToIdle_IT, I am still unable to receive any response from UART7.

Here is my code for reference,

 

/* USER CODE BEGIN PV */
#define RX_BUFFER_SIZE 20
#define RX_BUFFER_SIZE_7 50

uint8_t rxBuffer[RX_BUFFER_SIZE] = {0}; // Buffer to store received data
uint8_t rxBuffer7[RX_BUFFER_SIZE_7] = {0}; // Buffer to store received data


osThreadId_t uartTaskHandle;
const osThreadAttr_t uartTask_attributes =
{
 .name = "uartTask",
 .priority = (osPriority_t)osPriorityNormal,
 .stack_size = 512 * 4,
};

void UART_Print(const char* message)
{
 // Transmit the string data over UART
 HAL_UART_Transmit(&huart4, (uint8_t*)message, strlen(message), HAL_MAX_DELAY);
}


void SendDataOnUART7(uint8_t *pData)
{
	uint8_t TxData[20];

	uint16_t length = (uint16_t)pData[0];

	memcpy(TxData, &pData[1],length);

	// Transmit the string data over UART
	HAL_UART_Transmit(&huart7,TxData, length, HAL_MAX_DELAY);
}


void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if (huart->Instance == huart7.Instance)
	{
		// Transmit the string data over UART
		printf("Received data on uart7: %s\n\r", rxBuffer7);

		HAL_UARTEx_ReceiveToIdle_IT(&huart7, rxBuffer7, RX_BUFFER_SIZE_7);
	}
}


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if (huart->Instance == huart4.Instance)
	{
		// Print received message
		printf("Received: %s\n\r", rxBuffer);

		SendDataOnUART7(rxBuffer);

		memset(rxBuffer, 0, RX_BUFFER_SIZE);

		// Re-enable UART interrupt for the full buffer to receive more data
		HAL_UART_Receive_IT(&huart4, rxBuffer, RX_BUFFER_SIZE);
	}

}


/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{

 /* USER CODE BEGIN 1 */

 /* USER CODE END 1 */

 /* MPU Configuration--------------------------------------------------------*/
 MPU_Config();

 /* Enable the CPU Cache */

 /* Enable I-Cache---------------------------------------------------------*/
 SCB_EnableICache();

 /* Enable D-Cache---------------------------------------------------------*/
 SCB_EnableDCache();

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

 /* Update SystemCoreClock variable according to RCC registers values. */
 SystemCoreClockUpdate();

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


 MX_GPIO_Init();
 MX_HPDMA1_Init();
 MX_LTDC_Init();
 MX_CRC_Init();
 MX_DMA2D_Init();
 MX_JPEG_Init();
 MX_FLASH_Init();
 MX_I2C1_Init();
 MX_GPU2D_Init();
 MX_ICACHE_GPU2D_Init();
 MX_UART4_Init();
 MX_UART7_Init();
 
 UART_Print("Start...TouchGFX...Project\n\r");
 printf("Hello_STM32H7S78-DK!\n\r");

 /* Enable UART4 interrupt mode */
 //Make sure that the data sent is exactly 20 bytes, as the RX_BUFFER_SIZE is set to 20. If the data is not 20 bytes, it will not work properly!
 HAL_UART_Receive_IT(&huart4, rxBuffer, RX_BUFFER_SIZE); 
 HAL_UARTEx_ReceiveToIdle_IT(&huart7, rxBuffer7, RX_BUFFER_SIZE_7);


 MX_TouchGFX_Init();
 /* Call PreOsInit function */
 MX_TouchGFX_PreOSInit();

 osKernelInitialize();

 defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);

 /* creation of TouchGFXTask */
 TouchGFXTaskHandle = osThreadNew(TouchGFX_Task, NULL, &TouchGFXTask_attributes);

 uartTaskHandle = osThreadNew(UART_Task, NULL, &uartTask_attributes);


 /* Start scheduler */
 osKernelStart();

 while (1)
 {

 }
 /* USER CODE END 3 */
}

 

I would appreciate any guidance or example code to resolve this issue.

Best regards,
Mehul

This topic has been closed for replies.
Best answer by Mehulrana511

Hi @Andrew Neil ,

Thank you for your response!

We have identified the bug. The interrupt is being blocked due to the printf function, as it transmits data over UART4 at the same time when we receive an interrupt on UART7.

Here’s what I did to resolve it:

I am now sending the data (command) through Ethernet and transmitting this data over UART7. Once I get a response from UART7, I wait for one byte of data. Since I am unsure of the exact length of the received data, I treat the reception as complete when I encounter a '\n' character. After this, I send the data over Ethernet.

During this operation, I avoid using the printf function (on UART4). In other scenarios, I can continue using printf for debugging purposes.

Thank you once again for your help!

Best regards,
Mehul

 

33 replies

Tesla DeLorean
Guru
January 21, 2025

There was a complaint within last few days of UART7 IRQ on H7

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
January 21, 2025
Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Andrew Neil
Super User
January 21, 2025

@Mehulrana511 wrote:
  1. I am sending data from UART4 (connected to the Virtual COM port on the board).
  2. The data is transmitted from UART4 to UART7.
  3. After sending the data, I expect a response from UART7, but I am unable to receive it.

You need to disconnect the Virtual COM Port (VCP) from UART4 - otherwise it will prevent this setup from working.

https://community.st.com/t5/stm32-mcus-boards-and-hardware/i-cannot-receive-data-while-using-usb-to-uart-for-nucleo-f411re/m-p/690201/highlight/true#M19855

 

PS:

With the VCP connected, you have this:

UART4 TX ------->+--------------------> UART7 RX
 |
UART4 RX <-------------+<-------------- UART7 TX
 | ^
 | |
 v |
 VCP VCP
 RX TX

So the VCP TX and UART7 TX are shorted together - this is why UART7 can receive from UART4, but UART4 cannot receive from UART7.

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.
Associate III
January 21, 2025

Hi @Andrew Neil ,
Thanks for answering but I need UART4 for debugging purpose.

One thing I need to add in this thread,
When I was trying HAL_UART_Receive_IT function and  send cmd from Ethernet, I get response from UART7 but it happens only once(at very first time) then i am not able to get response even after sending same or different cmd.

But when I use HAL_UARTEx_ReceiveToIdle_IT , I am not able to get response even single time.

Here is the screenshot of response i get from UART7 when i send cmd from UART7.

 

Mehulrana511_0-1737461869325.png


/Mehul 

Andrew Neil
Super User
January 21, 2025

@Mehulrana511 wrote:

Thanks for answering but I need UART4 for debugging purpose.


As noted, you cannot use it both for the VCP and for connection to UART7 (or any other UART) at the same time.

You can do one or the other - but not both at once.

 


@Mehulrana511 wrote:

Here is the screenshot of response i get from UART7 when i send cmd from UART7.


So how are you connecting UART7 to that terminal?

Please give full details of your hardware setup:

https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

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.
Associate III
January 17, 2025

Hello,

I am working on stm32h7s78 using UART-4 & UART-7  and MXCHIP EMC3080-P WIFI/BLE module. However,  I am facing issues regarding the UART-7 RX interrupt. If I transmit the command from UART-4 to UART-7 it will transmit the same command data to EMC3080-P WIFI/BLE module. In addition, WIFI/BLE module will send the response to UART-7 but I am not getting the UART-7 callback.

But if I do the debugging with USB-to-TTL and EMC3080-P module I am receiving the expected response from the module.

Bellow is the code for the reference your will be appreciated.

Thank you,

Harsh

 

#include "main.h"
#include "stdio.h"
#include "string.h"
#include "stdbool.h"
#define RX_BUFFER_7 36
uint8_t rx_buff[20];
uint8_t rx_buff_7[RX_BUFFER_7];

UART_HandleTypeDef huart4;
UART_HandleTypeDef huart7;

static void MX_GPIO_Init(void);
static void MX_FLASH_Init(void);
static void MX_UART4_Init(void);
static void MX_UART7_Init(void);
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

	if(huart->Instance == UART4)
	{
		uint8_t tx_buff[20];
	//	 Print received message
		printf("Received on UART4: %s\n\r", rx_buff);


		uint16_t length = (uint16_t) rx_buff[0];

		memcpy(tx_buff,&rx_buff[1],length);

		HAL_UART_Transmit(&huart7, tx_buff,length, 1000);

	//	 Re-enable UART interrupt for the full buffer to receive more data

		HAL_UART_Receive_IT(&huart4, rx_buff, 20);
		memset(rx_buff, 0, 20);

	}
	else
	{
		//	 Print received message
			printf("Received on UART7: %s\n\r", rx_buff_7);
			HAL_UART_Receive_IT(&huart7, rx_buff_7, RX_BUFFER_7);
	}

}

int main(void)
{

 /* USER CODE BEGIN 1 */



 /* USER CODE END 1 */

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

 /* Update SystemCoreClock variable according to RCC registers values. */
 SystemCoreClockUpdate();

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

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_FLASH_Init();
 MX_UART4_Init();
 MX_UART7_Init();
 /* USER CODE BEGIN 2 */

 HAL_UART_Receive_IT(&huart4, rx_buff, 20);
 HAL_UART_Receive_IT(&huart7, rx_buff_7, RX_BUFFER_7);
 printf("Start....\n\r");
// /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */
//	 HAL_GPIO_TogglePin(GREEN_LED_GPIO_Port, GREEN_LED_Pin);
//	 HAL_Delay(1000);

 /* USER CODE BEGIN 3 */
 }

 /* USER CODE END 3 */
}

/**
 * @brief FLASH Initialization Function
 * None
 * @retval None
 */
static void MX_FLASH_Init(void)
{

 /* USER CODE BEGIN FLASH_Init 0 */

 /* USER CODE END FLASH_Init 0 */

 /* USER CODE BEGIN FLASH_Init 1 */

 /* USER CODE END FLASH_Init 1 */
 /* USER CODE BEGIN FLASH_Init 2 */

 /* USER CODE END FLASH_Init 2 */

}

PUTCHAR_PROTOTYPE
{
 /* Place your implementation of fputc here */
 /* e.g. write a character to the LPUART1 and Loop until the end of transmission */
 HAL_UART_Transmit(&huart4, (uint8_t *)&ch, 1, 0xFFFF);

 return ch;
}

/**
 * @brief UART4 Initialization Function
 * None
 * @retval None
 */
static void MX_UART4_Init(void)
{

 /* USER CODE BEGIN UART4_Init 0 */

 /* USER CODE END UART4_Init 0 */

 /* USER CODE BEGIN UART4_Init 1 */

 /* USER CODE END UART4_Init 1 */
 huart4.Instance = UART4;
 huart4.Init.BaudRate = 115200;
 huart4.Init.WordLength = UART_WORDLENGTH_8B;
 huart4.Init.StopBits = UART_STOPBITS_1;
 huart4.Init.Parity = UART_PARITY_NONE;
 huart4.Init.Mode = UART_MODE_TX_RX;
 huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart4.Init.OverSampling = UART_OVERSAMPLING_16;
 huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart4.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart4) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(&huart4, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(&huart4, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_DisableFifoMode(&huart4) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN UART4_Init 2 */

 /* USER CODE END UART4_Init 2 */

}

/**
 * @brief UART7 Initialization Function
 * None
 * @retval None
 */
static void MX_UART7_Init(void)
{

 /* USER CODE BEGIN UART7_Init 0 */

 /* USER CODE END UART7_Init 0 */

 /* USER CODE BEGIN UART7_Init 1 */

 /* USER CODE END UART7_Init 1 */
 huart7.Instance = UART7;
 huart7.Init.BaudRate = 115200;
 huart7.Init.WordLength = UART_WORDLENGTH_8B;
 huart7.Init.StopBits = UART_STOPBITS_1;
 huart7.Init.Parity = UART_PARITY_NONE;
 huart7.Init.Mode = UART_MODE_TX_RX;
 huart7.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart7.Init.OverSampling = UART_OVERSAMPLING_16;
 huart7.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart7.Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart7.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart7) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(&huart7, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(&huart7, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_DisableFifoMode(&huart7) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN UART7_Init 2 */

 /* USER CODE END UART7_Init 2 */

}

/**
 * @brief GPIO Initialization Function
 * None
 * @retval None
 */
static void MX_GPIO_Init(void)
{
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */

 /* GPIO Ports Clock Enable */
 __HAL_RCC_GPIOD_CLK_ENABLE();
 __HAL_RCC_GPIOE_CLK_ENABLE();

/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
 /* USER CODE BEGIN Error_Handler_Debug */
 /* User can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
 * @brief Reports the name of the source file and the source line number
 * where the assert_param error has occurred.
 * file: pointer to the source file name
 * line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
 /* USER CODE BEGIN 6 */
 /* User can add his own implementation to report the file name and line number,
 ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

 

 

Karl Yamashita
Principal
January 22, 2025

So I've tested on the Nucleo-H723 and UART7 is interrupting. 

The first time I tested, it was over a year ago. Possibly the FW package back then could have had a bug? I never did check the generated code for bugs back then.

But with STM32CubeIDE 1.16.1 and the latest FW package, UART7 doesn't show any issue with interrupts when receiving data. 

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
Andrew Neil
Super User
January 23, 2025

@Karl Yamashita wrote:

So I've tested on the Nucleo-H723 and UART7 is interrupting.  


@Mehulrana511 has also confirmed that they have UART7 interrupts working when they don't also use UART4.

So it's certainly not a fundamental issue with UART7 interrupts.

A already noted, I strongly suspect the fault(s) is/are in @Mehulrana511 and @harshpanchal_6's code

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.
Mehulrana511AuthorBest answer
Associate III
January 27, 2025

Hi @Andrew Neil ,

Thank you for your response!

We have identified the bug. The interrupt is being blocked due to the printf function, as it transmits data over UART4 at the same time when we receive an interrupt on UART7.

Here’s what I did to resolve it:

I am now sending the data (command) through Ethernet and transmitting this data over UART7. Once I get a response from UART7, I wait for one byte of data. Since I am unsure of the exact length of the received data, I treat the reception as complete when I encounter a '\n' character. After this, I send the data over Ethernet.

During this operation, I avoid using the printf function (on UART4). In other scenarios, I can continue using printf for debugging purposes.

Thank you once again for your help!

Best regards,
Mehul