Author Topic: STM32 USB boot conundrum  (Read 3691 times)

0 Members and 1 Guest are viewing this topic.

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
STM32 USB boot conundrum
« on: November 16, 2022, 12:14:25 pm »
I am designing a (hobby) project around an STM32F3. The device will have a LiPo battery, and is meant to have a "soft" power switch and the ability to go into standby on its own after a timeout, implemented simply via the STM32's Standby mode. So the regulated VDD supply voltage will always be present, to enable the processor to wake up again when the soft-power button is pressed.

The device will also have a USB port, for charging the battery and for an optional data connection. This particular STM32 processor does not have an integrated 1.5k pullup on USB_DP, so I need to provide that externally. USB enumeration should occur when the STM32 is woken up, and must not be tried in vain when a sleeping STM32 is connected to the host. So I intend to connect the 1.5k pullup to a GPIO pin of the STM32 rather than to VDD, and set that pin high in my code when the STM32 wakes up.

So far, so good.

But now I also want to use the STM32 boot loader to enable firmware updates via USB. There will be a jumper for the BOOT0 pin to select booting from flash vs. USB. But how do I get the 1.5k pullup to be activated when the boot loader kicks in?! Is there any GPIO pin which the boot loader or the hardware sets high? Is there another trick, e.g. some other side effect of the STM32 waking up? I would like to avoid additional hardware (external flip-flop or such) if possible.

Thanks for your ideas!
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6430
  • Country: es
Re: STM32 USB boot conundrum
« Reply #1 on: November 16, 2022, 01:32:55 pm »
You don't really need the power to be present, lots of regulators have Enable input, so just wire than pin to the button and the stm32, once the STM32 boots it should latch the pin to keep the power enabled.
As far as I know, the bootloader will handle the usb automatically, including the pullup, you don't need to configure anything.

Also, you can boot into the bootloader without physically modifying BOOT pins, issuing a direct call from your firmware:

https://stackoverflow.com/questions/26891432/jump-to-bootloader-in-stm32-through-application-i-e-using-boot-0-and-boot-1-pins
https://stm32f4-discovery.net/2017/04/tutorial-jump-system-memory-software-stm32/
https://michaeltien8901.github.io/2020/05/30/Jump-to-Internal-Bootloader-STM32F4.html
« Last Edit: November 16, 2022, 01:34:30 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: ebastler

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7295
  • Country: fi
    • My home page and email address
Re: STM32 USB boot conundrum
« Reply #2 on: November 16, 2022, 01:50:23 pm »
So I intend to connect the 1.5k pullup to a GPIO pin of the STM32 rather than to VDD, and set that pin high in my code when the STM32 wakes up.
[...]
But how do I get the 1.5k pullup to be activated when the boot loader kicks in?!
[...]
I would like to avoid additional hardware (external flip-flop or such) if possible.
AN2606: STM32 microcontroller system memory boot mode describes the boot loader (DFU, for USB).

As far as I can see, a transistor with a weak resistor to enable it by default, that a GPIO pin can disable by driving it, seems like a requirement to me.

Unless, of course, you switch to boot loader using a jump from your own code, as described in the abovementioned appnote.
 
The following users thanked this post: ebastler

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #3 on: November 16, 2022, 02:22:33 pm »
Thank you both!

You don't really need the power to be present, lots of regulators have Enable input, so just wire than pin to the button and the stm32, once the STM32 boots it should latch the pin to keep the power enabled.
But if the STM32 boots into the bootloader (rather than my own code), it won't set that pin, right?

Quote
As far as I know, the bootloader will handle the usb automatically, including the pullup, you don't need to configure anything.
No, as mentioned my STM32F3 does not have an internal pullup for the USB data line. Some of the STM32 series do have it, some don't.


AN2606: STM32 microcontroller system memory boot mode
describes the boot loader (DFU, for USB).

As far as I can see, a transistor with a weak resistor to enable it by default, that a GPIO pin can disable by driving it, seems like a requirement to me.

