cancel
Showing results for 
Search instead for 
Did you mean: 

Issue with USB DFU, request for direction

rumlyen
Associate II
Posted on August 15, 2016 at 05:34

Hello all,

I am working on a project where MCU will enter USB DFU mode via a command (STM32L151rd, USB-FS_4.0, 32MHz PLL driven by HSE) without sensing any button press or changing BOOT0 pin.

I've configured USB VCP as the default mode. It'll switch role to DFU or MSC (in next USB connectivity) upon a command sending via VCP. DFU/MSC session will continue as long as USB cable is connected (via sensing a GPIO pin connected to USB). PC can recognize all three USB modes. Unfortunately, I am not clear about the register/vector table settings needed for DFU or which .hex file is needed to convert to .dfu and upload. Will this idea work at all for DFU ?

Would you please give me some direction for this specific project and help me get out of this problem.

Thank you for your kind time.
5 REPLIES 5
Posted on August 15, 2016 at 18:05

I'm not using L1 parts, you'll have to review how to map and call the ROM in a viable manner, or implement your own DFU loader. This topic has been covered multiple times for several of the STM32 family devices, the concepts will not be unduly different here. If necessary review the technical manuals for the chip and core, and experiment.

The .DFU file is just a binary encapsulation of the data (firmware image) you are representing in your .HEX file. There is no magic about it, it is your firmware, it will get put exactly where you tell it to put it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rumlyen
Associate II
Posted on August 25, 2016 at 01:59

Thank you Clive. I've explored your DFU example/discussions.

My Bootloader code can upload a sample .dfu but cant upload more than 4% of my application code. I apologize, I'm not getting the whole picture of what I need to configure. I request your kind suggestion.

From STM32L1 datasheet:

System Memory: 0x1FF0 0000 -- 0x1FF0 1FFF [2 Banks. Bank1upto 0x1FF0 0FFF]

Flash:                   0x0800 0000 -- 0x0805 FFFF [2 Banks. Bank1upto 0x0800 17FF]

Data EEPROM:   0x0808 0000 -- 0x0808 2FFF [2 Banks. Bank1upto 0x0808 2FFF]

SRAM:                0x2000 0000 -- 0x2000 BFFF

In my bootloader project/code, MCU switch either Jump_To_Application() or initialize USB DFU mode + send .dfu via DfuSe Demo + perform a soft reset. Its around 13KB code. From Keil_u5 'Options for Target\Target', I've set

IROM1:0x0800 0000 (start) and size 0x4000

IRAM1:0x2000 0000 (start) and size 0xC000 (Default)

And 'Options for Target\Linker' :

R/O Base: 0x0800 0000 (Default)

R/W Base: 0x2000 0000 (Default)

Code:

------

//#define BOOTLOADER_MAGIC_ADDR ((uint32_t*) ((uint32_t) 0x2000BFF0))

//#define BOOTLOADER_MAGIC_TOKEN 0xDEADBEEF  

//#define ApplicationAddress 0x08004000

At the start of main() function:

 

 

tmp=*BOOTLOADER_MAGIC_ADDR;

if (tmp != BOOTLOADER_MAGIC_TOKEN){

JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4);  

Jump_To_Application = (pFunction) JumpAddress;

__set_MSP(*(__IO uint32_t*) ApplicationAddress);

 Jump_To_Application();

 }

 

else

{

USB_Connectivity_Pin_config(); // to check USB connectivity via PB12 GPIO pin

*BOOTLOADER_MAGIC_ADDR=0;

Set_System();

Set_USBClock();

USB_Init();     // DFU mode

while (GPIOB->IDR & GPIO_Pin_12) ==SET); // Continue DFU mode as long as USB cable connected.

NVIC_SystemReset (); // Reset after USB cable disconnected

}

---------------------------------------------------

And the application code (where I configured USB VCP/MSC, timers,FATFS SDIO, interrupts) is around 30KB. I've configured:

IROM1:0x0800 4000 (start) and size 0x5C000

IRAM1:0x2000 0000 (start) and size 0xC000 (Default)

'Options for Target\Linker'

R/O Base: 0x0800 4000 (Default)

R/W Base: 0x2000 0000 (Default)

with

#define VECT_TAB_OFFSET  0x4000

NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x4000);

In USB VCP mode, upon a user command:

*BOOTLOADER_MAGIC_ADDR = BOOTLOADER_MAGIC_TOKEN; 

NVIC_SystemReset();

---------------------------------------------------------------------------

I saw your following assembly codes. I guess I don't need to add these for my project:

