cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H743 : Reading UART7 while writing on UART4

LDess
Associate

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 !

3 REPLIES 3
Bob S
Principal

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
Associate
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.

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
Up vote any posts that you find helpful, it shows what's working..