Unless, of course, you switch to boot loader using a jump from your own code, as described in the abovementioned appnote.

I had tried my luck with AN2606 and found it helpful to understand how the bootloader decides which serial interface to boot from. But did not find anything about additional outputs driven by the bootloader -- which probably means it does not do that...

If I had the 1.5k pullup activated by a transistor by default -- how would I keep it disabled while the STM32 is in standby mode? I understand that all GPIOs go to high impedance state while the STM32 is on standby. And unfortunately it seems they stay like this while the bootloader is doing its thing. Hence I can't distinguish between "standby" and "booting" state, unless I add some extra logic which latches the wakup button press?

Not taking the direct route to the bootloader (via BOOT0) but calling it from my own code would be an option. Not as bulletproof though, in case I upload some messed-up code. And I would still need to provide a separate SW/JTAG interface for the initial upload.

Maybe I will just add another jumper for forcing the USB pullup high when the BOOT0 jumper is set?
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7295
  • Country: fi
    • My home page and email address
Re: STM32 USB boot conundrum
« Reply #4 on: November 16, 2022, 03:48:39 pm »
If I had the 1.5k pullup activated by a transistor by default -- how would I keep it disabled while the STM32 is in standby mode? I understand that all GPIOs go to high impedance state while the STM32 is on standby.
On STM32F301C8 the DAC output (PA4) ought to be retained during standby if VDDA is available.  (I could be wrong, though, so perhaps ask ST to verify?)

I do suspect that some kind of MOSFET-enabled pullup with logical OR between the BOOT0 and a GPIO pin, perhaps via a dual Schottky or just resistors, is a more robust approach.  Or one of those configurable logic gates like 74LVC1G58 or 74LVC1G98, with BOOT0 as one of the inputs, and the output the gate to the logic-level MOSFET for the pullup.  Two SOT-23 (SOT-23-3 and a SOT-23-6) or smaller dirt-cheap chips would perhaps be acceptable?

EDIT to add:

At least Mouser does have flip-flops in SOT-23 and SC70-6 (TI SN74LVC1G374) in stock, so perhaps your original flip-flop solution would be more acceptable, and it was just a matter of not realizing they do come in nice tiny (but hand-solderable) packages also, not just in SOIC and such?
« Last Edit: November 16, 2022, 03:54:06 pm by Nominal Animal »
 
The following users thanked this post: ebastler

Offline Sauli

  • Contributor
  • Posts: 43
  • Country: fi
Re: STM32 USB boot conundrum
« Reply #5 on: November 16, 2022, 05:52:53 pm »
Quote
Is there any GPIO pin which the boot loader or the hardware sets high?

I would imagine that USART1/USART2 transmit pins are set high by the bootloader. I don't know if they stay high after the bootloader detects activity in the USB port.
 
The following users thanked this post: ebastler

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #6 on: November 16, 2022, 06:18:31 pm »
I do suspect that some kind of MOSFET-enabled pullup with logical OR between the BOOT0 and a GPIO pin, perhaps via a dual Schottky or just resistors, is a more robust approach.  Or one of those configurable logic gates like 74LVC1G58 or 74LVC1G98, with BOOT0 as one of the inputs, and the output the gate to the logic-level MOSFET for the pullup.  Two SOT-23 (SOT-23-3 and a SOT-23-6) or smaller dirt-cheap chips would perhaps be acceptable?

That's what I was just gravitating towards. Realized that I don't need a second jumper to pull up the "hot" end of the 1.5k resistor, since the BOOT0 input conveniently gets jumpered to VDD to enable USB boot. The most primitive solution should be just a Schottky diode from BOOT0 to the resistor, since the other source driving the resistor will be a GPIO which is either high-impedance (STM32 at standby) or high (running). Or an OR gate in a small single-gate package, for a cleaner solution. I will give that a try!
 

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #7 on: November 16, 2022, 06:21:50 pm »
I would imagine that USART1/USART2 transmit pins are set high by the bootloader. I don't know if they stay high after the bootloader detects activity in the USB port.

