Due to limited amount of flash on MSP430F2013 my bootloader (located in upper 1K of flash) handles some of low level I2C functionality and passes the execution to the application (located in lower 1K of flash). The execution is passed using a regular function call.
1. To change the power state on interrupt exit, the application needs to change the state of SR register on exit for an interrupt. For that, I have allocated a variable sr_address_on_exit (address 0x027C) that is shared between the bootloader and the application. Before the bootloader calls the application it would write the address of "stacked" SR register to 0x027C. If the application needed to change the power state on exit, it would get the address of where the SR is stored from 0x027C and update it as needed.
The problem is figuring out the location of SR on stack. Calling __get_SR_register_on_exit() returns the "interrupt exit" value of SR register.
Calling __get_SP_register() returns the current value and does not account for the frame size (PUSH.W calls at the beginning of the interrupt).
One way is to write the ISR in assembly language which at this point is not feasible.
Would be nice to have an intrinsic function __get_SP_on_exit() that would return the value of SP + "whatever is added by PUSH.W calls".
Is there any way to get the address of SR on stack with the current tools without writing the whole ISR in assembly?
2. An alternative is to call __get_SR_register_on_exit() and save the SR value in a shared location. If needed, the application would update the value at a shared location. Upon return to the bootloader, the value from a shared location should be written over the SR value on stack. In assembly, it could be done with one instruction. Since __set_SR_on_exit(val) does not exist, I have to make two calls:
__bic_SR_register_on_exit(~sr_value_on_exit);
__bis_SR_register_on_exit(sr_value_on_exit);
These unroll into four instructions:
MOV.W &sr_value_on_exit+0,r15
INV.W r15
BIC.W r15,10(SP)
BIS.W &sr_value_on_exit+0,10(SP)
Any way to get the compiler to generate an instruction:
MOV.W &sr_value_on_exit+0,10(SP)
automatically? This would replace 4 instructions with just 1 (save some flash space and execution time).