cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with custom usb bootloader

anrusal
Associate II
Posted on June 23, 2014 at 01:20

Hi all,

I´m trying to develop my owm custom usb bootloader and firmware. As most of the people who tried before I am having problems because I´m ussing again the usb peripheral in the firmware. So I tried disconnecting and doing a soft reset in the usb peripheral but no one of them has work so far. I would like to know if somebody would know how to fix it.

For more info I am using the last peripheral and usb libraries and I am writing the code in the suite Atollic TrueStudio. Also I will be very happy if someone knows how to debug the firmware, because after the jump to the application the only thing that I can do is debug de assembly code and I suppose that it should be some way to do it.

Regards.
9 REPLIES 9
chen
Associate II
Posted on June 23, 2014 at 10:19

Hi

'' I am having problems because I´m ussing again the usb peripheral in the firmware. So I tried disconnecting and doing a soft reset in the usb peripheral but no one of them has work so far. I would like to know if somebody would know how to fix it.'' It is not clear from your description but I am guessing you want the USB to deisconnect and re-enumerate? Try :

/**===========================================================================
* @brief Function does a soft USB disconnect - simulates unplug of USB
* @param None
* @retval None
*/
void USB_SoftDisconnect( void )
{
// set bit SDIS in OTG_FS_DCTL reg
USB_OTG_dev.regs.DREGS->DCTL |= 0x02;
}

''I am writing the code in the suite Atollic TrueStudio. Also I will be very happy if someone knows how to debug the firmware, because after the jump to the application the only thing that I can do is debug de assembly code and I suppose that it should be some way to do it.'' No, not that I am aware of. It is not possible to debug 2 projects in Atollic. The bootloader is 1 project and the application is another project. You can only debug 1 at a time. (This is true for most IDEs)
anrusal
Associate II
Posted on June 23, 2014 at 11:32

Hi cheng.

''I am having problems because I´m ussing again the usb peripheral in the firmware. So I tried disconnecting and doing a soft reset in the usb peripheral but no one of them has work so far. I would like to know if somebody would know how to fix it.''It is not clear from your description but I am guessing you want the USB to deisconnect and re-enumerate?'' Thats correct, I'm trying to use the usb both in firmware and bootloader. I've tried the function that you gave me, and also the next one:

DCD_DevDisconnect(&USB_OTG_dev); 


But it didn't work, when the bootloader disconnects the peripheral then I can listen how windows recognizes than one usb port has been disconnected, but in the firmware when I connect again the usb peripheral I can listen any sound and afte a while, 1min, windows pops up message saying that he found a problem with a usb device. I think than the problem is in the bootloader, because it looks like when I init the usb in the firmware it gets stuck in someplace. Regards.
jdcowpland
Associate II
Posted on June 23, 2014 at 11:43

Have you tried making sure that all interrupts are disabled in your bootloader before you jump to your application? You'll also need to make sure you de-initialise your usb in the bootloader before jumping:

__asm(''CPSID I'');
NVIC_DisableIRQ(OTG_FS_IRQn);
USB_OTG_WRITE_REG32(&USB_OTG_Core.regs.DREGS->DCTL, 0x02);
USBH_DeInit(&USB_OTG_Core,&USB_Host);
Jump_To_Application();

An then make sure you re-enable your interrupts in your application:

__asm(''CPSIE I '');

chen
Associate II
Posted on June 23, 2014 at 12:14

Hi

''But it didn't work, when the bootloader disconnects the peripheral then I can listen how windows recognizes than one usb port has been disconnected, but in the firmware when I connect again the usb peripheral I can listen any sound and afte a while, 1min, windows pops up message saying that he found a problem with a usb device.

I think than the problem is in the bootloader, because it looks like when I init the usb in the firmware it gets stuck in someplace.''

The problem is that Windows has not recognized the USB instance has gone away at the end of the bootloader (because the instance information is the same). Even thought the bootloader has disabled the USB, Windows does not see this as a disconnect. The application re-initialising the USB with the same information just re-enforces to Windows it is seeing the same USB device and instance.

The way to get around this is to simulate un-plugging the USB at the end of the bootloader.

The code I posted does this.

anrusal
Associate II
Posted on June 23, 2014 at 20:09

