Coldfire - USB in Host mode problems TOKEN BUSY

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Coldfire - USB in Host mode problems TOKEN BUSY

2,277 Views
fferraro
Contributor II

I am using CodeWarrior 6.3 C Compiler for Coldfire MCF52223 on the Freescale M52223EVB Development board. I need to use the processor USB interface in Host mode. My software is based on the CMX routines (Host Demo) downloaded from Freescale Web Site.

 

My problem is specifically:

 

I wait till pending tokens are processed, checking the bit 5 of the MCF_USB_CTL register (IPSBAR Offset 0x1C0094) ( bit5 = MCF_USB_CTL_TXDSUSPEND_TOKBUSY) before starting reset signaling (MCF_USB_CTL |= MCF_USB_CTL_RESET) or before writing any tokens to the Token Register (IPSBAR Offest 0x1C00A8), but sometimes this bit5 does not clear.

 

#define DSC_BUG 0                in the project and this is the code:

 

#if DSC_BUG == 0

  while(MCF_USB_CTL & MCF_USB_CTL_TXDSUSPEND_TOKBUSY)

  {

    if (MCF_USB_INT_STAT & MCF_USB_INT_STAT_USB_RST)

    {

      MCF_USB_CTL &= ~MCF_USB_CTL_TXDSUSPEND_TOKBUSY;

      break;

    }

  }

#endif

 

Changing the setting in the Target panel in the sheet “Code Generation” I get different behaviours and the program stops in different modes and in different subroutines.

I think I have some problems related to Compiler optimizations:
depending on the optimization level it seems that the same C source code works well or not, and sometimes it stops.

 

Any suggestion?

 

I have tried the CodeWarrior 7 C Compiler but I do not found any differences.

Labels (1)
0 Kudos
4 Replies

432 Views
RichTestardi
Senior Contributor II
Hi,
 
I am not sure if it matters, but after writing a token, I used a slightly different algorithm than you have:
 
Code:
        assert(! (MCF_USB_OTG_CTL & MCF_USB_OTG_CTL_TXSUSPEND_TOKENBUSY));        MCF_USB_OTG_TOKEN = (uint8)(MCF_USB_OTG_TOKEN_TOKEN_PID(token)|MCF_USB_OTG_TOKEN_TOKEN_ENDPT(endpoint));        // wait for token done or reset        for (;;) {            int_stat = MCF_USB_OTG_INT_STAT;            if (int_stat & (MCF_USB_OTG_INT_STAT_TOK_DNE|MCF_USB_OTG_INT_STAT_USB_RST)) {                break;            }        }
 
More troubling is the effect of compiler options on your code...
 
There are three possible issues that jump to mind...
 
1. if you have uninitialized variables or race conditions in your code, compiler optimization levels can cause bugs to be exposed or hidden.
 
2. CW optimizations can "reorder" operations as described in this thread: http://forums.freescale.com/freescale/board/message?board.id=CWCFCOMM&thread.id=2052
 
3. CW optimizations have a bug if you have a switch case that starts immediately with a do loop, as described in this thread: http://forums.freescale.com/freescale/board/message?board.id=CWCFCOMM&thread.id=1882
 
Hopefully that might be of some help...
 
-- Rich
 
 
 
0 Kudos

432 Views
fferraro
Contributor II

Thanks very much, now trying to replace my code with yours.

After read the thread links, which I already know, I have replaced all the “switch case” with the “if” and so the program is more “stable” during the compiler.

:smileysad: One of mine “switch case” was at the start in While(1) in the Main Program.

 


I use “Optimize For Faster Execution Speed” and “Optimizations Off”
, for example only switching to  “Smaller Code Size” and “Optimizations Off”  the program stops in the code on top of my first message or not.

The same using “Optimize For Faster Execution Speed” and “Optimizations Off” and modifing the Parameter Passing from “Compact” to “Standard” .

It is so strange!

 

Francesco

0 Kudos

432 Views
RichTestardi
Senior Contributor II
Hi Francesco,
 
I definitely don't think you have to go so far as to replace all switch statements with if's -- the bug I found is *very* specific to a "do" loop as the *very* first statement of a switch case...  If your code doesn't look like this:
 
    switch (...) {
        ...
        case ...:
            do {
                ...
            } while (...);
            ...
            break;
        ...
    }
 
(with the "case" immediately followed by a "do" ), then you're fine.
 
Does your program stop before or after interrupts are enabled?  If it is after, it is possible interrupts are trashing registers as well (which optimized code would be more susceptible to).  How, exactly, does the program stop?  With an exception?  If so, you can get a lot of information from looking at the exception frame on the stack.  Displaying the memory at address a7 should reveal two words as defined in section 11.1.2 of the ColdFire Family Programmer's Reference Manual.
 
I am sorry -- I did not mean to scare you about the compiler -- in general it is very well behaved!!! :smileyhappy:
 
-- Rich
0 Kudos

432 Views
fferraro
Contributor II

Hi, my error was caused by  “Internal Flash Speculation Address Qualification Incomplete” as described in the “MCF52223DE Rev. 2, 03/2008”

Before I had this code:

 

            /* Initialize FLASHBAR */

            move.l          #0,d0

            add.l            #0x21,d0

            movec          d0,RAMBAR0

 

Now I have replaced with this, and my C source code works well:

 

            /* Initialize FLASHBAR */

            move.l         #0,d0

            add.l            #0x61,d0

            movec          d0,RAMBAR0

 

0 Kudos