2023-08-11 05:43 AM
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 */
Solved! Go to Solution.
2023-08-16 12:56 AM
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.
2023-08-11 05:55 AM
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.
2023-08-14 12:52 AM
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:
2023-08-14 02:22 AM
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
2023-08-16 12:56 AM
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.