cancel
Showing results for 
Search instead for 
Did you mean: 

a problem in sending with Usart using GPDMA

HamedTahamtan
Associate II

Hi every one .

I have designed a new MCU circuit  board for my own purposes. I am using an stm32u575VGTX  MCU in this circuit board and for the first thing i need to send and receive data with UART .

As i don't want to busy the CPU just sending and receiving UART data , I decided to use GPDMA for this purpose.

But in this case i faced a problem . the data will receive in a good condition but when i want to transmit the data with GPDMA, if after transmiting every were i use

HAL_Delay(Delay)

after that hole uart dont work and i can not receive or send any data with uart

I tried to debug the code and I have got nothing more . just i now that the cpu is still  running after this problem and the code goes on   but uart won't send  data after that .

I tried to send data in normal way and i didn't face any problem in this case. the problem just cames when i want to send it using GPDMA and after that using

HAL_Delay(Delay)

also if i dont use this delay function i will not face any problem with usart

I am using STM32CubeIDE

here is an executable code that i faced the problem in it .

 

#include "main.h"
UART_HandleTypeDef huart3;
DMA_HandleTypeDef handle_GPDMA1_Channel7;
DMA_HandleTypeDef handle_GPDMA1_Channel6;

/* USER CODE BEGIN PV */
#define RxBuf_SIZE 		20
#define TxBuf_SIZE 		20
#define MainBuf_SIZE	40

uint8_t RxBuf[RxBuf_SIZE];
uint8_t TxBuf[TxBuf_SIZE] = "Count:  \r\n";
uint8_t MainBuf[MainBuf_SIZE];
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_GPDMA1_Init(void);
static void MX_MEMORYMAP_Init(void);
static void MX_USART3_UART_Init(void);
/* Private user code ---------------------------------------------------------*/
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/
  HAL_Init();
  SystemClock_Config();

  MX_GPIO_Init();
  MX_GPDMA1_Init();
  MX_MEMORYMAP_Init();
  MX_USART3_UART_Init();

  HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE);
  uint8_t u8Inc = 0x30; // 0x30 => ‘0’ ASCII

  while (1)
  {
	  	  	TxBuf[7] = u8Inc++;
	  		if(u8Inc > 0x39)
	  		{
	  			u8Inc = 0x30;
	  		}
	  		HAL_UART_Transmit_DMA(&huart3, TxBuf, 10);
	  		HAL_Delay(1000);
	  		HAL_UART_Transmit(&huart3, TxBuf, 10, 100);
	  		HAL_Delay(1000);
  }
}
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 1;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_PCLK3;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}
static void MX_GPDMA1_Init(void)
{
  __HAL_RCC_GPDMA1_CLK_ENABLE();
    HAL_NVIC_SetPriority(GPDMA1_Channel6_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(GPDMA1_Channel6_IRQn);
    HAL_NVIC_SetPriority(GPDMA1_Channel7_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(GPDMA1_Channel7_IRQn);
}
static void MX_MEMORYMAP_Init(void)
{

}
static void MX_USART3_UART_Init(void)
{
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
}
static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
}


void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if (huart->Instance== USART3)
	{
		HAL_UART_Transmit(&huart3, RxBuf, Size, 300);
		HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE);
	}
}
void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
  }
}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
HamedTahamtan
Associate II

Hi

I have to say that the problem with system clock config was just a Hardware problem and i just changed the mcu and it solved.

but about the hall uart dma , I noticed that when i use this function

 HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE);

it just recives maximum the half of RxBuf_SIZE

then disabled the DMA Half recive interrupt with this code

__HAL_DMA_DISABLE_IT(&handle_GPDMA1_Channel6,DMA_IT_HT);

I solved this problem .

I used this code every where exactly in  the line after I request a DMA receive Data.

 

View solution in original post

4 REPLIES 4
TDK
Guru

You have a blocking HAL_UART_Transmit call in your interrupt handler. The UART is probably getting into an overflow condition during this time.

Consider handling all transmission outside of the interrupt handler, or use DMA instead. Note that calling HAL_UART_Transmit_DMA from multiple contexts (main thread and interrupt handler) can cause those calls to fail.

If you feel a post has answered your question, please click "Accept as Solution".

I tried also to change it and use DMA or use it outside of the interrupt handler but the problem is still here.

consider of this example

#include "main.h"
UART_HandleTypeDef huart3;
DMA_HandleTypeDef handle_GPDMA1_Channel7;
DMA_HandleTypeDef handle_GPDMA1_Channel6;

