EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

modifying stack pointer fails when returning execution from RAM

Started by WobberJ June 23, 2005

Hi all,
I've posted this to P&E's site, but am cross-posting here
for any thoughts.
Thanks,
JoeW

*************************************************************

I'm implementing freescale's AN2720, which is a flash write algorithm
that pushes the final flash write routine onto the stack and then
executes it from RAM. I'm doing this on an hcs12c32 part, and
debugging with IAR tools using a Rev B Multilink BDM.

When returning execution from RAM to flash, the stack is free'd
using 'leas'.

The flash write succeeds. If I break on the 'leas' statement,
I can step over the statement and the stack pointer is properly
updated and execution continues normally.

However, if I execute through the 'leas' statement and break on the
statement after,
I can see that the stack pointer has not been updated. It appears
that the 'leas' statement did not execute. After that, the next stack
pointer operation causes program failure.

Any help is appreciated. Thanks in advance.
*************************************************************



Hi,
This problem has been resolved by adding this instruction to
the end of the "do_on_stack" assembly routine:

brclr FSTAT,#CBEIF,*

I'm not entirely sure why :-( , but it appears that waiting
for the flash buffers to clear is a necessary precursor to
returning execution to flash from ram.

Attached is the Do_On_Stack.s12 file that I've modified to
work for the C32 part.
JoeW

;*******************************************************************
;* MOTOROLA
;*
;* DESCRIPTION: S12 Flash Asm Routines
;* SOURCE: Do_On_Stack.asm
;* COPYRIGHT: 04/2004 Made in the USA
;* AUTHOR: rat579
;* REV. HISTORY: 060304 - fixed CCR return value and optimized
;* in SpSub routine
;*
;*
;*******************************************************************/
;*****************************************************************************
; Local defines
;*****************************************************************************
CBEIF EQU $80
FSTAT EQU $105
FCMD EQU $106
CCIF EQU $40
PAGE_ADDR EQU $30

RSEG CODE

;*********************************************************************
;* DoOnStack - copy SpSub onto stack and call it (see also SpSub)
;* De-allocates the stack space used by SpSub after returning from it.
;* Allows final steps in a flash prog/erase command to execute out
;* of RAM (on stack) while flash is out of the memory map
;* This routine can be used for flash word-program or erase commands
;*
;* Calling Convention:
;* jsr DoOnStack
;*
;* Uses 20 bytes on stack + 3 bytes if Call instruction used
;********************************************************************
public DoOnStack
DoOnStack
ldx #SpSubEnd-2 ;point at last word to move to stack
SpmoveLoop: ldd 2,x- ;read from flash
pshd ;move onto stack
cpx #SpSub-2 ;past end?
bne SpmoveLoop ;loop till whole sub on stack
tfr sp,x ;point to sub on stack
ldaa #CBEIF ;preload mask to register command
call 0,x,0 ;execute the sub on the stack
leas SpSubEnd-SpSub,sp ;de-allocate space used by sub
rts

;*********************************************************************
;* SpSub - register flash command and wait for Flash CCIF
;* this subroutine is copied onto the stack before executing
;* because you can't execute out of flash while a flash command is
;* in progress (see DoOnStack to see how this is used)
;*
;* Note: must be even # of bytes!
;*
;* Uses 20 bytes on stack + 3 bytes for CALL above
;*********************************************************************

SpSub:
tfr ccr,b ; get copy of ccr
orcc #$10 ; disable interrupts
staa FSTAT ; initiate command

brclr FSTAT,#CCIF,* ; wait for command to complete

brclr FSTAT,#CBEIF,* ; wait for buffers to become ready

tfr b,ccr ; restore ccr and int condition
rtc
SpSubEnd:

END
--- In 68HC12@68HC..., "WobberJ" <wobberj@y...> wrote:
>
> Hi all,
> I've posted this to P&E's site, but am cross-posting here
> for any thoughts.
> Thanks,
> JoeW
>
> *************************************************************
>
> I'm implementing freescale's AN2720, which is a flash write algorithm
> that pushes the final flash write routine onto the stack and then
> executes it from RAM. I'm doing this on an hcs12c32 part, and
> debugging with IAR tools using a Rev B Multilink BDM.
>
> When returning execution from RAM to flash, the stack is free'd
> using 'leas'.
>
> The flash write succeeds. If I break on the 'leas' statement,
> I can step over the statement and the stack pointer is properly
> updated and execution continues normally.
>
> However, if I execute through the 'leas' statement and break on the
> statement after,
> I can see that the stack pointer has not been updated. It appears
> that the 'leas' statement did not execute. After that, the next stack
> pointer operation causes program failure.
>
> Any help is appreciated. Thanks in advance.
> *************************************************************


--- In 68HC12@68HC..., "WobberJ" <wobberj@y...> wrote:
> Hi,
> This problem has been resolved by adding this instruction to
> the end of the "do_on_stack" assembly routine:
>
> brclr FSTAT,#CBEIF,*
>
> I'm not entirely sure why :-( , but it appears that waiting
> for the flash buffers to clear is a necessary precursor to
> returning execution to flash from ram.

Flash and EE operation take a relatively long time to complete, you either wait or set some timers/check the flags before using them.
I did time the EE once, in my case it was in excess of a milly second per location for a sequential programming cycle.

Simplest if you can wait around for this to finish.

Cheers,

Theo

