cancel
Showing results for 
Search instead for 
Did you mean: 

stm32g484 bootloader communication problems

RHert.1
Associate II

Hello everybody.

I have problems with uarts in the my bootloader. In the main program the communication works OK.
The client card is stm32g484 based.

The first problem:
After HAL_NVIC_SystemReset()from main app enter to bootloader and HAL_UART_Transmit() send data to host but host received nothing. HAL_UART_Transmit() returns HAL_OK but the sniffer received nothing.

The second problem:
50-70% of the times the bootloader stopped accepting the data after erasing the flash. The next time (power cycle) the program will work fine.

------------------------------------------------------------------
int main(void)
{
int16_t pack_left = 1, data_size;
uint32_t pack_offset;
flash_status status = FLASH_OK;
HAL_StatusTypeDef hal_status; //grom  21feb2024 vA1
 
  /* MCU Configuration--------------------------------------------------------*/
  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
 
/* Configure the system clock */
SystemClock_Config();
__enable_irq(); 
 
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_IWDG_Init();
  
HAL_IWDG_Refresh(&hiwdg); 
LoadComConfig();
HAL_IWDG_Refresh(&hiwdg); 
  
MX_LPUART1_UART_Init(UARTs.Uart4.BaudRate); 
MX_USART1_UART_Init(UARTs.Uart1.BaudRate);
MX_USART2_UART_Init(UARTs.Uart2.BaudRate);
MX_USART3_UART_Init(UARTs.Uart3.BaudRate);
  
 
HAL_UART_Receive_DMA(&hlpuart1, buffer4, ENTER_COUNT); 
HAL_UART_Receive_DMA(&huart1, buffer1, ENTER_COUNT);
HAL_UART_Receive_DMA(&huart2, buffer2, ENTER_COUNT);
HAL_UART_Receive_DMA(&huart3, buffer3, ENTER_COUNT);
 
uint32_t tickstart = HAL_GetTick();
while (
((HAL_UART_GetState(&huart1) != HAL_UART_STATE_READY) 
  || (HAL_UART_GetState(&huart2) != HAL_UART_STATE_READY) 
  || (HAL_UART_GetState(&huart3) != HAL_UART_STATE_READY)
  || (HAL_UART_GetState(&hlpuart1) != HAL_UART_STATE_READY)) 
  && ((HAL_GetTick() - tickstart) < BL_UART_DELAY))
{
HAL_IWDG_Refresh(&hiwdg);
}
 
uint8_t is_ok = 0;
if (HAL_UART_GetState(&huart1) == HAL_UART_STATE_READY)
{
for (int i = 0; i < ENTER_COUNT; i++)
{
if (buffer1[i] == ENTER_CHAR)
is_ok++;
}
huart = &huart1;
buffer = buffer1;
}
else if (HAL_UART_GetState(&huart2) == HAL_UART_STATE_READY)
{
for (int i = 0; i < ENTER_COUNT; i++)
{
if (buffer2[i] == ENTER_CHAR)
is_ok++;
}
huart = &huart2;
buffer = buffer2;
}
else if (HAL_UART_GetState(&huart3) == HAL_UART_STATE_READY)
{
for (int i = 0; i < ENTER_COUNT; i++)
{
if (buffer3[i] == ENTER_CHAR)
is_ok++;
}
huart = &huart3;
buffer = buffer3;
}
else if (HAL_UART_GetState(&hlpuart1) == HAL_UART_STATE_READY)
{
for (int i = 0; i < ENTER_COUNT; i++)
{
if (buffer3[i] == ENTER_CHAR)
is_ok++;
}
huart = &hlpuart1;
buffer = buffer4;
}
 
HAL_UART_DMAStop(&huart1);
__HAL_DMA_DISABLE_IT(&hdma_usart1_rx, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 
HAL_DMA_DeInit(huart1.hdmarx); 
HAL_UART_DMAStop(&huart2);
__HAL_DMA_DISABLE_IT(&hdma_usart2_rx, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 
HAL_DMA_DeInit(huart2.hdmarx); 
HAL_UART_DMAStop(&huart3);
__HAL_DMA_DISABLE_IT(&hdma_usart3_rx, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 
HAL_DMA_DeInit(huart3.hdmarx); 
HAL_UART_DMAStop(&hlpuart1); 
__HAL_DMA_DISABLE_IT(&hdma_lpuart1_rx, (DMA_IT_TC | DMA_IT_HT | DMA_IT_TE)); 
HAL_DMA_DeInit(hlpuart1.hdmarx); 
 
if (is_ok == ENTER_COUNT)
{
/*
* start package update
*/
tx_data[0] = (uint8_t)VERSION;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
 
/*
* flash erase
*/
for (uint32_t i = FLASH_APP_START_PAGE; i < FLASH_APP_END_PAGE; i++)
{
status = Flash_Erase(i, 1);
tx_data[0] = (uint8_t)status;
HAL_IWDG_Refresh(&hiwdg);
HAL_Delay(50);
if (status != FLASH_OK)
{
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler(); //error 
}
}
 
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
/*
* write to flash
*/
 
do
{
uint8_t sum = 0;
/*
* start byte
*/
do
{
hal_status = HAL_UART_Receive(huart, buffer, 1, 100000);
if (hal_status != HAL_OK)
{
tx_data[0] = (uint8_t)COM_ERROR;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler();
}
HAL_IWDG_Refresh(&hiwdg);
} while (buffer[0] != START_CHAR);
sum = buffer[0];
 
/*
* read package header
*/
hal_status = HAL_UART_Receive(huart, buffer, MESSAGE_HEADER, 100000); 
if (hal_status != HAL_OK)
{
tx_data[0] = (uint8_t)COM_ERROR;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler();
}
HAL_IWDG_Refresh(&hiwdg);
 
/*
* unpacking the package
*/
//Pack Offset
((uint8_t*)&pack_offset)[0] = buffer[0];
((uint8_t*)&pack_offset)[1] = buffer[1];
((uint8_t*)&pack_offset)[2] = buffer[2];
((uint8_t*)&pack_offset)[3] = buffer[3];
if ((pack_offset & 0x08) != 0)
{
//offset error
tx_data[0] = (uint8_t)DATA_OFFSET_ERROR;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler(); //error 
}
  
//Pack left
((uint8_t*)&pack_left)[0] = buffer[4];
((uint8_t*)&pack_left)[1] = buffer[5];
 
//Data size
((uint8_t*)&data_size)[0] = buffer[6];
((uint8_t*)&data_size)[1] = buffer[7];
for (int8_t i = 0; i < MESSAGE_HEADER; i++)
{
sum += buffer[i];
}
HAL_IWDG_Refresh(&hiwdg);
 
/*
* read data
*/
hal_status = HAL_UART_Receive(huart, buffer, data_size + 1, 100000); 
if (hal_status != HAL_OK)
{
tx_data[0] = (uint8_t)COM_ERROR;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler();
}
HAL_IWDG_Refresh(&hiwdg);
 
 
for (int i = 0; i < data_size; i++)
{
sum += buffer[i];
}
 
/*
* check CS
*/
if (sum != buffer[data_size])
{
//CS error
tx_data[0] = (uint8_t)COM_ERROR_CS;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler(); //error 
}
 
if ((data_size & 0b0111) != 0) //if (mod(data_size,8))
{
if (pack_left != 0)
{
tx_data[0] = (uint8_t)DATA_SIZE_ERROR;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler(); //error 
}
else
{
//fill to 64bit
for (int i = 0; i < 8; i++)
tx_data[data_size + i] = 0xff;
data_size = (data_size + 8) & 0xfff8;
}
}
 
HAL_IWDG_Refresh(&hiwdg);
 
//write to flash
status = Flash_Write(FLASH_APP_START_ADDRESS + pack_offset, (uint64_t *)buffer, data_size);
tx_data[0] = (uint8_t)status;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
if (status != FLASH_OK)
Error_Handler(); //error
  
} while (pack_left != 0);
}
 
//go to main project
 
HAL_UART_DeInit(&huart1);
HAL_UART_DeInit(&huart2);
HAL_UART_DeInit(&huart3);
HAL_RCC_DeInit();
HAL_DeInit();
 
__disable_irq();
extern void* _app_start[];
SCB->VTOR = _app_start;
((void(*)())_app_start[1])();
}
-----------------------------
static void MX_LPUART1_UART_Init(uint32_t BaudRate)
{
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = BaudRate;
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_DIV10; //UART_PRESCALER_DIV1;
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
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();
}
}
--------------------------- 
initializing of usart1,usart2,usart3 it same
--------------------------- 
static void MX_USART1_UART_Init(uint32_t BaudRate)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = BaudRate;
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.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();
}
}
5 REPLIES 5
Imen.D
ST Employee

