cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L072C6T6 LPUART DMA interrupt need Reset MCU to works

MLam
Associate III

Hi everyone,

I'm working on a project with an STM32L072C6T6.

I'm using LPUART1 DMA to get data from my LPUART with interrupt when the bus go idle.

My soft working when, after power on the device, i push the reset button of the MCU. All start correctly.

But when I try turn on my device with only power ON, no interrupt from LPUART occur.

  • I have verify my data send on my LPUART bus, it's OK (all data receive and good quality of signal)
  • I use DMA for LPUART and USART1 and USART1 works great with every power on method and i have implement LPUART in the same way that USART1
  • I have debug the DMA state (HAL_DMA_GetState) and i have seen that when my error occur it's because my DMA state for LPUART stay ready and never become busy like my USART1.
  • I check in the same time DMA error (HAL_DMA_GetError) but no error occur

Do you have advice that can put me on a way of a solution ?

I attached CubeMX configuration screen and function that i use to use the LPUART DMA.

Best regards,

Lam

void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if (huart->Instance == LPUART1)
	{
		
		//do something
                printf("LPUART1\r\n");
		
		/* start the DMA again */
		memset(lpuart1_Rx_data, 0, sizeof(lpuart1_Rx_data));
		HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1, lpuart1_Rx_data, sizeof(lpuart1_Rx_data));
		__HAL_DMA_DISABLE_IT(&hdma_lpuart1_rx, DMA_IT_HT);
 
	}
	
	if (huart->Instance == USART1)
	{
		//printf("INT USART1\r\n");
				
		/* start the DMA again */
		memset(usart1_Rx_data, 0, sizeof(usart1_Rx_data));
		HAL_UARTEx_ReceiveToIdle_DMA(&huart1, usart1_Rx_data, sizeof(usart1_Rx_data));
		__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
		
	}
	
}
 
//-------------------------------
 
int main(void)
{
  /* USER CODE BEGIN 1 */
	clear_led();
	
  /* 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_I2C1_Init();
  MX_LPUART1_UART_Init();
  MX_USART1_UART_Init();
  MX_ADC_Init();
  MX_USB_DEVICE_Init();
  MX_LPTIM1_Init();
  MX_RTC_Init();
  /* USER CODE BEGIN 2 */
 
	Init_Context();
 
	//Enable LPUART for RF interrupt
	HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1, lpuart1_Rx_data, sizeof(lpuart1_Rx_data));
	__HAL_DMA_DISABLE_IT(&hdma_lpuart1_rx, DMA_IT_HT);
 
	//Enable USART1 for Keyboard RFID
	HAL_UARTEx_ReceiveToIdle_DMA(&huart1, usart1_Rx_data, sizeof(usart1_Rx_data));
	__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, DMA_IT_HT);
	
	//verify if DMA is correctly init
	getDMA_init();
	
	//test_main();
	
		
#ifdef DEBUG_PRINT
	printf("*** DEBUG FIRMWARE ***\r\n");
#endif
 
while(1)
{
}
 
}
 
//------------------------------------
 
static void MX_LPUART1_UART_Init(void)
{
 
  /* USER CODE BEGIN LPUART1_Init 0 */
 
  /* USER CODE END LPUART1_Init 0 */
 
  /* USER CODE BEGIN LPUART1_Init 1 */
 
  /* USER CODE END LPUART1_Init 1 */
  hlpuart1.Instance = LPUART1;
  hlpuart1.Init.BaudRate = 9600;
  hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
  hlpuart1.Init.StopBits = UART_STOPBITS_1;
  hlpuart1.Init.Parity = UART_PARITY_NONE;
  hlpuart1.Init.Mode = UART_MODE_TX_RX;
  hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LPUART1_Init 2 */
 
  /* USER CODE END LPUART1_Init 2 */
 
}
 
