Register bank switching in ISR

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable
0 Likes
5 Replies
Anonymous
Not applicable

Somehow the post went missing after sending.

   

 

   

Anyway,  I am writing an ISR for a PWD module on the CY8C29466.  It is being written in assembler in the PWD_1INT.asm file for convenience.

   

here is the relevant code:

   

push X ;put CPU_X on the stack
push A ;put CPU_A on the stack
call PWD_1_DisableInt ;disable another interrupt during ISR
call PWD_1_ClearInt ;clear pending interrupt
call PUMP_1_Invert ;call routing to toggle pump state
call PWD_1_EnableInt ;turn interrupt back on
pop A ;restore A register
pop X ;restore X register

   

 

   

PUMP_1 is just an LED module.  The PWD interrupt is caused by a button press so it could happen at any moment.

   

My concern is that the LED module is going to write PRT2DR which is in bank 0.  Since the interrupt could happen at any time, the current bank set in the CPU_F register could be set to 1.  I could insert an M8C_SetBank0 inside the ISR, however then when the ISR returns to the original function, CPU_F XIO will still be 0 and that function would read or write the wrong register.

   

 

   

How can I preserve the F register's state inside the ISR so that it will return with the same state?  F cannot be pushed or popped and cannot be mov'd to X.
 

   

Thank you for your help with this.

0 Likes
TeHe_281121
Level 3
Level 3

Hi Colin,

   

From the TRM,

   

4.1.3 Interrupts
Interrupts, in a multi-page SRAM PSoC device, operate the
same as interrupts in a 256 byte PSoC device. However,
because the CPU_F register is automatically set to 0x00 on
an interrupt and because of the non-linear nature of interrupts
in a system, other parts of the PSoC memory paging
architecture can be affected.

   


Interrupts are an abrupt change in program flow. If no special
action is taken on interrupts by the PSoC device, the
interrupt service routine (ISR) could be thrown into any
SRAM page. To prevent this problem, the special addressing
modes for all memory accesses, except for stack and
MVI, are disabled when an ISR is entered.
The special
addressing modes are disabled when the CPU_F register is
cleared. At the end of the ISR, the previous SRAM addressing
mode is restored when the CPU_F register value is
restored by the RETI instruction.

   


Therefore, all interrupt service routine code will start execution
in SRAM Page 0
. If it is necessary for the ISR to change
to another SRAM page, it can be accomplished by changing
the values of the CPU_F[7:6] bits to enable the special
SRAM addressing modes. However, any change made to
the CUR_PP, IDX_PP, or STK_PP registers will persist after
the ISR returns. Therefore, the ISR should save the current
value of any paging register it modifies and restore its value
before the ISR returns.

   

 

   

So as long as you preserve and restore those _PP register, you are ok.

   

Also, during an interrupt the GIE is disabled, so that no other interrupt can occur during an ISR, unless you enable GIE in the ISR.

   

From the TRM

   

GIE is also cleared automatically when
an interrupt is processed, after the flag byte has been stored
on the stack, preventing nested interrupts. If desired, the bit
can be set in an interrupt service routine (ISR).

0 Likes
Anonymous
Not applicable

Thank you for pointing out section 4.1.3.  I had missed the bit that:

   

"At the end of the ISR, the previous SRAM addressing mode is restored when the CPU_F register value is restored by the RETI  insruction."

   

I didn't realize that RETI restores CPU_F.

   

I don't need to worry about preserving the state of the F register then. 

0 Likes
ETRO_SSN583
Level 9
Level 9
250 likes received 100 sign-ins 5 likes given

Moderator, another IP address to block, prior post in thread.

   

 

   

Regards, Dana.

0 Likes
Anonymous
Not applicable

 Another adverstisment 

0 Likes