cancel
Showing results for 
Search instead for 
Did you mean: 

Really basic question about HAL_USART_RxCpltCallback function

JBee.1
Associate II

Hello everyone!

I'm trying to setup a very basic application and currently have my LPUART Tx and Rx pins tied together. I'm able to run the following code without any issues (well, this is the core of the code with all the initializations stripped out for quick, readability purposes) :

uint8_t TX1_Char = 0x01;
uint8_t RX1_Char = 0x00;
 
int main(void)
{
  while(1)
  {
	HAL_UART_Transmit(&hlpuart1, &TX1_Char, sizeof(TX1_Char), 100);
	HAL_UART_Receive_IT(&hlpuart1, &RX1_Char, 1);
 
	RX1_Char = 0;
 
	HAL_Delay(100);
  }
}

Obviously, all it's doing is sending TX1_Char (value of 1) to RX1_Char. Pretty straight forward.

What I want to do is have it run the HAL_UART_RECEIVE_IT function from the HAL_USART_RxCpltCallback function and receive it there. So this is essentially what I'm trying to do:

uint8_t TX1_Char = 0x01;
uint8_t RX1_Char = 0x00;
 
int main(void)
{
  while(1)
  {
	HAL_UART_Transmit(&hlpuart1, &TX1_Char, sizeof(TX1_Char), 100);
	//HAL_UART_Receive_IT(&hlpuart1, &RX1_Char, 1);
 
	RX1_Char = 0;
 
	HAL_Delay(100);
  }
}
 
void HAL_USART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Receive_IT(&hlpuart1, &RX1_Char, 1);
}

Unfortunately, I can't seem to get it to call the HAL_USART_RxCpltCallback function . . . I assume my issue is I missed something pretty straight forward (like starting the LPUART interrupt or something to that effect). I have it setup to have a global interrupt for the LPUART with priority 2.

