I currently have a branch of embassy that I am using successfully for an MSP430i2041-based project over here: https://github.com/vadixidav/embassy/tree/msp430. This issue is related to the note I left in this commit: vadixidav/embassy@2a43df7.
Essentially, I would like for embassy to put the CPU to sleep when not in use. This would normally mean executing the following:
asm!("bis #16, R2", options(nomem, nostack, preserves_flags));
However, I am unable to do this because, at the end of my interrupts, the compiler generated several pop instructions that pop registers from the stack. This is a perfectly reasonable and valid thing for it to do. The problem is that this prevents me from using the bic instruction to clear the CPUOFF bit in the SR before the generated reti instruction. What I really want to do is perform a bic instruction immediately before the reti instruction at the end of the interrupt. Then I could guarantee that the SR is on the top of the stack and clear the CPUOFF bit. The only way I can see to achieve this (though my imagination only goes so far) without making too significant of changes to Rust's msp430 support would be to ensure that the outermost stack frame doesn't need to push any registers so bic #16, @R1 will do what I want.
This is where msp430-rt comes in. I believe that the interrupt macro (#[interrupt]) should automatically do the following:
- Wrap the interrupt specified by the user in an inner function
- Call this inner function using a
call instruction (this forces the inner function to clean up its stack before returning)
- Add the line
asm!("bic #16, @R1"); after the call instruction
This would unconditionally wake the CPU back up after an interrupt.
I don't think this is perfectly ideal, but I believe that it would be better to unconditionally assume the CPU should be waken up after an interrupt than to wait until there is a proper solution that allows the user to specify if they would like to wake the CPU back up or not. Later we could add an inner inner function that returns a bool indicating if it should wake up or not and then set a static variable.
This very basic functionality I am suggesting could be added as a feature flag like wake-after-interrupt for people who are using msp430-rt with embassy. Any alternatives to solve this problem are welcome. The MSP430 toolchain has a built-in that allows you to set flags in the SP for the function that was interrupted that can only be executed in the outermost stack frame of the interrupt, but I don't think we can reasonably implement this without adding special features to Rust that probably aren't worth the effort at this stage.
I currently have a branch of embassy that I am using successfully for an MSP430i2041-based project over here: https://github.com/vadixidav/embassy/tree/msp430. This issue is related to the note I left in this commit: vadixidav/embassy@2a43df7.
Essentially, I would like for embassy to put the CPU to sleep when not in use. This would normally mean executing the following:
However, I am unable to do this because, at the end of my interrupts, the compiler generated several pop instructions that pop registers from the stack. This is a perfectly reasonable and valid thing for it to do. The problem is that this prevents me from using the
bicinstruction to clear the CPUOFF bit in the SR before the generatedreti instruction. What I really want to do is perform abicinstruction immediately before theretiinstruction at the end of the interrupt. Then I could guarantee that the SR is on the top of the stack and clear the CPUOFF bit. The only way I can see to achieve this (though my imagination only goes so far) without making too significant of changes to Rust's msp430 support would be to ensure that the outermost stack frame doesn't need to push any registers sobic #16, @R1will do what I want.This is where
msp430-rtcomes in. I believe that theinterruptmacro (#[interrupt]) should automatically do the following:callinstruction (this forces the inner function to clean up its stack before returning)asm!("bic #16, @R1");after thecallinstructionThis would unconditionally wake the CPU back up after an interrupt.
I don't think this is perfectly ideal, but I believe that it would be better to unconditionally assume the CPU should be waken up after an interrupt than to wait until there is a proper solution that allows the user to specify if they would like to wake the CPU back up or not. Later we could add an inner inner function that returns a bool indicating if it should wake up or not and then set a static variable.
This very basic functionality I am suggesting could be added as a feature flag like
wake-after-interruptfor people who are usingmsp430-rtwith embassy. Any alternatives to solve this problem are welcome. The MSP430 toolchain has a built-in that allows you to set flags in the SP for the function that was interrupted that can only be executed in the outermost stack frame of the interrupt, but I don't think we can reasonably implement this without adding special features to Rust that probably aren't worth the effort at this stage.