cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F746VGT7 firmware update fails via UART

Nchen.1
Associate III

Hi all,

I'm having a firmware issue with updating my MCU via UART

After reading AN2606 and AN3155, I try to do the following:

  • Disable all interrupts and save a register with unique value
  • Call system reset
  • Jump to bootloader on the beginning of SystemInit
  • Update the FW via USART1 (PA9, PA10) with baudrate 115200

What I get is a fallback to baudrate 1200, which means baudrate auto detection failed.

I have to mention that it works well in the same method I describe with USART3 (PB10, PB11) and it also works on USART1 (PA9, PA10) if I'm remove my code logic and jump to bootloader from the same place (SystemInit)

I still couldn't figure it out and would appreciate if someone could help me

Thanks for your help

1 ACCEPTED SOLUTION

Accepted Solutions

Interrupts, expectations about reset conditions and clock speeds?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

View solution in original post

11 REPLIES 11

Interrupts, expectations about reset conditions and clock speeds?

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thanks for your respond

I'm using 12 MHz HSE clock and HCLK is 216 Mhz

Before calling the ResetHandler I do this:

RCC->APB1ENR |= RCC_APB1ENR_PWREN;
	PWR->CR1 |= PWR_CR1_DBP;
	RTC->BKP0R = 1;
 
	HAL_RCC_DeInit();
	SysTick->CTRL = 0;
	SysTick->LOAD = 0;
	SysTick->VAL = 0;
	__disable_irq();
	for (int x = 0; x < 8; x++)
	{
		NVIC->ICER[x] = 0xFFFFFFFF;
		NVIC->ICPR[x] = 0xFFFFFFFF;
	}
	HAL_NVIC_SystemReset();

After the reset I do this:

    if (RTC->BKP0R == 1)
    {
        RCC->APB1ENR |= RCC_APB1ENR_PWREN;
        PWR->CR1 |= PWR_CR1_DBP;
        RTC->BKP0R = 0;
        volatile isrVector_t *bootloaderVector = (isrVector_t *)systemBootloaderAddress();
        __set_MSP(bootloaderVector->stackEnd);
        bootloaderVector->resetHandler();
        while (1);
    }

I managed to fixed it, it appeared that I had two SystemInit functions and I actually had some interrupts enabled.

Thank you very much

Piranha
Chief II

What's the point of all those de-initializations, if you are doing a system reset anyway? ;)

Actually I've followed others code and found this pattern, after it finally worked, I didn't think to try it without system reset :)

Now I stuck on making it work for G4746 MCU :grinning_face_with_sweat:

Same issue, DFU from USB works well but USART cannot perform the update

The problem is most try to do the control transfer on a system running all kinds of interrupts. The idea generally is the reset, and then immediately transfer control.

You don't need to do a lot before HAL_NVIC_SystemReset();

You don't want to hand a broken system off to bootloaderVector->resetHandler();

You shouldn't __disable_irq(); as this doesn't get undone by the loader.

You should avoid changing the SP mid function.

The UART expects 8E1 (Even Parity) for the 0x7F test pattern. Scope the signal make sure it's not glitching, and that you give enough time between doing a reset and sending a pattern. Make sure your UART output pin is high before reset.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

The UART output pins are high before reset, I also added 10k pull up to ensure that. both Rx and Tx are glitching at the time I call bootloaderVector->resetHandler(). Rx signal receive 0x7F but no respond transmitted on Tx.0693W00000aJmrtQAC.jpg 

I removed __disable_irq() and not calling HAL_NVIC_SystemReset(), but it didn't change the situation.

After moving the boot jump to be called before SystemClock_Config() it worked, so I looked for the issue inside this function and found that RCC->CCIPR CLK48SEL was enabled so I set RCC->CCIPR = 0 before the transfer.

With this fix, I tried again to update the FW and I see that if I my software is running for more than ~450 ms (just used HAL_Delay for that before the main loop), it fails to upgrade, and again no respond seen on TX.

I suspect I might not disabled all PLLs properly, but it's after I've tried to use __HAL_RCC_PLL_DISABLE();

Thanks for your help

Nchen.1
Associate III

I finally managed to fix the issue for G4 MCU!

I was pretty confident that I had a SW issue because FW update from UART worked using BOOT0 pin, but it didn't when I jumped to system memory from SW.

On one try, I had the USB cable connected on the MCU side, and disconnected from the host side, and it appeared to work. I thought, it was a coincidence, but I managed to find a pattern.

Long story short, after using a 100K ohm resistor for at least one of DP or DM lines (and even when I just used scope on these lines, which means ~1M ohm), UART update worked successfully.

I don't know if it's the right solution from EMI aspects, but it's sufficient for me.

None of these happened on F7 MCU, so it might be something in G4 series, or you might have some explanation for this