//---------------------------------
 
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA1_Channel2_3_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel2_3_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel2_3_IRQn);
  /* DMA1_Channel4_5_6_7_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn);
 
}
 
//----------------------------
 
void getDMA_init(void)
{
	//Waiting DMA hardware initialization
	uint8_t draw_wait_state = 0;
	uint32_t counter;
	HAL_DMA_StateTypeDef test;
	uint32_t test2;
	test = HAL_DMA_GetState(&hdma_lpuart1_rx);
	printf("dma lpuart1 : %x", test);
	test = HAL_DMA_GetState(&hdma_usart1_rx);
	printf("dma usart1 : %x", test);
	test2 = HAL_DMA_GetError(&hdma_lpuart1_rx);
	printf("dma lpuart1 error : %lu", test2);
	test2 = HAL_DMA_GetError(&hdma_usart1_rx);
	printf("dma usart1 error: %lu", test2);
}

3 REPLIES 3
MLam
Associate III

News about my problem,

I have try to get information about my LPUART state. So i use this functions to get informations : HAL_UART_GetState(&hlpuart1) and HAL_UART_GetError(&hlpuart1).

I use this functions after uart init and i ahve this results : lpuart 1 state : 34 lpuart 1 error : 0

I use this just before my function that want to receive and send data throught LPUART1 and i obtain this results : lpuart 1 state : 32 lpuart 1 error : 0

I understand that i have an error on my LPUART1 apparently. But i don't understand the cause and why this occur only sometimes.

I joined below my code to check error.

Do you have advice about this error ?

void getDMA_init(void)
{
	//Waiting DMA hardware initialization
	uint8_t draw_wait_state = 0;
	uint32_t counter;
	HAL_DMA_StateTypeDef test;
	uint32_t test2;
	HAL_UART_StateTypeDef test3;
	test = HAL_DMA_GetState(&hdma_lpuart1_rx);
	printf("dma lpuart1 : %x ", test);
	test = HAL_DMA_GetState(&hdma_usart1_rx);
	printf("dma usart1 : %x ", test);
	test2 = HAL_DMA_GetError(&hdma_lpuart1_rx);
	printf("dma lpuart1 error : %lu ", test2);
	test2 = HAL_DMA_GetError(&hdma_usart1_rx);
	printf("dma usart1 error: %lu \r\n", test2);
	test3 = HAL_UART_GetState(&hlpuart1);
	printf("lpuart 1 state : %lu ",(uint32_t)test3 );
	printf(" lpuart 1 error : %lu \r\n", HAL_UART_GetError(&hlpuart1));
}

Dear @MLam​ 

Regarding UART state values you mentioned, i don't think this indicates an error.

32 => 0x20 indicates Initialisation has been done an no TX or RX activity is ongoing. No error reported.

34 => 0x22 indicates Initialization is done, and a RX process is ongoing.

Regarding your problem, when nothing seems to appear on reception side, could you check the LPUART ISR register content when this occurs ? One hypothesis could be that Overrun flag is set, preventing any further reception until it is cleared.

Just an idea ...

Hope this helps

MLam
Associate III

Hello,

Thanks for you return,

I found a solution to solve my problem when my device boot,

if (HAL_UART_GetState(&hlpuart1) == 32)	// on power-on LPUART/DMA meet problem to start interrupt maybe due of power-on of the module connected so we need to reinitialize LPUART and DMA
	{
		HAL_UART_Abort_IT(&hlpuart1);
		HAL_UART_DMAStop(&hlpuart1);
		MX_LPUART1_UART_Init();
		//Enable LPUART for RF interrupt
		HAL_UARTEx_ReceiveToIdle_DMA(&hlpuart1, lpuart1_Rx_data, sizeof(lpuart1_Rx_data));
		__HAL_DMA_DISABLE_IT(&hdma_lpuart1_rx, DMA_IT_HT);
		
	}

I'm agree that not the better solution but that allow my program to receive the frames with interrupt.

Since this time my program has evolve and i start with USART and after LPUART, i don't need to use this code and i don't meet this error.

Best regards,

MLam