cancel
Showing results for 
Search instead for 
Did you mean: 

DFUSE Demo bricks STM32L476

seb2
Associate
Posted on October 21, 2016 at 21:00

We had success updating our device with the DFUSE demo which uses a STM32F4 device. We now have a product with a STM32L476 device, but when I try to update it via DFUSE demo, it bricks it.

To get the device in DFU mode, I do the following instructions immediately after a reset. This is similar to the STM32F4 code, but modified for the STM32L476, which has same registers but different address and bitmapping.

asm(
''LDR R0, =0x40021060\n\t'' /* RCC_APB2ENR */
''LDR R1, =0x00000001\n\t'' /* ENABLE SYSCFG CLOCK */
''STR R1, [R0, #0]\n\t''
''LDR R0, =0x40010000\n\t'' /* SYSCFG_MEMRMP */
''LDR R1, =0x00000001\n\t'' /* MAP ROM AT ZERO */
''STR R1, [R0, #0]\n\t''
''LDR R0, =0x1FFF0000\n\t'' /* ROM BASE */
''LDR SP,[R0, #0]\n\t'' /* SP @ +0 */
''LDR R0,[R0, #4]\n\t'' /* PC @ +4 */
''BX R0''
);

This seems to work fine, the device enters DFU mode, and I can connect to it via USB on the DFUSe demo app. The product has a 768kHz LSE crystal, so the bootloader code should be running off that. I create a DFU file using the Dfu file manager and a hex file compiled via a GCC compiler. This hex file works fine when loading the code via ST-Link utility. When I try to do an upgrade, the process looks normal (does the erase phase then the download phase). When I leave DFU mode, the device is bricked. It's consuming the same current as if it was totally erased. I need to reload the firmware via ST-Link to get it working again. On a maybe related note, another strange behavior I'm seeing with the STM32L476, when I use my debugger via OpenOCD, everytime I start a new session I need to first erase the device via the ST-Link utility app, otherwise when code already exists, the debug session ends up in a hard fault during static initialization (I think the first malloc call). When this happens, the device is also bricked. Seem to me like something is getting erased during a full chip erase which is not during a new debug session or DFU USB upgrade. Something that is persistent and not being touched by a new debug session or the DFU upgrade?
2 REPLIES 2
Posted on October 21, 2016 at 21:13

Pull the code off with ST-LINK and review what was actually written. Check the Options Bytes

Use a debugger that can turn off ''Run to main()'' and step from the Reset_Handler.

Check the BOOT0 pin state, pull LOW

Instead of using my entry code, pull BOOT0 High and use the DFU loader normally. If that causes the same failure, look very carefully at what is written, as the CPU does very basic things with the code it is running. Write some assembler in the very front of the Reset_Handler to enable/toggle a GPIO

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
seb2
Associate
Posted on October 21, 2016 at 23:16

Thanks for the reply clive,

I've checked several cases:

Case 1: Good code, programmed from ST-Link Utility

Case 2: Good code, programmed from debugger after a full erase

Case 3: Bad code, programmed from debugger second time in a row

Case 4: Bad code, using DFU mode from software

Case 5: Bad code, using BOOT0 pin.

I used ST-Link utility to read the flash (0x08000000 1024K) for each case. I also checked the option bytes (starting at both 0x1FFF7800 and 0x1FFFF800).

In all cases, the options bytes are the same. Same as factory settings. So I looked at the flash contents:

Case 1 and 2 are almost exactly the same, except 1 word different at address 0x08027894. In one case it's 0xFFFFFFFF, the other it's 0xF864F000.

Case 4 and 5 are identical.

Case 1/2 has several words different to case 3

Case 1/2 has several words different to case 4/5

Case 3 has several words different to case 4/5

When I'm debugging in a bad state, the debugger steps just fine all the way to __libc_init_array in my Reset_Handler routine, but during this call I get a hardfault. I believe this happens on the first malloc call when the standard c library is creating the static C++ objects.

My only conclusion so far is there's no difference if I enter DFU mode via BOOT0 pin or from within software. If I do an upgrade, it bricks in the same way. Compared god state to bad states, there's no difference in option bytes but there are differences in the flash memory.

I might have a looks at the peripherals state, before the __libc_init_array call and at other points and see if there's any differences.