Skip to main content
Nchen.1
Associate II
March 13, 2023
Solved

STM32F746VGT7 firmware update fails via UART

  • March 13, 2023
  • 4 replies
  • 3081 views

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

This topic has been closed for replies.
Best answer by Tesla DeLorean

Interrupts, expectations about reset conditions and clock speeds?

4 replies

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
March 13, 2023

Interrupts, expectations about reset conditions and clock speeds?

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Nchen.1
Nchen.1Author
Associate II
March 14, 2023

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);
 }

Piranha
Principal III
March 17, 2023

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

Nchen.1
Nchen.1Author
Associate II
March 23, 2023

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

Tesla DeLorean
Guru
March 23, 2023

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
Nchen.1
Nchen.1Author
Associate II
March 30, 2023

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

Piranha
Principal III
March 31, 2023

Sounds like there are some floating pins, which are detected by the system bootloader. Read the AN2606 sections "4.3 Hardware connection requirements" and "48 STM32G491xx/4A1xx devices bootloader". Especially this:

It is recommended to keep the RX pins of unused bootloader interfaces (USART_RX, SPI_MOSI, CAN_RX and USB D+/D- lines if present) at a known (low or high) level at the startup of the bootloader (detection phase). Leaving these pins floating during the detection phase might lead to activating unused interfaces.

Nchen.1
Nchen.1Author
Associate II
April 1, 2023

I actually missed that.

Right above this note, there are schemes that shows the typical connection for the mentioned lines, and D+ connected to a pull up relies on VBUS, which means it’s floating when USB disconnected.

As it’s not mentioned, what’s the recommended resistor value I need to choose? Is it matters for USB if it’s a pull up or down? It worked well with 100k but I don’t want to damage the USB communication for future uses