This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430-GCC-OPENSOURCE: Errata USCI39 and RETI / hardware multiplier

Part Number: MSP430-GCC-OPENSOURCE

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?

slau646f says:

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:

  1. Is there a way to break GCC out of its habit of disabling interrupts for multiplication, or:
  2. 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
  • The problem, and I seem to recall it turning up in other contexts, is with the interrupt hardware. In effect what happens is that it sees that it needs to service an interrupt and begins that process. Then the information needed to pick an interrupt vector (the IFG) goes away. Leaving the interrupt hardware in a bad way. Which vector will it use? A spurious interrupt vector to be used in this instance would be nice.

    So I don't see it mattering very much how GIE gets set so long as the timing on the IFG being cleared is perfect.

    You can cure GCC of messing with the interrupt state when using the hardware multiplier by replacing the library code. You don't need to insert into the library, just make sure its object file precedes the library on the ld command line. This works for the optimization levels that use the library code but not for the level that inlines the code. It would be nice if there were an option to say that you will play nice in your ISRs (no multiplies) so that disabling interrupts isn't required. With a warning if a multiply sneaks into an ISR.

  • The problem, and I seem to recall it turning up in other contexts, is with the interrupt hardware. In effect what happens is that it sees that it needs to service an interrupt and begins that process. Then the information needed to pick an interrupt vector (the IFG) goes away. Leaving the interrupt hardware in a bad way. Which vector will it use? A spurious interrupt vector to be used in this instance would be nice.

    But then we have a much more serious issue!

    1. If this error exists for reti, in effect, what all of my ISRs (and I have many) must do before they return is to disable UCNACKIE, UCSTPIE, UCSTTIE for I2C peripherals, and reenable these flags after returning from this interrupt context. Can you confirm this view?

    2. What makes you so sure this error does not exist for UCTXIFG as well? In chapter 38.3.4.1.1 slau208q, UCTXIFG is cleared by hardware upon reception of a "NACK".

    3. What makes you so sure, that this error does not exist, when setting e.g. UCSTPIE, and exactly in this moment, UCSTPIFG is cleared by hardware?

    4. Assuming this errata does not apply to UCTXIFG, and that I do not have a multi-master bus, can you confirm, that Errata USCI39 only applies to USCI peripherals in slave mode, but not master?

    You can cure GCC of messing with the interrupt state when using the hardware multiplier by replacing the library code.

     I certainly don't want to mess with the CRT library on this level. I will just write my own inline asm macro.

    It would be nice if there were an option to say that you will play nice in your ISRs (no multiplies) so that disabling interrupts isn't required.

    Yes indeed.

    With a warning if a multiply sneaks into an ISR.

    Agreed. This would be important, as we don't know whether some GCC generated code optimisations would make use of the HW multiplier (though I doubt it, shift operations certainly do not at present, and using the HW multiplier for barrel shifts most readily comes to my mind as a possible optimisation).

  • From slau208q:

    1.3.4.2 Return From Interrupt
    The interrupt handling routine terminates with the instruction:
    RETI //return from an interrupt service routine
    The return from the interrupt takes five cycles to execute the following actions and is shown in Figure 1-5.
    1. The SR with all previous settings pops from the stack. All previous settings of GIE, CPUOFF, and
    others are now in effect, regardless of the settings used during the interrupt service routine.
    2. The PC pops from the stack and begins execution at the point where it was interrupted.

    The reti instruction is special in that it needs 5 MCLK cycles. After GIE is restored, it still must pop the PC from stack, which maybe closes the "1 MCLK" window from Errata USCI39. As opposed to that, a simple EINT only takes one MCLK (BIS.W #8, SR)

    FWIW, I don't have access to the Verilog / VHDL files or whatever TI uses to design their MSPs, so I cannot tell and this is something that only TI can verify.

    As I wrote in my previous comment, if "reti" has this problem, we're in a world of pain; a consequence of this is that all ISRs must then disable interrupt enable flags for all I2C peripherals where this problem can occur.

    And if this is a problem as well:

    3. What makes you so sure, that this error does not exist, when setting e.g. UCSTPIE, and exactly in this moment, UCSTPIFG is cleared by hardware?

    then erratum USCI39 fundamentally breaks I2C USCI and there is no good way to work around this problem.

  • Hi Thilo,

    I'll have to look into the other questions and get back to you, but regarding the RETI portion and whether USCI39 only applies to slave mode, I would refer to these related threads:

    https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/409917/help-on-dealing-with-usci39-on-a-5xx-msp430

    https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/462451/msp430f5335-crashing

    In thread 2, the answer is that RETI can trigger this errata and that this errata mostly impacts slave mode.

    Thanks,

    Urica Wang

**Attention** This is a public forum