DFU (Device Firmware Update) mode is an incredibly useful feature on modern microcontrollers. It allows for quick and easy updates to a device’s firmware without the need of extra piece of hardware. This can be critical if you need to update the firmware of a device in the field or to streamline a production or development process. There are two main ways to force a device into DFU mode. The first is to have the device be manipulated externally to force it into DFU or you can even handle it completely in firmware!
Invoking DFU Externally
Sometimes you’re dealing with a larger and more complex system where the STM32 is not the primary processor, you want to prevent accidentally forcing the device into DFU mode by physically requiring the user to augment the device, or you’re simply running low on code space and need to offload it elsewhere.
To make this work, there are three hardware pins that we care about: BOOT0, BOOT1, and RESET. On the microcontroller in question they are pins 60, 28, and 7 respectively. These pins need to be augmented according to Table 2 in the AN2606 app note linked below.
The state of the boot pins is only a portion of the picture. There’s also specific timing criteria that must be met. The device latches the state of these pins at a specific time after boot-up. This can vary greatly per the specific device in question. As seen in the images below this can take upwards of 100ms!
Now that we know our timing constraints and what pins to actuate, we can properly place the device into DFU mode at our leisure. Either by physically shorting pins on a header or using external circuitry to drive them.
Invoking DFU Internally
What if I want to have this under strict software control? That can be done easily as well! (with some passives to help us out). Since we already know our pattern from the above tables (BOOT0 high, BOOT1 low) after a reset. We can configure these by setting this pins as outputs and then setting their state according to the pattern, then following it with a reset call. To help ourselves out we can use simple pull-down resistors on both pins (something weak, say 100k-ohm) and then to maintain that state on the BOOT0 pin we’ll need to throw on a heavy capacitor to hold the charge through the reset.
1 2 3 4 5 6 7 8 9 |
/***** Set our device into DFU mode, or clear it *****/ void DFU_Handler(int state) { if(state) DFUPORT->BSRRL = DFU_PIN; // Set DFU mode else DFUPORT->BSRRH = DFU_PIN; // Clear it if we change our mind } |
1 2 3 |
// Initiate a system reset. // This is completely taken care of for us by the standard STM32 CMSIS libraries NVIC_SystemReset() ; |
It’s really that simple! Happy coding!
can we disable particular DFU mode like to give only USART and not USB or any other for stm32f072 series. ?