Author Topic: USB, GCC and bootloader  (Read 8659 times)

Offline akorud

  • Newbie
  • *
  • Posts: 31
    • View Profile
USB, GCC and bootloader
« on: August 18, 2009, 02:57:01 PM »
Hi, the next problem I have is the following: compiling my USB application (USB code is unchanged bare uTasker) with GCC everything works fine if application is loaded at address 0x00. If I change it to be loaded at 0x1000 (SPI bootloader) application itself works fine but just after USB connect it hangs and system is restarted by watchdog.
I change only linker script from
Code: [Select]
MEMORY
{
  rom (rx) : ORIGIN = 0x0000, LENGTH = 256K
to
Code: [Select]
MEMORY
{
  rom (rx) : ORIGIN = 0x1000, LENGTH = 252K
I'm still trying to investigate the problem but maybe you can point me, maybe there is hardcoded address somewhere in USB code...

Thanks in advance,
Andriy Korud

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: USB, GCC and bootloader
« Reply #1 on: August 18, 2009, 05:51:39 PM »
Hi Andriy

Check out Appendix A in the USB User's Guide: http://www.utasker.com/docs/uTasker/USB_User_Guide.PDF
This discusses an optimised SRAM setting for the Coldfire project (saving up to 511 bytes RAM space). It may be that you need to adapt the linker SRAM setup to match the specific USB Buffer Descriptor Table requirements (if the option USB_BDT_FIXED is active in app_hw_m5223x.h). All detains concerning this option and its correct configuration is contained in the document.

Good luck

Regards

Mark





Offline akorud

  • Newbie
  • *
  • Posts: 31
    • View Profile
Re: USB, GCC and bootloader - SOLVED
« Reply #2 on: August 20, 2009, 09:38:41 AM »
Hi, thanks for the answer. Unfortunately the problem is somewhere else. Currently I've found that:
After first USB interrupt, interrupt vector table is corrupted (?) and next interrupt (?)  go to undef_int() function, and naturally board is reset by watchdog. The most interesting is that it happens only if compiled with start address 0x1000, with start 0x0 (no bootloader) everything works fine.
I realize that this problem is really strange, I write here to share information - maybe someone sometime find it useful. When I find solution, I'll write here.
BTW, is there any way in ISR (undef_int()) get interrupt vector that caused this interrupt?

UPD1: I've checked that this is not spurious interrupt.

UPD2: It's "Illegal instruction" exception.

UPD3: It seems I was "lucky" and "enjoyed" Speculation Address errata. After I changed code in Starup_gnu.s to unconditional
Code: [Select]
    move.l  #0x61,%d0                      /* This is the workaround 1 due to the Internal FLASH Speculation error in the first devices */
    movec   %d0,#0x0c04
everything works. It's possible that original code
Code: [Select]
move.l  #__FLASH,%d0
add.l   #0x61,%d0
movec   %d0,#0x0c04
may not work as expected if __FLASH is not 0x0 (in case of bootloader)
« Last Edit: August 20, 2009, 02:14:40 PM by akorud »

Offline mark

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 3234
    • View Profile
    • uTasker
Re: USB, GCC and bootloader
« Reply #3 on: August 22, 2009, 03:30:45 PM »
Hi Andriy

I just compared the startup code when used with the Codewarrior project. It does the following:

//  move.l  #__FLASH,d0                                                     don't take from linker script because it is incorrect {1}
#if defined FLASH_SPECULATION_ERROR_SOLVED                               // {3} M5225X family have errata corrected
    move.l  #0x121,d0                                                    // no workaround 1 {1} set value assuming FLASH is at low address
#else
    move.l  #0x161,d0                                                    // this is the workaround 1 due to the Internal FLASH Speculation error in the first devices
#endif
    movec   d0,RAMBAR0


As you can see, this problem was identified before since it results in some undocumented bit(s) getting set in the RAMBAR register. I remember that it seemed to cause DMA transfers to fail. The technique of taking the __FLASH value as base address originated from the Freescale framework and I expect that the SPI boot loader (where the problem was then identified) is generally used with CW and not GCC; thus it hasn't been detected until now.

This means that it is not related to the FLASH speculation error itself.
Note also that, when using the Kirin3, the FLASH speculation error has been solved and the Codewarrior project automatically enables or disables the workaround.
In the GCC case it doesn't seem possible to use conditional assembler in the same way, so it is necessary to enable or disable the workaround manually based on the chip used. If you are using the Kirin3 (rather than a different USB processor such as the M52210) you could disable the workaround and get instruction operation in FLASH to increase performance by about 5..8%:

    move.l  #0x121,%d0                     /* No workaround when using Kirin3 */   
    movec   %d0,#0x0c04


Note that I have also added the bit 0x100 since this is the write protect bit. Probably it is fixed but this makes it identical to the CW version.
I have modified the Startup_gnu.s in the development project to use your method - Thanks!

Regards

Mark

« Last Edit: August 22, 2009, 03:45:14 PM by mark »