Solved: Off in the weeds

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My program is going off into the weeds, and in an odd fashion. I hope someone can spot my error. I have a table of sine values stored as a const in flash. The table is 2048 16-bit entries. Here is the routine that uses the table:

unsigned int ConvertToSin(unsigned long thisPhase)
{
    unsigned int quarterPhase;
    unsigned int thisQuarter;
    unsigned int thisSample;
    unsigned int dummySample;

    quarterPhase = (thisPhase>>19) & 0x7FF;    //bottom 11 bits please
    thisQuarter = thisPhase>>30;                //top two bits is the quarter
	thisQuarter = thisQuarter & 0x03;			//limit to 2 bits

    switch(thisQuarter) {
        case 0:
            thisSample=sine_table[quarterPhase];
			break;
        case 1:
            thisSample=sine_table[(0x7FF-quarterPhase)];
            break;
        case 2:
            thisSample=0xFFF-sine_table[quarterPhase];
            break;
        case 3:
            thisSample=0xFFF-sine_table[(0x7FF-quarterPhase)];
            break;
		default:
			thisSample = 0;
    }
    return thisSample;
	//return 0;
}

Here is the sine table declaration:

const __flash uint16_t sine_table[] = {
0x0800,
0x0801,
0x0803,
0x0804,
..
..
0x0FFF,
0x0FFF,
0x0FFF,
0x0FFF };  // 2048 entries

When this routine gets executed my target stops running, and when I pause the debugger the program counter is in the sine table!

If I remove the references to quarterPhase in the sine_table reads and use constants it works. I don't see how running off the end of an array would cause what I am seeing.

I have tried using PROGMEM instead of __flash with the same results. Also I have another table that is the same size but is 1K of long words and it works just fine.

 

Any help would be appreciated.

--tr

Tim Ressel
Portland, OR
timr@earthling.net

Last Edited: Tue. Sep 12, 2017 - 02:44 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To start with the obvious, have you confirmed that you are not on the ragged edge in either flash or SRAM usage?  What happens if you make your sine table e.g. half as big?

 

 

Last Edited: Sun. Sep 10, 2017 - 07:22 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

madhun wrote:
and when I pause the debugger

It sounds like you are all set up -- go for it.  Once you identify the problem area, you can single-step.  As it can be reproduced, if you go "too far" to identify the root cause the first time, then you just do it again.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

madhun wrote:

unsigned int ConvertToSin(unsigned long thisPhase)
{
    unsigned int quarterPhase;
    unsigned int thisQuarter;
    unsigned int thisSample;
    unsigned int dummySample;

    quarterPhase = (thisPhase>>19) & 0x7FF;    //bottom 11 bits please
    thisQuarter = thisPhase>>30;                //top two bits is the quarter
	thisQuarter = thisQuarter & 0x03;			//limit to 2 bits

What microcontroller are you using?

What compiler/tool chain?

What is the intended target? You posted this to the "megaAVR and tinyAVR" forum.

 

You have defined variables as "unsigned int" and then bit shift them more than 16 bits.

 

With Atmel Studio (gcc compiler) for the AVR line, "unsigned int" is a 16-bit integer.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have done that. I set a breakpoint at the first use of the table, then I single step. The program then takes off into the weeds. The program counter winds up in the table in flash.

 

--tr

Tim Ressel
Portland, OR
timr@earthling.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Avr Mega168 @ 20MHz

Atmel Studio 7

Target is a custom board

No, the variable that gets shifted is defined as an unsigned long. I know the shifting works because my other waveform convertor routines work okay.

 

The part that bugs me is my other table, which is similar, has no problems.

 

--tr

Tim Ressel
Portland, OR
timr@earthling.net

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1

Again, what is your flash and SRAM usage?  Going off into the weeds is often the sign of a corrupted return address due to the stack being trashed.  You need to look at the code just before the PC gets whacked, and if it happens at a return instruction, look at the stack contents at that point.  

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I checked the ram and flash usage, it is fine. but it turns out you were close!  I had too much code inside an ISR. I know better than to do that, stupid me. I moved non-critical code out of the ISR and I use a flag to run it later outside the ISR. It works fine now! I guess it ran out of heap or something. I also had a timing issue where sample updates were getting skipped. Just not enough cycles to get 'er done. Slowed the sample rate and all is well.

 

Thanks to everyone who helped out!

 

--tr

Tim Ressel
Portland, OR
timr@earthling.net