Jump to content
rebeltaz

timing different between Release and Debug in CSS?

Recommended Posts

OK... this is odd. I have been compiling my code as Debug and programming the MSP with that. Worked great. After I got everything right, I built the project as Release and programmed that. Running with the Release code, timing is sped up by at least double. I am using a snippet of code that I found on the TI wiki (I think) for Playing the Imperial March which uses __delay_cycles for timing. With Debug, this is fine, but with Release this is playing way too fast and too soft.

 

Does the timing change between Debug and Release and (obviously it does) why? I guess the code is more optimized? But shouldn't one cycle equal one cycle regardless of the optimization?

Share this post


Link to post
Share on other sites

The code is definitely (hopefully) more optimized in Release builds. Depending on how the __delay_cycles macro is implemented and compiler settings it might even have been optimized out as it does nothing "useful".

 

A good start is to check the .asm output. If it isn't already in the Release folder, check the compiler settings to create it. It's an intermediary file of the actual machine code generated by the compiler.

Share this post


Link to post
Share on other sites

OK... this is the code that I am using (from http://processors.wiki.ti.com/index.php/Playing_The_Imperial_March):

 

//This function generates the square wave that makes the piezo speaker sound at a determined frequency.
void beep(unsigned int note, unsigned int duration)    // ex. beep (a, 500)
{
    int i;
    long delay = (long)(10000/note);  //This is the semiperiod of each note.
    long time = (long)((duration*100)/(delay*2));  //This is how much time we need to spend on the note.
    for (i=0;i<time;i++)
    {
        P1OUT |= BIT7;     //Set P1.7...
        delay_us(delay);   //...for a semiperiod...
        P1OUT &= ~BIT7;    //...then reset it...
        delay_us(delay);   //...for the other semiperiod.
    }
    delay_ms(20); //Add a little delay to separate the single notes
}

/* These two functions stop the main thread for a certain number of milli -or- microseconds.
   They are based on trial and error, but they work fine for the out-of-the-box Launchpad board.
   
   based on default 1 MHz clock speed
*/
void delay_ms(unsigned int ms )
{
      unsigned int i;
      for (i = 0; i<= ms; i++)
        __delay_cycles(500); //Built-in function that suspends the execution for 500 cycles
}

void delay_us(unsigned int us )
{
      unsigned int i;
      for (i = 0; i<= us/2; i++)
        __delay_cycles(1);
}

 

I changed unsigned int i in both delay functions to volatile unsigned int i and, while the tones are much closer to how the were in the Debug version, they still aren't right. Also, when the volatile keyword is used with the Debug version, the tones are no longer correct there, either.


Is there any other way to preserve that (seemingly useless as far as the compiler is concerned) very important empty loop regrardless of Debug or Release?

Share this post


Link to post
Share on other sites

You can change the optimization level of the debug code.  Usually I use "level 1" for debug, which strips away some of the completely obvious overhead.

 

That said, oPossum is right.  Use a timer.  This is what they are for.

 

Lastly, your for loop isn't going to run in anything close to 2 cycles.  The MSP only does a small few instructions in 1 clock cycle, and it certain doesn't have a 1 IPC instruction for "for loop" or "__delay_cycles()."  If you were to do this in hardware, I suspect that it would run *a lot* faster than it does now in debug OR release.  You'll need to multiply your timing array.

 

Generating variable frequency square pulse is reasonably easy to do with a timer.  Keep in mind the the core frequency range for hearing is 60-2000Hz.  A dial tone is 440Hz... I'm dating myself...  You can find what "middle C" is, but I think it's close to 440Hz.

Share this post


Link to post
Share on other sites

You have a for() loop with __delay_cycles() in it. You are (without knowing) depending on the property that the for loop consules cycles as well. You might want to consider rewriting your delay_ms() function using a timer instead of cycle counting.

Share this post


Link to post
Share on other sites

Yeah... that was my first program and I borrowed that portion of the code from the TI wiki page. I figured TI's page... must be reliable. And like I said.. as long as I only run CSS in debug mode, the code works fine.

 

I have been reading MSP430 Microcontroller Basics, though, and I now understand how to use the Timer to do this. Next project I'll try it that way. I don't feel like rewriting the code to fix this.

 

If I share this, I'll just make sure I make it clear to turn off optimization before compiling.

Share this post


Link to post
Share on other sites

Using a Timer depends on setting a bunch of registers the right way, but once you get it, you have it forever.  There are many examples.  98% of the time you are interested in the Output-Compare feature (often it is internal only) and not the Update feature or the Input-Compare feature, so look especially for Output-Compare examples.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...