Skip to main content
Visitor II
February 26, 2024
Question

stm32g484 bootloader communication problems

  • February 26, 2024
  • 2 replies
  • 2045 views

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();
}
}
    This topic has been closed for replies.

    2 replies

    Technical Moderator
    February 26, 2024

    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?

     

    RHert.1Author
    Visitor II
    February 28, 2024

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

    Super User
    February 26, 2024

     

    /*
    * 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.

     

    RHert.1Author
    Visitor II
    February 28, 2024

    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?

     

    RHert.1Author
    Visitor II
    February 28, 2024

    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()?