STM32 DFU mode. Explicit declations for boot pins? - Page 1
Forum section: electronics / general

author: Pack34
author_rank: Frequent Contributor
timestamp: August 17, 2015, 06:15:13 pm
content: I'm having an odd issue and I'm hoping that someone here might be able to help me out. I'm working with an STM32F405 processor with the CoIDE and I'm noticing an odd behaviour difference between two boards that I'm working with.What I'm trying to accomplish is to get both boards going into DFU mode when the signal on the BOOT0 pin is raised (BOOT1 has a 10k pull-down). I'm seeing it work properly on one, but not the other. The hardware and firmware between the two boards is the same, so my hunch is that there's something that I'm supposed to be explicitly setting for the boot pins.My question is: Is there anything I need to explicitly declare to see the STM32 go into DFU mode? Or should it simply just work when the pin is raised and my issue is most likely elsewhere?The two main application notes that I found were AN2606 and AN3156. AN3156 goes into detail on how the communication scheme works after it's been placed into DFU mode and AN2606 talks about how to put it into DFU. In AN2606 on table 2 (page 16) it implies I should just need to bring the Boot0 pin high, while Boot1 is low. However, no code seems to be listed in the appnote.AN2606 - STM32 microcontroller system memory boot modehttp://www.st.com/st-web-ui/static/active/en/resource/technical/document/application_note/CD00167594.pdfAN3156 - USB DFU protocol used in the STM32 bootloaderhttp://www.st.com/st-web-ui/static/active/jp/resource/technical/document/application_note/CD00264379.pdfSTM32 Datasheethttp://www.st.com/web/catalog/mmc/FM141/SC1169/SS1577/LN1035/PF252144Does anyone have any thoughts or ideas?

author: FrankBuss
author_rank: Unknown
timestamp: August 17, 2015, 06:54:02 pm
content: How do you set boot0 and boot1? You have to apply the signals externally, then do a reset.Recently I implemented a hardware solution to start the bootloader, as mentioneherein the last answer: A GPIO pin charges as capacitor, which is connected to boot0 and set the pin to 1. Then I do a reset (which turns the GPIO to input, which is the reason for the resistor/capacitor) and the boot pins are sampled from the reset function, which then starts the DFU mode. Might be not the most elegant solution, because it could be done all in software, but works very reliable (tested on a STM32F4 Discovery board, and on the custom hardware of a client) and you can't forget to reset some timers etc., which the DFU bootloader requires, if you jump to it.The microcontroller is connected by USB to a Beagle Bone in the client hardware, running Linux. I can then detect the device in USB mode with lsusb and flash a new firmware withthis program.

author: Pack34
author_rank: Frequent Contributor
timestamp: August 17, 2015, 07:22:42 pm
content: BOOT0 and BOOT1 are being set externally. Once the device recieves a command to go into DFU mode, the STM32 will output tell another chip to raise the BOOT0 pin. The BOOT1 pin is tied to ground using a 10k resistor so it's always low.All of this is happening on both devices. BOOT0 ends up being held high for about 20 to 50ms. This should be sufficient, right? The hardware inside the chip should really just be looking for that pos-edge interrupt.Define, do a reset? When BOOT0 is high and BOOT1 is low, I thought that the transition into DFU was interrupt driven?

author: Neganur
author_rank: Unknown
timestamp: August 17, 2015, 07:33:28 pm
content: Quote from: Pack34 on August 17, 2015, 07:22:42 pmHow are you setting the BOOT0 of the second MCU with the other while you reset it? The pin might not be set long enough.To my knowledge, the BOOT pins have to be set before reset happens else the boot loader won't start the device in DFU mode (i.e. from system memory)

author: Pack34
author_rank: Frequent Contributor
timestamp: August 17, 2015, 07:39:23 pm
content: Quote from: Neganur on August 17, 2015, 07:33:28 pmAn I2C command is sent off to the secondary processor, which then changes the state of the BOOT0 net. I think the key part I'm missing is that I'm not explicitly restarting the STM32 after the command is sent off to the secondary processor. Since it was working on the other board I had assumed it was all interrupt driven and handled in internal hardware.

author: FrankBuss
author_rank: Unknown
timestamp: August 17, 2015, 07:46:57 pm
content: boot0 and boot1 are sampled on reset, at least for the STM32F4 devices, see RM0090, page 58: "The values on the BOOT pins are latched on the 4th rising edge of SYSCLK after a reset. It is up to the user to set the BOOT1 and BOOT0 pins after reset to select the required boot mode."

author: Jeroen3
author_rank: Super Contributor
timestamp: August 17, 2015, 07:56:45 pm
content: There is more involded.First, the reset is lifted. It takes a few cycles before the clocks are running and then the boot loader is started. If it was not skipped by the lockbits. The boot loader read the boot pins.When a boot mode is detected, and there are no other imits in the lockbits, the boot loader starts sampling other gpio to determine which interface is active. This is also an important detail. Having the wrong interface active will enable dfu over uart instead of can, for example. Highly annoying to fix if the boards are already made.Then the chip waits for input on the active peripheral.The datasheet and app notes provide a detailed flow chart and sometimes binary table to show which pin states cause which dfu mode. Alternatively, you could use your own boot script and jump back to the boot loader. However, you cannot use boot0 for that. The forum of ST itself has some active members with internal knowledge of this process. Maybe you can also ask your question there?

author: PChi
author_rank: Frequent Contributor
timestamp: August 18, 2015, 05:42:21 pm
content: It may be that there is a difference in the crystal oscillator start time. On one of the STM32 parts with a particular ROM (System Memory) if the oscillator didn't start up quickly enough it would revert to the UART.

author: Lukas
author_rank: Frequent Contributor
timestamp: August 18, 2015, 07:23:42 pm
content: Quote from: FrankBuss on August 17, 2015, 06:54:02 pmInstead of directly jumping to the dfu, you can do so in the startup code, right after reset. The startup code looks for a magic value in ram you set from your main application and then do a reset. If the magic value matches, it jumps to the DFU instead of the main app.