Reset_Handler   PROC

                EXPORT  Reset_Handler             [WEAK]

                IMPORT  SystemInit

                IMPORT  __main

 

                LDR     R0, =0x2000BFF0 ; End of SRAM

                LDR     R1, =0xDEADBEEF

                LDR     R2, [R0, #0]

                STR     R0, [R0, #0] ; Invalidate

                CMP     R2, R1

                BEQ     Reboot_Loader

 

                LDR     R0, =SystemInit

                BLX     R0

 

                LDR     R0, =__main

                BX      R0

                ENDP

 

 

Reboot_Loader   PROC

                EXPORT  Reboot_Loader

 

                LDR     R0, =0x40023844 ; RCC_APB2ENR

                LDR     R1, =0x00004000 ; ENABLE SYSCFG CLOCK

                STR     R1, [R0, #0]

                LDR     R0, =0x40013800 ; SYSCFG_MEMRMP

                LDR     R1, =0x00000001 ; MAP ROM AT ZERO

                STR     R1, [R0, #0]

                LDR     R0, =0x1FF00000 ; ROM BASE of L1

                LDR     SP,[R0, #0]     ; SP @ +0

                LDR     R0,[R0, #4]     ; PC @ +4

                BX      R0

                ENDP ;

Posted on August 25, 2016 at 03:22

My Bootloader code can upload a sample .dfu but cant upload more than 4% of my application code.

Ok, but what does this mean? Can the ROM based System Loader take the whole .DFU image? Your DFU firmware bugs out at some point? If it is *your* DFU loader, can you instrument that and quantify where it is failing.

The DFU format is not inherently complicated, it describes blocks of data with a size and destination address. If you can take the .HEX it was created from, and burn it in with the ST-LINK Utilities, then the DFU Loader should be able to digest/process it too. The DFU Manager can also take a .DFU and create a .HEX or .S19 file. One could build a HEX Loader that could take these same files, and prove if delivering them that way works, doing so would allow you to focus on where exactly the problem lays.

Yes the memory division here looks reasonable enough. I'm not a fan of control transfer done this late in C. You need to be very careful that your SystemInit() code doesn't assume cold reset conditions, and that the Loader and App load the correct address for the Vector Table.

My code example should allow it to boot into the ROM's System Loader.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
rumlyen
Associate II
Posted on October 07, 2016 at 05:33

Hi Clive,

I apologize I was busy doing other stuffs and now back what I left unsolved.

One query:

http://stackoverflow.com/questions/34959898/how-to-work-with-usb-dfu-bootloader-without-using-vbus-and-id-ilne-for-stm32f4xx

hints that if MCU jumps to built-in boot loader of system ROM (0x1FF00000--ROM BASE of L1), it'll detect USB as a DFU device (without configuring USB DFU in code as provided in USB_FS library) and we can load .dfu file using DFUse utility. Am I understanding correctly?

If so, may be I can configure the whole system in one project (code) using your RAM magic content. I was always getting wrong concept and wondering whether switch to 0x1FF00000 or 0x08004000 in Reboot_Loader section (or in which project: DFU boot loader or application code).

I request your kind guidance.
rumlyen
Associate II
Posted on October 07, 2016 at 23:26

I've done it at last.

Yes, I was missing this point from the beginning ''if MCU jumps to built-in boot loader of system ROM, it'll detect USB as a DFU device (without configuring USB DFU in code as provided in USB_FS library example)''.

For reference, in my code, user will send a character command from PC via USB VCP and MCU will enter DFU mode (*BOOTLOADER_MAGIC_ADDR = BOOTLOADER_MAGIC_TOKEN;

NVIC_SystemReset();) and PC will recognize it as an USB DFU device.

Thank you Cilve once again. Startup code for L151rd stands as:

Reset_Handler   PROC

                EXPORT  Reset_Handler             [WEAK]

                IMPORT  SystemInit

                IMPORT  __main

 

                LDR     R0, =0x2000BFF0 ; End of SRAM 0x2000BFFF

                LDR     R1, =0xDEADBEEF

                LDR     R2, [R0, #0]

                STR     R0, [R0, #0] ; Invalidate

                CMP     R2, R1

                BEQ     Reboot_Loader

                LDR     R0, =SystemInit

                BLX     R0

 

                LDR     R0, =__main

                BX      R0

                ENDP

 

Reboot_Loader   PROC

                EXPORT  Reboot_Loader

 

                LDR     R0, =0x40023820 ; RCC 0x40023800 base with 0x20 offset

                LDR     R1, =0x00000001 ; ENABLE SYSCFG CLOCK

                STR     R1, [R0, #0]

                LDR     R0, =0x40010000 ; SYSCFG_MEMRMP base with 0x00 offset

                LDR     R1, =0x00000001 ; MAP ROM AT ZERO LOCATION

                STR     R1, [R0, #0]

                LDR     R0, =0x1FF00000 ; ROM BASE of L1

                LDR     SP,[R0, #0]     ; SP @ +0

                LDR     R0,[R0, #4]     ; PC @ +4

                BX      R0

                ENDP ;