/* USER CODE BEGIN PV */
#define RxBuf_SIZE 		20
#define TxBuf_SIZE 		20
#define MainBuf_SIZE	40

uint8_t RxBuf[RxBuf_SIZE];
uint8_t TxBuf[TxBuf_SIZE] = "Count:  \r\n";
uint8_t MainBuf[MainBuf_SIZE];
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_GPDMA1_Init(void);
static void MX_MEMORYMAP_Init(void);
static void MX_USART3_UART_Init(void);
/* Private user code ---------------------------------------------------------*/
int main(void)
{
  /* MCU Configuration--------------------------------------------------------*/
  HAL_Init();
  SystemClock_Config();

  MX_GPIO_Init();
  MX_GPDMA1_Init();
  MX_MEMORYMAP_Init();
  MX_USART3_UART_Init();

  HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE);
  uint8_t u8Inc = 0x30; // 0x30 => ‘0’ ASCII

  while (1)
  {
	  		HAL_Delay(100);
  }
}
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1;
  RCC_OscInitStruct.PLL.PLLM = 1;
  RCC_OscInitStruct.PLL.PLLN = 20;
  RCC_OscInitStruct.PLL.PLLP = 2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 1;
  RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1;
  RCC_OscInitStruct.PLL.PLLFRACN = 0;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2
                              |RCC_CLOCKTYPE_PCLK3;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
  {
    Error_Handler();
  }
}
static void MX_GPDMA1_Init(void)
{
  __HAL_RCC_GPDMA1_CLK_ENABLE();
    HAL_NVIC_SetPriority(GPDMA1_Channel6_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(GPDMA1_Channel6_IRQn);
    HAL_NVIC_SetPriority(GPDMA1_Channel7_IRQn, 0, 0);
    HAL_NVIC_EnableIRQ(GPDMA1_Channel7_IRQn);
}
static void MX_MEMORYMAP_Init(void)
{

}
static void MX_USART3_UART_Init(void)
{
  huart3.Instance = USART3;
  huart3.Init.BaudRate = 115200;
  huart3.Init.WordLength = UART_WORDLENGTH_8B;
  huart3.Init.StopBits = UART_STOPBITS_1;
  huart3.Init.Parity = UART_PARITY_NONE;
  huart3.Init.Mode = UART_MODE_TX_RX;
  huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart3.Init.OverSampling = UART_OVERSAMPLING_16;
  huart3.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart3.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart3.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart3, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart3, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart3) != HAL_OK)
  {
    Error_Handler();
  }
}
static void MX_GPIO_Init(void)
{
  __HAL_RCC_GPIOH_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
  __HAL_RCC_GPIOC_CLK_ENABLE();
}


void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
	if (huart->Instance== USART3)
	{
		//HAL_UART_Transmit(&huart3, RxBuf, Size, 300);
		HAL_UART_Transmit_DMA(&huart3, RxBuf, Size);
		HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE);
	}
}
void Error_Handler(void)
{
  __disable_irq();
  while (1)
  {
  }
}

#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{

}
#endif /* USE_FULL_ASSERT */

in this code when i receive a data that is longer than 10 byte then the micro just transmits the 10 first bytes .

but if there is no delay function inside the code then it works properly (i used a delay as a test inside the main while now). the problem apears  when i am using this delay function every where in the code. it is so weird :expressionless_face:

HamedTahamtan
Associate II

I have also explain some of my other experience may be it can clear ,where the problem comes from.

I tried to debug the code but now i faced a problem .

in

SystemClock_Config

when the device want to check this one and run into 

 

  if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)

 

inside the function the code catch this line

 

  if (VoltageScaling > PWR_REGULATOR_VOLTAGE_SCALE3)
  {
    MODIFY_REG(PWR->VOSR, (PWR_VOSR_VOS | PWR_VOSR_BOOSTEN), (VoltageScaling | PWR_VOSR_BOOSTEN));
  }

 

when the device want to run the code inside the if , the debugger will break down

HamedTahamtan
Associate II

Hi

I have to say that the problem with system clock config was just a Hardware problem and i just changed the mcu and it solved.

but about the hall uart dma , I noticed that when i use this function

 HAL_UARTEx_ReceiveToIdle_DMA(&huart3, RxBuf, RxBuf_SIZE);

it just recives maximum the half of RxBuf_SIZE

then disabled the DMA Half recive interrupt with this code

__HAL_DMA_DISABLE_IT(&handle_GPDMA1_Channel6,DMA_IT_HT);

I solved this problem .

I used this code every where exactly in  the line after I request a DMA receive Data.