Full disclosure, I did use the *.ioc file to setup most the parameters so it could be a setting issue in the *.ioc file. Regardless, here's my initialization function (if it helps):

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 = 31250;
  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.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
  if (HAL_UART_Init(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LPUART1_Init 2 */
 
  /* USER CODE END LPUART1_Init 2 */
 
}

As I mentioned above, I removed most the initializations (clock, other peripherals, etc) for readability purposes so if I'm missing something else crucial here that might help resolve this, let me know and I can easily post the full code!

I assume I'm missing something really dumb since this should be a relatively straight forward example . . . Unfortunately, I've been looking through the forums and haven't been able to find the solution so I thought I'd put a post up.

Any info you can give me to help me trigger the HAL_USART_RxCpltCallback function would be greatly appreciated. Thanks!

Oh, and in the odd chance it helps, I'm using an STM32WB55 nucleo development board. Thanks!

4 REPLIES 4
TDK
Guru

> I assume my issue is I missed something pretty straight forward

You need to start the reception somewhere. You commented it out. Start it once prior to the main() loop, then starting it again from within RxComplete should work fine.

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

Yeah, that's actually one of the things I had tried as well but it didn't seem to work for me either, oddly enough (had seen it in someone else's example project).

Here's what I tried:

 uint8_t temp_Char = 0x01;
 HAL_UART_Receive_IT(&hlpuart1, &temp_Char, 1);
 
int main(void)
{
  while(1)
  {
	HAL_UART_Transmit(&hlpuart1, &TX1_Char, sizeof(TX1_Char), 100);
	//HAL_UART_Receive_IT(&hlpuart1, &RX1_Char, 1);
 
	RX1_Char = 0;
 
	HAL_Delay(100);
  }
}
 
void HAL_USART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Receive_IT(&hlpuart1, &RX1_Char, 1);
}

Even tried uncommenting that line just to jumpstart it but no luck. Still won't call the callback function. It does look a bit funny how it's implemented above (with the temp character) but that mainly has to do with me having the structure setup so that the whole main loop is actually being called repeatedly from the main file but the functionality is in another file (hence the tempvar rather than using the same one). This was to avoid me accidentally wiping everything if I did something stupid with the code placement and wiping it when updating the *.ioc file (which, I'll admit, i did once in a previous project).

That said, I did put a breakpoint in the callback function here as well as the weak one it's replacing in the Hal Uart file:

__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(huart);
 
  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_UART_RxCpltCallback can be implemented in the user file.
   */
}

It didn't make it to that unused portion as well. Based on this, all signs seem to suggest there's an issue with setting up the NVIC for the UART, right? Not sure what else it might be if it's not opening up either of these. There aren't really too many settings to setup though so I'm a bit confused as to why that might've caused the issue . . .

0693W000005A70wQAC.png0693W000005A70rQAC.pngAm I missing something?

Thanks for the help!

TDK
Guru

There's a few things wrong here. Your main function doesn't even call MX_LPUART1_UART_Init. Just calling HAL_UART_Transmit isn't going to do anything. You can't execute statements outside of functions. HAL_UART_Receive_IT needs to be within a function.

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

Heh, yeah, I was actually kinda expecting this and should've just uploaded everything initially. I actually did have the inits in there, it's just not in the code above as I reduced it to make it easier to read (at the cost of having all the pertinent info, unfortunately). Here it is in full (ish, had to remove some of the other inits as it was too long to include here, unfortunately), if this ends up helping:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
  * All rights reserved.</center></h2>
  *
  * This software component is licensed by ST under BSD 3-Clause license,
  * the "License"; You may not use this file except in compliance with the
  * License. You may obtain a copy of the License at:
  *                        opensource.org/licenses/BSD-3-Clause
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;
 
I2C_HandleTypeDef hi2c1;
 
UART_HandleTypeDef hlpuart1;
UART_HandleTypeDef huart1;
 
SPI_HandleTypeDef hspi1;
 
PCD_HandleTypeDef hpcd_USB_FS;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_USB_PCD_Init(void);
static void MX_ADC1_Init(void);
static void MX_LPUART1_UART_Init(void);
static void MX_I2C1_Init(void);
static void MX_SPI1_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_USART1_UART_Init();
  MX_USB_PCD_Init();
  MX_ADC1_Init();
  MX_LPUART1_UART_Init();
  MX_I2C1_Init();
  MX_SPI1_Init();
  /* USER CODE BEGIN 2 */
  uint8_t temp_Char = 0x01;
  HAL_UART_Receive_IT(&hlpuart1, &temp_Char, 1);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
	  run_main();
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief LPUART1 Initialization Function
  * @param None
  * @retval None
  */
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 = 31250;
  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.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  hlpuart1.FifoMode = UART_FIFOMODE_DISABLE;
  if (HAL_UART_Init(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&hlpuart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&hlpuart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&hlpuart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN LPUART1_Init 2 */
 
  /* USER CODE END LPUART1_Init 2 */
 
}
 
/**
  * @brief USART1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_USART1_UART_Init(void)
{
 
  /* USER CODE BEGIN USART1_Init 0 */
 
  /* USER CODE END USART1_Init 0 */
 
  /* USER CODE BEGIN USART1_Init 1 */
 
  /* USER CODE END USART1_Init 1 */
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 115200;
  huart1.Init.WordLength = UART_WORDLENGTH_7B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
  huart1.Init.ClockPrescaler = UART_PRESCALER_DIV1;
  huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetTxFifoThreshold(&huart1, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_SetRxFifoThreshold(&huart1, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_UARTEx_DisableFifoMode(&huart1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN USART1_Init 2 */
 
  /* USER CODE END USART1_Init 2 */
 
}
 
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
uint8_t TX1_Char = 0x01;
uint8_t RX1_Char = 0x00;
 
uint8_t MSG1[] = "Button State: Released\r\n";
uint8_t MSG2[] = "Button State: Pressed\r\n";
 
void run_main()
{
	HAL_UART_Transmit(&hlpuart1, &TX1_Char, sizeof(TX1_Char), 100);
	//HAL_UART_Receive_IT(&hlpuart1, &RX1_Char, 1);
 
	RX1_Char = 0;
 
	HAL_Delay(100);
}
 
void HAL_USART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	HAL_UART_Receive_IT(&hlpuart1, &RX1_Char, 1);
}

Sorry, I know it's kinda hard to troubleshoot issues without all the info . . . but I also know no one wants to read through giant masses of code either . . . Thanks for your patience!

It was too long to post all of it so it mainly has my run_main() code (in a separate *.c file, hence the separate code snippet), as well as the separate *.h files as well. If I'm missing anything else that might be helpful, let me know and I can upload it. If this ends up being too much of a pain, let me know and I can just zip up the project and upload the link to it (not trying to give anyone homework though, hoping it's something I just missed that can be spotted. I didn't think this was going to be a difficult application so I was a bit confused that I'm having this much trouble with it . . . heh).

Thanks again for the help!