Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

MSP430FR2153: General MSP430 Debugging question; tracking where code has been?

Part Number: MSP430FR2153
Other Parts Discussed in Thread: MSP-FET

Tool/software:

I've got a system issue that I'm trying to debug, but having issues figuring out how it's getting into the state in which we see the failure.  I have an interrupt, set to the highest priority, but as far as I can tell, it will miss the interrupt randomly - I have a "debounce" that checks if the line is still high and I set a flag if it's not.  So I've found a means for catching WHEN it happens, but, as far as I know, there's no reason it SHOULD be happening. 

In the past I've used a logic analyzer to see what memory addresses were running just before the failure, but I don't believe the MSP-FET has that feature.  I tried following the stack pointer back through the stack, but it doesn't seem to make sense.  Is there any way to look 'into the past' and see where the code jumped into the interrupt FROM... see what lines were running just before the interrupt triggered?  Again, it's very random, so I haven't found a breakpoint in the normal operating code that will only stop when the failure occurs, rather than during every normal operation.

TIA

Justin

  • I am confused by your statement that the interrupt is set to the highest priority. Since the MSP430 has fixed interrupt priorities, the only way to do that is to not enable interrupts with a higher priority. Some devices do have an Interrupt Compare Controller which can provide some very limited ways to alter the priorities.

    It would seem that you are asking how to tell what code was executed just before entering an ISR. The stack from is the only way to do that. Mostly.

    The EEM provides a very limited trace buffer that might help. See slaa393

    A little more information on the interrupt source would be helpful. Source, frequency, and even ISR code.

  • I'm using the ICC to set priorities.  The only higher priority interrupt that is active is the WDT, but the part is not resetting, so I don't believe that is triggering. 

        // set interrupt priorities
        // 1. Phase Load
        // 2. UART RX
        // 3. Heartbeat
        // P2 is Phase Load Interrupt, ILSR2 is BIT[5:4] of ICCILSR0, zero (0b00) is highest priority
        ICCILSR0 = 0xFFCF;
        // eUSCI_A1 Receive or Transmit Interrupt for UART Comms, ILSR10 is B[5:4] of ICCILSR1, one (0b01) is medium priority
        ICCILSR1 = 0xFFDF;
        // Timer B0 (heartbeat), ILSR21 is BIT[10:11] of ICCILRS2, three (0b11) is lowest priority
        ICCILSR2 = 0xFFFF;
        // enable ICC module
        ICCSC |= ICCEN;

    Right now, I am running an external test script that is sending a pulse to trigger the interrupt every 100ms or so.  The pulse is ~150us wide (I'm using a 24MHz clock, so this is a long pulse).  Between pulses, the script is requesting a value, so the code is running through other functions.  The script will run for seconds to minutes before the fault happens.

    And to be clear, what I'm seeing is that when the interrupt is triggered, occasionally the port pin associated with it is not high (using a scope to see what is happening).

    Here's the snippet of code:

    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector=PORT2_VECTOR
    __interrupt
    #elif defined(__GNUC__)
    __attribute__((interrupt(PORT2_VECTOR)))
    #endif
    void P2_ISR (void)
    //#endif // #if GPIO_PORT_S1
    {
        if (P2IFG & PS_LOAD_BIT)
        {
            // phase load interrupt
            __delay_cycles(100);
            if(!(P2IN & PS_LOAD_BIT)) {
                __no_operation();
                POWER_GPIO_POUT |= POWER_FLAG;
                P2IFG &= ~(PS_LOAD_BIT);
                return;
            }

    ..........

    I'm using that "power flag" as a test point and when this triggers the oscope, the PS_LOAD pin is low (and has been for quite some time).  When this happens, the code doesn't service the interrupt and things get out of sequence.  Perhaps I don't need to debounce, but I'm not sure what the code is doing where it wouldn't service that interrupt immediately.  We're having a few other random issues with the code and I'm hoping that solving this will shed light on other issues.

    I'll take a look at the app note and see if it might give me some options, thanks.

  • Given this, something else in your code is preventing timely servicing of the port interrupt. Another ISR most likely. (Remember that MSP430 interrupts are disabled on entry to the ISR.) If you can't figure out what it is, try disabling chunks of code.

    Not sure why you would need to debounce. The data sheet specifies a minimum pulse duration of 50ns to trigger a port interrupt.

    Oh, I would use the P2IV register as this automagically clears the IFG bit. Easier and safer than explicitly clearing it.

  • "Another ISR most likely."  That was my thought, as well.  Given the script we're running, no other ISRs should be active except during comms - which is my most likely suspect.  I was trying to find a way to trace the code before disabling functions, as I've seen once or twice in the past that simply changing the code organization CAN cause it to behave differently (rare).

    Debouncing is just something I've always done, as a "just in case".  I don't seem to have a noise issue right now and have been considering getting rid of that.  I likely will for all in the next build, thanks.

    I'll give the IV register a try.  As with the debounce, manually clearing the flag was just a "just in case" to ensure no other interrupts pulled the pointer away (I know, shouldn't happen).

    Thanks for your help.

**Attention** This is a public forum