cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_Receive_IT skips bytes from RN2483 lorawan module

KStan.2
Associate

Hi,I want to use a lorawan device with my stm32 l053r8 microcontroller.

To do this, i reset the lora module initially. In Response I should get the firmware version of the device, but i receive only parts of the string, e.g. some bytes between the string are missing. It Global interrupt ist enabled. I already tested UART_ABORT_IT in between with the same result (some other bytes are missing)

i looket into this with an oszilloskop and that shows, that command (e.g. ("sys get hweui\r\n)) gets sent and the module responses data.

code:

// callback
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    rxBuffer[counter++] = rxValue;
    HAL_UART_Receive_IT(&huart1, &rxValue, 1);
}
 
// main
{
...
HAL_UART_Receive_IT(&huart1, &rxValue, 1);
HAL_GPIO_TogglePin(lora_reset_GPIO_Port, lora_reset_Pin) // reset lora module
...
}
 
// init of uart
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 57600;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  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.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    Error_Handler();
  }

5 REPLIES 5
Karl Yamashita
Lead III

is HAL_UART_Receive_IT in main before a while loop?

Also, You are not looking at the HAL return status. Once HAL does not return HAL_OK, you're interrupts will no longer work.

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
Johi
Senior III

57600 is not extremely high so interrupt based receive should be possible.

Can you show us the rest of the relevant code you are using?

Are your buffers and counters volatile? I think HAL_UART_RxCpltCallback is called from an ISR context.

Are there other interrupt handlers that could take priority over the rest?

KStan.2
Associate

Thanks for your replies!

@Community member​ Yes, receive_it was in main before the while loop.

@Johi​ I tested the code with volatile buffer and counter, same result. There are no other interrupt handler that i can see. I thought the code i posted is the only relevant part, the rest is generated by STM32CubeIDE. What parts are missing?

I also tested my Code without interrupt (e.g. blocking calls) and i get the desired results:

char* sendCommand(char *command, int shouldPrintResponse, int shouldReturnResponse) {
	uint8_t *responseBuffer = calloc(200, sizeof (uint8_t));
	uint8_t responseValue;
	int curCounter = 0;
 
	HAL_UART_Transmit(&huart1, (uint8_t *) command, strlen(command), 5000);
 
	do {
		HAL_UART_Receive(&huart1, &responseValue, 1, 1000);
		responseBuffer[curCounter++] = responseValue;
	} while (responseValue != '\n' && curCounter <= 200);
 
	if (shouldPrintResponse == 1) {
		HAL_UART_Transmit(&huart2, responseBuffer, curCounter, 1000);
	}
 
	if (shouldReturnResponse) {
		return (char *) responseBuffer;
	} else {
		free(responseBuffer);
		return NULL;
	}
}
 
 
 
// in main:
{
...
  HAL_GPIO_TogglePin(lora_reset_GPIO_Port, lora_reset_Pin);
  HAL_Delay(500);
 
  // skip firmware version response after startup
  HAL_UART_AbortReceive(&huart1);
 
  sendCommand("sys get hweui\r\n", 1, 0);
  sendCommand("sys get ver\r\n", 1, 0);
....
}

I cant figure out, why bytes are skiped in the UART_IT version

Karl Yamashita
Lead III

Well on your first post you don't show all relevant code.

  • Not sure what is happening with counter outside of the function.
  • Your rxBuffer needs to be declared outside of HAL_UART_RxCpltCallback as global. When you return from that callback, rxBuffer is no longer considered valid and the address it resides in can be used by other variables.
  • How are you checking that you have received a new character? You don't set a flag.

Depending on your device, you're probably better off using DMA with HAL_UARTEx_ReceiveToIdle_DMA with HAL_UARTEx_RxEventCallback. It can be used to receive any variable length binary/string. You just use a size of data elements greater than the longest string you're expecting to receive from the module.

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
Johi
Senior III

@KStan.2, is this topic still pending or did you find the solution?