Skip to main content
LDess
Associate
September 3, 2019
Question

STM32H743 : Reading UART7 while writing on UART4

  • September 3, 2019
  • 3 replies
  • 967 views

Hello, I have issues with STM32H743 UART. I use Nucleo 144 and I need to get GPS frames on UART7 (at 9600 baud) and display them on UART4 (at 115200 baud). If nothing is sent on UART4, reception of frames on UART7 is good but I want to display some values at the same time on UART4. If I do that, the frames on UART7 are not entirely received, some caracters are missing. More I print values on UART4 more there are missing caracters on UART7. Is that normal ? What can I do about this ? Thanks for your help !

This topic has been closed for replies.

3 replies

Bob S
Super User
September 3, 2019

WIthout seeing your code all we can do is make wild-#%$ guesses. My guess would be that you are using HAL and the polled version of HAL_UART_Transmit() and HAL_UART_Receive(). If that isn't it, post your code so we can give you better answers.

LDess
LDessAuthor
Associate
September 3, 2019
void log_print(const char *format, ...)
{
	uint8_t fmt_idx = 0;
	char pct = '%';
	va_list args;
	va_start(args, format);
 
	while(format[fmt_idx] != '\0')
	{
		if(format[fmt_idx] == '%')
		{
			fmt_idx++;
			if(format[fmt_idx] == 'c')
			{
				char arg = (char) va_arg(args, int);
				HAL_UART_Transmit(&huart4, (uint8_t*) &arg, 1, 1000);
			}
			else if(format[fmt_idx] == 'd')
			{
				char message[11];
				memset(message, 0, 11);
				int arg = (int) va_arg(args, int);
				sprintf(message, "%d", arg);
				HAL_UART_Transmit(&huart4,(uint8_t*) message, strlen(message), 1000);
			}
			else if(format[fmt_idx] == 's')
			{
				char message[256];
				memset(message, 0, 256);
				char* arg = (char*) va_arg(args, char*);
				sprintf(message, "%s", arg);
				HAL_UART_Transmit(&huart4,(uint8_t*) message, strlen(message), 1000);
			}
			else
				HAL_UART_Transmit(&huart4, (uint8_t*)&pct, 1, 1000);
		}
		else
			HAL_UART_Transmit(&huart4, (uint8_t*) &format[fmt_idx], 1, 1000);
		fmt_idx++;
	}
 
	va_end(args);
}
void MX_UART4_Init(void)
{
	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.Prescaler = UART_PRESCALER_DIV1;
	huart4.Init.FIFOMode = UART_FIFOMODE_ENABLE;
	huart4.Init.TXFIFOThreshold = UART_TXFIFO_THRESHOLD_1_8;
	huart4.Init.RXFIFOThreshold = UART_RXFIFO_THRESHOLD_1_8;
	huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
	if (HAL_UART_Init(&huart4) != HAL_OK)
	{
		Error_Handler();
	}
}
void MX_UART7_Init(void)
{
 huart7.Instance = UART7;
 huart7.Init.BaudRate = 9600;
 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.Prescaler = UART_PRESCALER_DIV1;
 huart7.Init.FIFOMode = UART_FIFOMODE_ENABLE;
 huart7.Init.TXFIFOThreshold = UART_TXFIFO_THRESHOLD_1_8;
 huart7.Init.RXFIFOThreshold = UART_RXFIFO_THRESHOLD_1_8;
 huart7.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
 if (HAL_UART_Init(&huart7) != HAL_OK)
 {
	LOG_E("ERROR : UART 7 initialization");
 Error_Handler();
 }
}

void GPS_getFrame(char* GPS_frame)
{
	char uart_char = '\0';
	uint8_t current_index = 0;
	HAL_StatusTypeDef ret;
 
	// read each character on the UART until '$' which is the beginning of a new frame
	do
	{
		ret = HAL_UART_Receive(&huart7, (uint8_t*)&uart_char, 1*sizeof(char),1000);
		if(ret == HAL_TIMEOUT)
		{
			LOG_W("HAL_UART_Receive return a timeout");
		}
		else if(ret == HAL_BUSY)
		{
			LOG_W("HAL_UART_Receive is busy");
		}
		else if(ret == HAL_ERROR)
		{
			LOG_E("ERROR : HAL_UART_Receive return an error");
			Error_Handler();
		}
		__HAL_UART_CLEAR_FLAG(&huart7, UART_CLEAR_NEF | UART_CLEAR_OREF | UART_FLAG_RXNE | UART_FLAG_ORE);
	} while(uart_char != '$');
 
 
	// read and store each character on the UART until '\n' which is the end of the frame
	do
	{
		if(current_index > MAX_FRAME_SIZE-1)
		{
			LOG_E("ERROR : Too much characters in the frame (maximum size : %d)\r\n", MAX_FRAME_SIZE);
			Error_Handler();
		}
 
		ret = HAL_UART_Receive(&huart7, (uint8_t*)&uart_char, 1*sizeof(char), 100000000);
 
		if(ret == HAL_TIMEOUT)
		{
			LOG_W("HAL_UART_Receive return a timeout");
		}
		else if(ret == HAL_BUSY)
		{
			LOG_W("HAL_UART_Receive is busy");
		}
		else if(ret == HAL_ERROR)
		{
			LOG_E("ERROR : HAL_UART_Receive return an error");
			Error_Handler();
		}
 
		if(ret == HAL_OK)
		{
			GPS_frame[current_index] = uart_char;
			current_index++;
		}
		__HAL_UART_CLEAR_FLAG(&huart7, UART_CLEAR_NEF | UART_CLEAR_OREF | UART_FLAG_RXNE | UART_FLAG_ORE);
	} while(uart_char != '\n');
 
 
	//log_print("%s", GPS_frame);
 
}

Here is the init functions generated by MX Cube (for UART4 and UART7) and the functions I use to send data on the UART4 and to receive GPS frame on the UART7.

Tesla DeLorean
Guru
September 3, 2019

HAL_UART_Receive and HAL_UART_Transmit both BLOCK, you'll need to use a different scheme for concurrent comms

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