The Errata says:
Unpredictable code execution can occur if one of the hardware-clear-able IFGs UCSTTIFG, UCSTPIFG or UCNACKIFG is set while the global interrupt enable is set by software (GIE=1). This erratum is triggered if ALL of the following events occur in following order: 1. Pending Interrupt: One of the UCxIFG=1 AND UCxIE=1 while GIE=0 2. The GIE is set by software (e.g. EINT) 3. The pending interrupt is cleared by hardware (external I2C event) in a time window of 1 MCLK clock cycle after the "EINT" instruction is executed. Workaround: Disable the UCSTTIE, UCSTPIE and UCNACKIE before the GIE is set. After GIE is set, the local interrupt enable flags can be set again.
Upon entry into an ISR, GIE is cleared automatically in hardware, whereas upon "reti" the last status register value is popped from stack which reenables GIE. Is this a problem with respect to USCI39, or does setting GIE via "reti" not cause this bug?
The hardware multiply routines disable interrupts while running and restore the previous interrupt state when they finish. This makes them safe to use inside interrupt handlers as well as in normal code.
I can apply the workaround, when re-enabling interrupts in software that I control. However, I have no such control, if gcc generated code which calls into the CRT messes with interrupt states. I am not doing multiplications in interrupts anyways, and so far I have not seen bit shift operations being accelerated with the HW multiplier (for lack of a barrel shifter). I guess my question here is two-fold:
- Is there a way to break GCC out of its habit of disabling interrupts for multiplication, or:
- Is this required for the USCI39 workaround, at all? Namely: on -O3, gcc pushes r2 to stack and uses "pop r2" to reenable interrupts (if they were enabled). On -Os, function __mulhisi2 which uses reti to reenable GIE