> Attached is the Do_On_Stack.s12 file that I've modified to
> work for the C32 part.
> JoeW
>
> ;*******************************************************************
> ;* MOTOROLA
> ;*
> ;* DESCRIPTION: S12 Flash Asm Routines
> ;* SOURCE: Do_On_Stack.asm
> ;* COPYRIGHT: 04/2004 Made in the USA
> ;* AUTHOR: rat579
> ;* REV. HISTORY: 060304 - fixed CCR return value and optimized
> ;* in SpSub routine
> ;*
> ;*
> ;*******************************************************************/
> ;*****************************************************************************
> ; Local defines
> ;*****************************************************************************
> CBEIF EQU $80
> FSTAT EQU $105
> FCMD EQU $106
> CCIF EQU $40
> PAGE_ADDR EQU $30
>
> RSEG CODE
>
> ;*********************************************************************
> ;* DoOnStack - copy SpSub onto stack and call it (see also SpSub)
> ;* De-allocates the stack space used by SpSub after returning from it.
> ;* Allows final steps in a flash prog/erase command to execute out
> ;* of RAM (on stack) while flash is out of the memory map
> ;* This routine can be used for flash word-program or erase commands
> ;*
> ;* Calling Convention:
> ;* jsr DoOnStack
> ;*
> ;* Uses 20 bytes on stack + 3 bytes if Call instruction used
> ;********************************************************************
> public DoOnStack
> DoOnStack
> ldx #SpSubEnd-2 ;point at last word to move to stack
> SpmoveLoop: ldd 2,x- ;read from flash
> pshd ;move onto stack
> cpx #SpSub-2 ;past end?
> bne SpmoveLoop ;loop till whole sub on stack
> tfr sp,x ;point to sub on stack
> ldaa #CBEIF ;preload mask to register command
> call 0,x,0 ;execute the sub on the stack
> leas SpSubEnd-SpSub,sp ;de-allocate space used by sub
> rts
>
> ;*********************************************************************
> ;* SpSub - register flash command and wait for Flash CCIF
> ;* this subroutine is copied onto the stack before executing
> ;* because you can't execute out of flash while a flash command is
> ;* in progress (see DoOnStack to see how this is used)
> ;*
> ;* Note: must be even # of bytes!
> ;*
> ;* Uses 20 bytes on stack + 3 bytes for CALL above
> ;*********************************************************************
>
> SpSub:
> tfr ccr,b ; get copy of ccr
> orcc #$10 ; disable interrupts
> staa FSTAT ; initiate command
>
> brclr FSTAT,#CCIF,* ; wait for command to complete
>
> brclr FSTAT,#CBEIF,* ; wait for buffers to become ready
>
> tfr b,ccr ; restore ccr and int condition
> rtc
> SpSubEnd:
>
> END >
> --- In 68HC12@68HC..., "WobberJ" <wobberj@y...> wrote:
> >
> > Hi all,
> > I've posted this to P&E's site, but am cross-posting here
> > for any thoughts.
> > Thanks,
> > JoeW
> >
> > *************************************************************
> >
> > I'm implementing freescale's AN2720, which is a flash write algorithm
> > that pushes the final flash write routine onto the stack and then
> > executes it from RAM. I'm doing this on an hcs12c32 part, and
> > debugging with IAR tools using a Rev B Multilink BDM.
> >
> > When returning execution from RAM to flash, the stack is free'd
> > using 'leas'.
> >
> > The flash write succeeds. If I break on the 'leas' statement,
> > I can step over the statement and the stack pointer is properly
> > updated and execution continues normally.
> >
> > However, if I execute through the 'leas' statement and break on the
> > statement after,
> > I can see that the stack pointer has not been updated. It appears
> > that the 'leas' statement did not execute. After that, the next stack
> > pointer operation causes program failure.
> >
> > Any help is appreciated. Thanks in advance.
> > *************************************************************


It doesn't have anything to do with transfering execution from RAM
back to Flash. It has everything to do with the fact that you cannot
access a Flash bank which is still in a programming state. So what you
are doing is waiting for the Flash to finish being burned before you
can execute the code in that Flash.

I thought I saw an erratta that might affect this as well. Something
about the flags to tell if the burning is complete, where one method
didn't work right so I guess CBEIF does.

--- In 68HC12@68HC..., "WobberJ" <wobberj@y...> wrote:
> Hi,
> This problem has been resolved by adding this instruction to
> the end of the "do_on_stack" assembly routine:
>
> brclr FSTAT,#CBEIF,*
>
> I'm not entirely sure why :-( , but it appears that waiting
> for the flash buffers to clear is a necessary precursor to
> returning execution to flash from ram.
>



Hi,
I see your point.
Since the C32 part has only the one flash bank, you
have to execute the final steps from ram.
I'm new to the cpu, so my problem solving notes are skewed
to the specific part that I'm using.

I've looked at the errata here:
http://www.freescale.com/webapp/sps/site/prod_summ
ary.jsp?code=MC9S12C32&nodeId62468636bJwn#Errata

I don't see any reference to this problem.

None of the app notes (AN2720, AN2302) talk about having
to query the CBEIF flag for an indication of completion.
The CCIF flag is the one that is referenced.
JoeW

--- In 68HC12@68HC..., "Jefferson Smith" <imajeffs@h...>
wrote:
> It doesn't have anything to do with transfering execution from RAM
> back to Flash. It has everything to do with the fact that you cannot
> access a Flash bank which is still in a programming state. So what
you
> are doing is waiting for the Flash to finish being burned before you
> can execute the code in that Flash.
>
> I thought I saw an erratta that might affect this as well. Something
> about the flags to tell if the burning is complete, where one method
> didn't work right so I guess CBEIF does.
>
> --- In 68HC12@68HC..., "WobberJ" <wobberj@y...> wrote:
> > Hi,
> > This problem has been resolved by adding this instruction to
> > the end of the "do_on_stack" assembly routine:
> >
> > brclr FSTAT,#CBEIF,*
> >
> > I'm not entirely sure why :-( , but it appears that waiting
> > for the flash buffers to clear is a necessary precursor to
> > returning execution to flash from ram.
> >



The 2024 Embedded Online Conference