This wiki article describes the automatic context save/restore for the C28x CPU.
This also applies to devices with the FPU and VCU extensions.
The context save and restore is documented in [TMS320C28x CPU and Instruction Set Reference Guide (spru430)](https://www.ti.com/lit/pdf/spru430)
First, a few facts regarding the C28x stack pointer:
* The C28x stack pointer (SP) always points to the first empty address within the stack.
* The C28x stack grows from low address to high address.
* The context save performs 32-bit PUSH operations (not 16-bit).
* The context restore performs 32-bit POP operations (not 16-bit).
* The stack pointer itself is 16 bits. Therefore, the stack must always be in low memory not to exceed address 0xFFFF.
#32-bit Writes and Reads
32-bit writes and reads are always even aligned on the C28x. That is, a 32-bit
value uses an even address and the next odd no matter which address the write was to.
This is true for all 32-bit reads/writes on the C28x. You will never see a 32-bit
value use a odd location and the next even.
The following image shows a 32-bit PUSH to an even address:
The following image shows a 32-bit PUSH to an odd address. Notice that the write
is even aligned and is the same as if the stack pointer pointed to the previous even address.
If there had been data in location 0xC140 before the push, it would have
been overwritten!! We will use this knowledge in the next section.
#Automatic Context Save
When an interrupt is taken by the CPU, there is no way to know if the stack
pointer (SP) is even or odd. As we saw in the previous section, if the SP is odd
then the context save has the potential to overwrite a previous value already on the stack.
In order to account for this, the automatic context save will first increment the
stack by 1. This guarantees the data saved will not overwrite something already on the stack.
After the stack pointer is incremented by 1, a number of registers will automatically
be pushed onto the stack. These registers are documented in the [TMS320C28x CPU and Instruction Set Reference Guide (spru430)](https://www.ti.com/lit/pdf/spru430).
Each push is a 32-bit write to memory. This is always even aligned on the C28x;
a 32-bit word always takes up an even and the next odd.
The following image shows the save if the stack pointer is odd when the interrupt
is taken. Note that adding 1 to SP keeps the first PUSH from overwriting any data
in address 0xC140.
The first instruction within an ISR should always be the ASP instruction. If you
are writing in C, then the compiler will automatically add ASP for you. If the SP
is odd aligned, the ASP instruction will increment it by one so that it is even
aligned. In the case shown below the ASP instruction within the ISR has no effect.
It should still be used, however, since there is no way to control whether the SP
will be even or odd when an interrupt is taken.
The following image shows the context save if the stack pointer is even when the
interrupt is taken. In this case, adding 1 to SP before the save could have been
skipped, but there is no way to know if the interrupt was taken when the SP is
even or odd. Adding 1 to SP has no ill effect. Notice in this case the ASP instruction
within the ISR will force re-alignment of the stack. This is done so that any values
placed on the stack within the ISR will not overwrite part of the context save.
Having an even aligned stack is important for the C compiler. Also following this
convention can make things easier when programming in assembly.
Notice in both cases, each 32-bit push is even aligned. That is it takes up an even
address and the next odd no matter which address the SP points to. This is true for
all 32-bit reads/writes on the C28x. You will never see a 32-bit value use a odd
location and the next even.
#Automatic Context Restore
When an IRET instruction executes, an automatic context restore will be done before
the code returns to the point where the interrupt was taken. The automatic context
restore is simply the reverse of the automatic context save.
Before the IRET instruction, the ISR must execute the NASP instruction. This will
un-do any alignment that was performed by the ASP instruction. If you are writing
in C, then the compiler will automatically add the ASP and NASP instructions to
your interrupt service routine.
As a last step, the the SP is automatically decremented by 1 and, therefore,
ends up back to where it was before the interrupt was taken.