Stumped with stack pointer problem

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

I am moving over from the motorola world and making my first attempt at using an avr. I started my first project by initializing a 16x2 lcd and displaying the number 255. I basically used the same algorithm that has worked for the motorolas and just substituted the asm code of the avr. This appears to have been successful.

I rushed the project and neglected to setup the stack pointer until after I had a working display. At this point I decided for good measure and before expanding my project I better initialize the stack pointer.

Now the problem. Stack pointer initialization crashes the program. Here is my setup code:

.include "tn2313.inc"

.org $0000
ldi r16,low (RAMEND)
out spl,r16

it would seem a sph instruction would be useless because the sram of the 2313 only has 128 bytes.

It doesn't seem that a stack overflow could be a problem because my program is very simple.

An help would be appreciated.

Thanks, Roger

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

It must be something else.
you can leave out the low( ) for the tiny2313.

RES

Last Edited: Sat. Feb 8, 2014 - 08:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
It must be something else.

+1

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

Mopar_512 wrote:
neglected to setup the stack pointer
SPL and SPH (when present) have a default value of RAMEND after reset, so technically there's no need to set them, but it is good practice in the event a bug or hardware problem results in a jump to 0x0000.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

My program uses rcall nine times but each rcall to a subroutine is completed with a ret instruction. It is my understanding that a ret after a subroutine execution restores the stack back to its original state.

Is this correct?

Thanks,
Roger

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

Yes, with a proviso.

An rcall (or call) will push the PC (program counter) onto the stack as the 'return address', leaving the stack pointer two bytes (or whatever width the PC is in your particular AVR) lower than it was before the rcall, and then loads the PC with the address of the rcall in order to execute the subroutine.

A ret pops the previously pushed return address off the stack and loads it into the PC, leaving the stack pointer two bytes higher than it was before the ret. Execution the resumes where it left off at the instruction immediately following the original rcall.

If, right before the ret, the stack pointer is at a different place than it was right after the rcall that got you here, the ret will pop whatever bytes are on the stack at that position (even though they aren't the return address) and shove them into the PC. This will generally crash your app.

This won't happen provided any changes your subroutine makes to the stack pointer are 'undone' before the ret.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Sounds like it's time for the simulator. That should let you see where things go wrong. The call/ret is the same on just about all processors, so no magic with the avr.
Have a look at what values the assembler generates to see if that is what you expect.

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

Quote:
SPL and SPH (when present) have a default value of RAMEND after reset, so technically there's no need to set them
Not on older chips including the tn2313. The initial value on the tn2313 is 0x00.

Regards,
Steve A.

The Board helps those that help themselves.

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

Koshchi wrote:
Not on older chips including the tn2313. The initial value on the tn2313 is 0x00.
I haven't used any older chips, but the ATtiny2313 datasheet disagrees:
Bit             15     14     13     12     11     10      9      8
                 –      –      –      –      –      –      –      –   SPH
                SP7    SP6    SP5    SP4    SP3    SP2    SP1    SP0  SPL
                 7      6      5      4      3      2      1      0
                 
Read/Write       R      R      R      R      R      R      R      R
                R/W    R/W    R/W    R/W    R/W    R/W    R/W    R/W
                
Initial Value RAMEND RAMEND RAMEND RAMEND RAMEND RAMEND RAMEND RAMEND
              RAMEND RAMEND RAMEND RAMEND RAMEND RAMEND RAMEND RAMEND

I haven't one to test the datasheet against reality ;)

JJ

//////////////////////////////////////////////////////////////////////////

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Quote:
but the ATtiny2313 datasheet disagrees:
Hmmm... Not the one I have (revision H). The latest version (revision L) does indeed say RAMEND.

Regards,
Steve A.

The Board helps those that help themselves.

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

Koshchi wrote:
Hmmm... Not the one I have (revision H). The latest version (revision L) does indeed say RAMEND.
I wonder which one has the copy/paste error ;)

Actually, the datasheet revision history shows the change:

Quote:
Rev. 2543J - 11/09
    1. Updated template 2. Changed device status to “Not recommended for new designs.”
    3. Updated “Stack Pointer” on page 11.
    4. Updated Table “Sleep Mode Select” on page 30.
    5. Updated “Calibration Byte” on page 160 (to one byte of calibration data)
There's still no guarantee in my mind... I'd want to test a real device.

In any event explicitly setting the SP is a good idea.

JJ

EDIT: The subject has been covered before.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Mopar_512 wrote:

.include "tn2313.inc"

.org $0000
ldi r16,low (RAMEND)
out spl,r16

You're setting spl to 0xdf instead of 0x00

RAMEND is 0x00df

ldi r16, RAMEND ; 0xdf
out sph, r16 ; high 0xdf

edit: the 2313 doesn't have sph.

Last Edited: Sun. Feb 9, 2014 - 11:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Duplicate deleted

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

Last Edited: Sun. Feb 9, 2014 - 11:06 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ront1234 wrote:
You're setting spl to 0xdf instead of 0x00
RAMEND is 0x00df
And?

0xDF is the correct value. Setting it to 0x00 would point to r0.

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

joeymorin wrote:
And?

the 2313 has no SPH, so that won't work.

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

ront1234 wrote:
the 2313 has no SPH, so that won't work.
I don't follow.

The OP isn't setting SPH, he's setting SPL, and he's setting it to be equal to the low byte of RAMEND. RAMEND is 0xDF, so the low byte is also 0xDF.

There's even an example of how to set the stack pointer in the datasheet:

Quote:
The most typical and general program setup for the Reset and Interrupt Vector Addresses in ATtiny2313 is:
    Address Labels Code                      Comments
    0x0000           rjmp    RESET           ; Reset Handler
...
    ;
    0x0013    RESET: ldi     r16, low(RAMEND); Main program start
    0x0014           out     SPL,r16            Set Stack Pointer to top of RAM

Which is exactly what the OP is doing.

So where's the problem?

JJ

/////////////////////////////////////////////////////////////////////////////////////

"Experience is what enables you to recognise a mistake the second time you make it."

"Good judgement comes from experience.  Experience comes from bad judgement."

"Wisdom is always wont to arrive late, and to be a little approximate on first possession."

"When you hear hoofbeats, think horses, not unicorns."

"Fast.  Cheap.  Good.  Pick two."

"We see a lot of arses on handlebars around here." - [J Ekdahl]

 

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

Problem solved and thanks for all the replies. I have the studio 4 on my computer but had never used it so I decided to give it a try. It seemed overwhelming at first but after playing around with it for a while I got my source code loaded into it, assembled, and started stepping into the program. The first thing I could see was the stack pointer was working correctly. Ramend does set the spl to the top of ram (DF) which is correct. After stepping through almost the entire program the problem jumped out at me. What I had done was use an rjmp instruction where an rcall was needed. Corrected this and now the program works correctly.

This simulator seems to be a wonderful thing. It is fun to play with.

Thanks
Roger

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

Quote:

It must be something else.

Score one to Res :-)