Hello @RHert.1,

The first behavior may be due to the device limitation described in the STM32G4xx Errata sheet:

ImenD_0-1708960364093.png

For the second issue related to bootloader: which bootloader version are you using?

 

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
Pavel A.
Evangelist III

 

/*
* check CS
*/
if (sum != buffer[data_size])
{
//CS error
tx_data[0] = (uint8_t)COM_ERROR_CS;
HAL_UART_Transmit(huart, tx_data, 1, HAL_MAX_DELAY);
Error_Handler(); //error 
}

 

Who wrote this code? Calling Error_Handler because of intermittent CRC errors is insane. If you get a bad checksum in the buffer, retry the affected portion of the data. Use a decent serial download protocol such as Ymodem. Check and clean up other error conditions, especially overrun, noise; also in the very beginning of the program - in case the host sent data while the MCU was booting and caused overrun.

If this is too hard or no time/resources, here you can summit help.

 

Hi Imen.
Thanks for the quick response
1. I'll check it.
2. This is my bootloader.

Hi Pavel.
It's my code. I need support specific protocol. Handling the CRC error is a temporary solution.

Regarding "check and clear other error conditions" could you detail more?

 

Hi Pavel.

Thank you very much. I fixed the second problem.

static void ClearCom(UART_HandleTypeDef* huart)
{
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_OREF);
__HAL_UART_CLEAR_FLAG(huart, UART_CLEAR_NEF);
}
 
Do you have any idea why the transmit doesn't work after HAL_NVIC_SystemReset()?