Neat idea! Unfortunately AN2606 suggests that the bootloader first looks at the USB port, and looks for incoming data on the USART if no valid levels are seen on USB. But that does not exclude the possibility that the USART already gets initialized before. I will try and measure!
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6430
  • Country: es
Re: STM32 USB boot conundrum
« Reply #8 on: November 16, 2022, 07:49:02 pm »
Yeah, AN2606 says you must connect a 1.5K pullup resistor.
So, what's the problem of doing so?

It clearly shows it will loop between USB and uart until the USB cable was detected or 0x7F was received in some uart.
So you can use a small p-fet with 100K to gnd so it activates by default, powering the pullup, that you later disable when booting normally. In bootloader mode pins will be Hi-Z, thus the fet will turn on.
Or use Tx pin output.
« Last Edit: November 16, 2022, 07:57:50 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 
The following users thanked this post: ebastler

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #9 on: November 16, 2022, 08:42:00 pm »
Yeah, AN2606 says you must connect a 1.5K pullup resistor.
So, what's the problem of doing so?

It clearly shows it will loop between USB and uart until the USB cable was detected or 0x7F was received in some uart.
So you can use a small p-fet with 100K to gnd so it activates by default, powering the pullup, that you later disable when booting normally. In bootloader mode pins will be Hi-Z, thus the fet will turn on.

The problem, in my understanding, comes with my intended use of Standby mode. All GPIOs are high-Z in Standby mode, so the p-FET would be activated in this mode also. Hence when a USB connection is made, USB enumeration is attempted and fails (since the STM32 is down).

I think my "dirty" solution should work: Just tie the pullup to BOOT0 and to a GPIO. After a normal start of the STM32, the GPIO will be set high; when boot from USB is selected, the BOOT0 jumper to VDD will pull the 1.5k resistor high instead.
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6430
  • Country: es
Re: STM32 USB boot conundrum
« Reply #10 on: November 16, 2022, 08:50:19 pm »
Or tie that resistor to uart TX, couldn't be easier.
Set it as input/analog mode (hi-z) so it won't trigger USB detection out of bootloader mode.

But the stm32 should wake up when the USB is connected, otherwise what are you trying to do?
« Last Edit: November 16, 2022, 08:59:09 pm by DavidAlfa »
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #11 on: November 16, 2022, 09:16:05 pm »
But the stm32 should wake up when the USB is connected, otherwise what are you trying to do?

Charging the battery?  :)
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6430
  • Country: es
Re: STM32 USB boot conundrum
« Reply #12 on: November 17, 2022, 01:14:28 am »
Well, then I don't see the problem anywhere.
The UART might get disabled when the USB is detected, but tte 1.5K resistor is only required for detection, you should have enumerated already.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #13 on: November 18, 2022, 12:47:04 pm »
Well, then I don't see the problem anywhere.
The UART might get disabled when the USB is detected, but tte 1.5K resistor is only required for detection, you should have enumerated already.

I thought that releasing the pullup signals a disconnect to the host? So D+ needs to be pulled high as long as one wants to maintain the connection?
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 6430
  • Country: es
Re: STM32 USB boot conundrum
« Reply #14 on: November 18, 2022, 01:44:42 pm »
Not 100% sure, but I think it's used purely for detection, once host detects the pullup it will wait ~100ms and start talking to the device.
Can't remember exactly, but I think the USB standard specified that initialization time.
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7295
  • Country: fi
    • My home page and email address
Re: STM32 USB boot conundrum
« Reply #15 on: November 18, 2022, 02:32:03 pm »
Full-speed USB 2.0 device signals disconnect by driving both D+ and D- below 0.3V (VOL).  The 1.5k pull-up on D+ is only used during speed detection, but the USB 2.0 Specification does imply that the pull-up should be enabled whenever the device may receive data.  (Well, Figure 7-22 in resistor_ecn.pdf says so explicitly.)

