cancel
Showing results for 
Search instead for 
Did you mean: 

USART receive break and reset mcu

tvill.1
Associate II

Hello,

I use STM32G0 and USART2 in IT mode or DMA mode.

When the mcu receive a break command on uart line, he reset after entering on the IRQ handler.

Have you an idea ?

Regards

18 REPLIES 18

Step through the ISR, best in disasm, until the reset or anything else strange occurs.

JW

Andrew Neil
Evangelist III

As @Community member​ says, you need to determine where, exactly, this "reset" is occurring.

Likely, there's an issue in your code that it doesn't (properly) handle the Break condition...

tvill.1
Associate II

Hello,

Thanks for your reply ^^

I think my code is good.

But i have found something, when i create simple uart code to receive and transmit data (and break), everything is good on stm32g031 but the stm32g0b0 reset on break.

I didn't found infos on errata about that but it is possible to have error on the design?

Regards.

> I think my code is good.

If your code is good, then the problem is in hardware.

But common experience is, that it's more likely that the code is not good.

JW

tvill.1
Associate II

thank for that intervention, but didn't help to resole my issue :)

I have some experience and the part of uart communication in my code is very simple.

And the second thing is the other code with only uart IP and receive on idle in IT works on the G031 but reset on G0B0 with break.

And i ask the question about the design, because i have already seen that on nxp with imx6.

Thanks.

@tvill.1​ "didn't help to resole my issue"

You've given so little information that it's hard to say anything other than sweeping generalisations - like the fact that common experience is, indeed, that it's far more likely that the code is not good.

Again, have you stepped through your code to see exactly where the reset is happening?

I can't step my code, no ISR or event can be catched. The debug stay connected when the reset arrive.

The only thing i can saw is the break point on the first line in main when the reset occur.

my main.c is attached (the test code simplified)

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2022 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "string.h"
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define MAX_USART_BUF_IN	100		/*! USART Buffer in length */
#define MAX_USART_BUF_OUT	5000	/*! USART Buffer out length */
static const uint8_t VERSION[] = "v1.4.1\r\n";
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_rx;
DMA_HandleTypeDef hdma_usart2_tx;
 
/* USER CODE BEGIN PV */
uint8_t usartBufferIn[MAX_USART_BUF_IN];
uint16_t usartBufferInLen;
uint16_t usartBufferInIndx;
uint8_t usartBufferOut[MAX_USART_BUF_OUT];
uint16_t usartBufferOutlen;
uint16_t usartBufferOutIndx;
 
uint8_t send = 0;
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
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();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  usartBufferOutlen = strlen((const char *)VERSION);
  memcpy(usartBufferOut, (uint8_t *)VERSION, usartBufferOutlen);
  HAL_UART_Transmit_IT(&huart2, usartBufferOut, usartBufferOutlen);
  HAL_UARTEx_ReceiveToIdle_IT(&huart2, usartBufferIn, MAX_USART_BUF_IN);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(send == 1)
	  {
		  send = 0;
		  HAL_UART_Transmit_IT(&huart2, usartBufferOut, usartBufferOutlen);
	  }
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1;
  RCC_OscInitStruct.PLL.PLLN = 8;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
  RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
  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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief USART2 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART2_UART_Init(void)
{
 
  /* USER CODE BEGIN USART2_Init 0 */
 
  /* USER CODE END USART2_Init 0 */
 
  /* USER CODE BEGIN USART2_Init 1 */
 
  /* USER CODE END USART2_Init 1 */
  huart2.Instance = USART2;
  huart2.Init.BaudRate = 9600;
  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.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart2) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART2_Init 2 */
 
  /* USER CODE END USART2_Init 2 */
 
}
 
/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
  /* DMA1_Channel2_3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
 
}
 
/**
  * @brief GPIO Initialization Function
  * @param None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOF_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(LD3_GPIO_Port, LD3_Pin, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : T_NRST_Pin */
  GPIO_InitStruct.Pin = T_NRST_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(T_NRST_GPIO_Port, &GPIO_InitStruct);
 
  /*Configure GPIO pin : LD3_Pin */
  GPIO_InitStruct.Pin = LD3_Pin;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(LD3_GPIO_Port, &GPIO_InitStruct);
 
}
 
/* USER CODE BEGIN 4 */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
	if(&huart2 == huart)
	{
		switch (huart->ErrorCode)
		{
		case HAL_UART_ERROR_ORE:	// Overrun error
			__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
			//commandEngine.um.errorCode = UM_ERROR_OVERRUN;
			break;
 
		case HAL_UART_ERROR_RTO:	// Receiver Timeout erro
			__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_RTOF);
			__HAL_UART_DISABLE_IT(huart, UART_IT_RTO);
			//commandEngine.um.errorCode = UM_ERROR_RX_TIMEOUT;
			break;
 
		case HAL_UART_ERROR_FE:		// Frame error
			__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_FEF);
			//commandEngine.um.errorCode = UM_ERROR_FRAME;
			break;
		}
	}
}
 
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if(&huart2 == huart)
	{
		usartBufferInLen = Size;
		usartBufferOutlen = Size;
		memcpy(usartBufferOut, usartBufferIn, usartBufferInLen);
		memset(usartBufferIn, 0, MAX_USART_BUF_IN);
		HAL_UARTEx_ReceiveToIdle_IT(huart, usartBufferIn, MAX_USART_BUF_IN);
		send = 1;
	}
}
/* 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.
  * @param  file: pointer to the source file name
  * @param  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 */

@tvill.1​ "I can't step my code, no ISR or event can be catched"

But, in the OP, you said:

"he reset after entering on the IRQ handler"

If it is really entering the IRQ handler, you should be able to break on that.

Have you tried putting a breakpoint on your Error_Handler() ?

Is that (also) your Hard Fault handler ?

tvill.1
Associate II

Yes i know but it was my first analyse but the step in IRQ handler is after the reset, when i call the first transmit_IT ;)

And i have put breakpoint on error handler and hard fault and the nmi handler, nothing happen