Hi I tried the last pieces of code that you gave me but still doesn´t works. Let me show you my code, maybe you will find what I am doing wrong.

This is the code for the bootloader:

__asm(''CPSID I'');
NVIC_DisableIRQ(OTG_FS_IRQn);
USB_OTG_WRITE_REG32(&USB_OTG_dev.regs.DREGS->DCTL, 0x02);
DCD_DevDisconnect(&USB_OTG_dev);
USBD_DeInit(&USB_OTG_dev);//,&USB_Host);
Delay( 0x03FFFF);
Address = *(__IO uint32_t*) (ApplicationAddress + 4);
// Jump to user application
Jump_To_Application = (pFunction) Address;
// Initialize user application's Stack Pointer
__set_MSP(*(__IO uint32_t*) ApplicationAddress);
Jump_To_Application();
while(1);

And here the code for the firmware:


NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x00020000);


STM32F4_Discovery_LEDInit(LED3);

STM32F4_Discovery_LEDInit(LED4);

STM32F4_Discovery_LEDInit(LED5);

STM32F4_Discovery_LEDInit(LED6);


STM32F4_Discovery_PBInit( BUTTON_USER, BUTTON_MODE_GPIO);

//SD_test();


__asm(
''CPSIE I ''
);


....

USBD_Init(&USB_OTG_dev,

#ifdef USE_USB_OTG_HS

USB_OTG_HS_CORE_ID,

#else

USB_OTG_FS_CORE_ID,

#endif

&USR_desc,

&USBD_CDC_cb,

&USR_cb);

I also changed in the firmware the VID and the PID to force Windows to re-identify the device, but still fails during the numeration of the device. Regards.
Posted on June 23, 2014 at 20:55

Are you building the application image properly for the address you have it at?

Do you have a serial port you can output diagnostic/progress information?

Can you print out the address you're about to jump too?

In Keil it's certainly possible to debug both the app and boot loader. For the app you need to be have the debugger ''Run to main()'' of the app, or break point the ResetHandler, from the IDE with the app loaded. How you might do this in Atollic is anyones guess, but even stepping an assembly view and looking at a .MAP file you should at least be able to figure what it's doing, or how it dies.

The SystemInit() function should deal with the vector table, but I'd watch what it does with the clocks, and the boot loader should tear down any interrupt stuff it has set up. Simply disabling interrupts doesn't solve any problems if you fail to handle the underlying sources.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
anrusal
Associate II
Posted on June 23, 2014 at 21:09

Hi Clive,

Are you building the application image properly for the address you have it at?

When I´m building the firmware I modified the ld file indicating what is the new position where my code is going to start

Do you have a serial port you can output diagnostic/progress information?

I suppose than I can use the SWO and redirect the printf to it.

 

 Can you print out the address you're about to jump too?

 

my address is 0x0802000, however before to try with the usb bootloader/firmware I did another bootloader/firmware system based in the UART and it worked ok.

I´ll try with Keil but it would be worth if someone has done something like this before to get the code and have a look.

Regards, Toni.

Posted on June 23, 2014 at 21:29

Fair enough, the .MAP file would confirm

SWV might work, I'd try very hard not to reconfigure the clocks in the application. If the boot loader has set up the HSE/PLL to desired frequencies there's no point tearing it down and doing it over in the application. Again check what in SystemInit() you actually need to do based on how the boot loader hands over the system.

I was thinking more of a real serial port, I try to make my systems debuggable by having one.

I have a similar boot loader + app configuration, not doing USB in the loader, had the app doing MSC+SDCard and VCP type functionality.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
anrusal
Associate II
Posted on June 23, 2014 at 23:46

Hi Clive and who it might concern,

I found what was the problem. The problem was a combination of not completely de-init the peripherals  and also the place my code was doing the jump. So my code was jumping from the usb application layer, what it would be de file ''usbd_cdc_vcp.c'' in the cdc-vcp example provided in the library. What I did is change this and jump from the main ussing a imported variable and also I changed the constant VECT_TAB_OFFSET in my firmware application to match the desired address. However is working right now, I will try to find what it really makes the difference.

Thanks for your help guys.

Regards, Toni.