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.
From the TRM,
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).
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.
Moderator, another IP address to block, prior post in thread.