cancel
Showing results for 
Search instead for 
Did you mean: 

USART4 does not work receiving data. It works only on USAR2. Sending data works on both. 1) polling on USART4: always timeout 2) Interrupt on USART4 --> Interrupt not thrown

ORend.1
Associate II
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart4;
...
//#define UART_MODE 1
#define UART_MODE 2
...
#define USARTX USART4
#define huartX huart4
 
uint8_t UART_rxBuffer[50] = {0};
...
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
  {
	uint8_t tstBuffer[] = "return: ";
	HAL_UART_Transmit(&huartX, tstBuffer, strlen(tstBuffer), 100);
	HAL_UART_Transmit(&huartX, UART_rxBuffer, 1, 100);//resend first byte
 
	delay(10);
	//normally: first enable interrupt again
	HAL_UART_Receive_IT(&huartX, UART_rxBuffer, 1);
  }
...
int main(void)
{
...
  MX_USART2_UART_Init();
  MX_USART4_UART_Init();
...
if (UART_MODE == 2)
  {
	  //expect at least 4 chars --> 40 bytes --> better just one byte (stable)
	  HAL_UART_Receive_IT(&huartX, UART_rxBuffer, DATA_LENGTH_POLLING);
  }
  while (1)
  {
	  // LED on
	         WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BS_5);
	         //delay(500);
 
	         puts("Hello");//standard output redirected
	         char number_str[10];
	         sprintf(number_str, "%d", testCounter);
	         puts(number_str);
	         testCounter++;
 
	         /**
	         	  polling problem: after some data received will not work anymore!
	         	          */
	         if (UART_MODE == 1)
	         {
	         //1a) polling --> needs fixed data length of transmission!!
	         //aa) reacts only on exact size!!
	         //ab) reacts once one too much data, afterwards it dies! //PROBLEM, stops when too much data was received!
	         HAL_StatusTypeDef res = HAL_UART_Receive (&huartX, UART_rxBuffer, DATA_LENGTH_POLLING, 5000);
 
	         if(res == HAL_OK) //why does it not work with USART4??
	         {
		         if (UART_rxBuffer[0] != '\0')
		         {
		        	 HAL_UART_Transmit(&huartX, UART_rxBuffer, 12, 100);
		         }
	         }
 
	         else if(res == HAL_TIMEOUT)
	         {
	        	 puts("timeout\n");
	         }
 
	         else if(res == HAL_BUSY)
	         {
	        	 puts("busy\n");
	         }
 
	         //1c) DMA --> needs added DMA channel
	         //HAL_UART_Receive_DMA (&huart4, UART1_rxBuffer, 12);
	         }//end polling
	         else//no uart polling
	         {
		         delay(500);
	         }
	         // LED off
	         WRITE_REG(GPIOA->BSRR, GPIO_BSRR_BR_5);
  }
}
 
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
 
  /** Configure the main internal regulator output voltage
  */
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_12;
  RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART2;
  PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_USART2_UART_Init(void)
{
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 115200;
  huart2.Init.WordLength = UART_WORDLENGTH_8B;
  huart2.Init.StopBits = UART_STOPBITS_1;
  huart2.Init.Parity = UART_PARITY_NONE;
  huart2.Init.Mode = UART_MODE_TX_RX;
  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
  huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
static void MX_USART4_UART_Init(void)
{
  huart4.Instance = USART4;
  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.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart4) != HAL_OK)
  {
    Error_Handler();
  }
}

8 REPLIES 8
ORend.1
Associate II

btw

USAR2: I use the nucleo eval board with STLINK. -.-> sending receiving works

USAR4: usb to uart adapter --> only sending from uc works. Data send from PC not received.

Using 115200 baud rate

What hardware?

Read out and check the relevant GPIO registers for given pin.

Try to connect it to the STLink UART.

JW

Which board/stm32?

Show pin initialization code, and related defines. Probably in MSP file.

Double check AF setting vs Data Sheet

Double check schematic, solder bridges, etc.

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

STM32L073 nucleo board.

The Port config was done in Cube IDE, the right AF was chosen.

I can send from nucleo via USART2 and USART4, BUT only on USART2 also receiving data from PC.

Using exactly the same code when switching from USART2 to USART4.

void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  if(huart->Instance==USART2)
  {
  /* USER CODE BEGIN USART2_MspInit 0 */
 
  /* USER CODE END USART2_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART2_CLK_ENABLE();
 
    __HAL_RCC_GPIOA_CLK_ENABLE();
    /**USART2 GPIO Configuration
    PA2     ------> USART2_TX
    PA3     ------> USART2_RX
    */
    GPIO_InitStruct.Pin = USART_TX_Pin|USART_RX_Pin;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
    /* USART2 interrupt Init */
    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART2_IRQn);
  /* USER CODE BEGIN USART2_MspInit 1 */
 
  /* USER CODE END USART2_MspInit 1 */
  }
  else if(huart->Instance==USART4)
  {
  /* USER CODE BEGIN USART4_MspInit 0 */
 
  /* USER CODE END USART4_MspInit 0 */
    /* Peripheral clock enable */
    __HAL_RCC_USART4_CLK_ENABLE();
 
    __HAL_RCC_GPIOC_CLK_ENABLE();
    /**USART4 GPIO Configuration
    PC10     ------> USART4_TX
    PC11     ------> USART4_RX
    */
    GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF6_USART4;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
 
    /* USART4 interrupt Init */
    HAL_NVIC_SetPriority(USART4_5_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(USART4_5_IRQn);
  /* USER CODE BEGIN USART4_MspInit 1 */
 
  /* USER CODE END USART4_MspInit 1 */
  }
 
}

Read out and check the relevant GPIO registers for given pin.

Try to connect it to the STLink UART.

JW

ORend.1
Associate II

thx Tesla DeLorean + Jan

I changed the solder bridges on my nucleo board to disconnect fixed USART2 from ST-Links virtual com port.

Connecting USART4 works there.

When I using different USB Uart adapter (FTDI chip) like this one

https://www.amazon.de/Serial-Konverter-Modul-original-FT232RL/dp/B075N82CDL

my uc will not receive data... just sending works.

Is there anything special I need to configure??

Pins look Ok,

Perhaps the IRQ Handler and call-into HAL or Peripheral clock settings.

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

Follow up question:

either in polling or in interrupt mode when more data is send than expected the functions

  • HAL_UART_Receive (&huartX, UART_rxBuffer, DATA_LENGTH_POLLING, 5000);
  • void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) / HAL_UART_Receive_IT(&huartX, UART_rxBuffer, DATA_LENGTH_INTERRUPT);

will lead to the problem that no more data receiving will work...

Example below shows that expected length is 10 bytes, but user sends 11 bytes. Two times this works, but afterwards the UART_Receive is not working anymore.

Example: 1234567890received: 1234567890received: 12345678901received: 12345678901received: 123456789011234567890112345678901

What's the reason for that?