What works in practice is a different thing, of course.
 

Offline abyrvalg

  • Frequent Contributor
  • **
  • Posts: 848
  • Country: es
Re: STM32 USB boot conundrum
« Reply #16 on: November 18, 2022, 02:33:01 pm »
The pullup must be present all the time. Removal of pullup signals disconnect (that’s how i.e. a “soft remuneration” works - remove pullup, wait, connect it back, enumerate as a different device).
 
The following users thanked this post: ebastler, Nominal Animal

Offline Nominal Animal

  • Super Contributor
  • ***
  • Posts: 7295
  • Country: fi
    • My home page and email address
Re: STM32 USB boot conundrum
« Reply #17 on: November 18, 2022, 04:00:55 pm »
At this point, I think making a table of the required states would help a lot.  Something like

    VUSB Jumper 1.5k BOOT0 Comment
    Low   Yes   No   No
    Low   No    No   No
    High  Yes   Yes  Yes
    High  No    Yes  No    Default
    High  No    No   No    When triggered by MCU software and D+ and D- driven low

If we assume the above is right (it probably is not), then the conclusion is that you do need some kind of external logic to handle the 1.5k pull-up on D+.  It will be affected by whether USB 5V is present (because when there is no voltage there, the D+ must not be pulled up either), whether the bootloader jumper is selected or not, and even be able to be disabled via GPIO, noting that in standby mode GPIOs will revert to hi-Z.  So, not just 3-input 1-output logic, but something with internal state.  (An additional input, or a RESET, might also be useful.)

Are you sure you need to go down to STM32 Standby?  In Stop mode, STM32F301C8 retains SRAM and register contents, and VDD current consumption is down to 6 µA, compared to the 1 µA or so of the Standby mode (VDDA current is roughly the same, around 1 to 3 µA, depending).
 
The following users thanked this post: ebastler

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #18 on: November 18, 2022, 04:53:14 pm »
At this point, I think making a table of the required states would help a lot.

Good idea. Let me try:

StateVDD   USBBOOT0GPIO to Pullup   Pullup
App running3.0V0V/5V   L (via pulldown)HH
Bootloader3.0V5VH (via jumper)ZH
Sleeping3.0V0V/5V   L (via pulldown)   ZZ
Charging3.0V5VL (via pulldown)ZZ

Under regular operation, a GPIO output will pull up the "hot" end of the Zener resistor. It will automatically be high-Z when the STM32 goes to standby. To bring the pullup high while the bootloader is active, I think a Schottky diode from BOOT0 input to the hot end of the resistor should do the trick? Slightly dirty, since the voltage will be below the 3.0V spec, but I trust that this will still be recognized.
« Last Edit: December 11, 2022, 01:05:08 pm by ebastler »
 

Online ebastlerTopic starter

  • Super Contributor
  • ***
  • Posts: 7391
  • Country: de
Re: STM32 USB boot conundrum
« Reply #19 on: December 11, 2022, 12:39:08 pm »
A quick follow-up, after testing Rev 1 of my board: The idea of pulling up the 1.5k series resistor via either a GPIO (when my application is running), or via a Schottky diode to BOOT0 (when the bootloader is activated), works fine.

I checked the UART1 and UART2 TX pins to see whether they could be an alternative for pulling up the resistor. But at least for the chip I am using (STM32F373) the bootloader does not set them to output High. They are set as inputs with a weak pullup while the bootloader waits for either the USB connection to come alive, or a magic character to be received on one of the UART RX lines.

So I will stick with the Schottky diode which seems to do the job nicely. The only thing this scheme does not support is to start the application directly from the bootloader after downloading it: I can't remove the BOOT0 jumper until the code download is complete, and then the newly started application can't force a USB re-enumeration since the jumper is still pulling the USB line high. But I can live with the need for a reset or power-cycle at that point.
 
The following users thanked this post: IU8BBM, Nominal Animal


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf