Because of the Thanksgiving holiday in the U.S., TI E2E™ design support forum responses may be delayed from November 25 through December 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.

MSP432 P3.3 IRQ when NOT debugging

Guru 18515 points
Other Parts Discussed in Thread: ENERGYTRACE

Good afternoon,

my code sleeps and wakes up upon a rising edge interrupt on P3.3 pin :)

The code works when debugged. However, it does NOT when unplugged and I press the reset pin. I have seen similar E2E threads but was not able to apply the solutions there to success. BTW, just ignore the SPI section.

#include "msp.h"
#include <stdint.h>

#define WAKEUP		BIT3
#define SPI_CS 		BIT3
#define BLUE_LED 	BIT2
#define GREEN_LED	BIT1
#define RED_LED		BIT0

static uint8_t RXData[100] = { 0 };
volatile uint8_t idx_RXData = 0;

void send_cmd_to_spi(uint8_t, uint8_t);

void boardInit(void);

int main(void) {
	WDT_A->CTL = WDT_A_CTL_PW |             // Stop WDT
			WDT_A_CTL_HOLD;

	__delay_cycles(1000000);

	// Initialize GPIO and clocks
	boardInit();

	// Configuring P1 as output and P1.1 (switch) as input with pull-up resistor
	P3->SEL0 &= ~WAKEUP;
	P3->DIR &= ~WAKEUP;
	P3->OUT &= ~WAKEUP;
	P3->REN |= WAKEUP;
	P3->IFG &= ~WAKEUP;
	P3->IES &= ~WAKEUP; /*!< Port Interrupt Edge Select */
	P3->IE |= WAKEUP;

	// Turn off PSS high-side supervisors
	PSS->KEY = PSS_KEY_KEY_VAL;
	PSS->CTL0 |= PSS_CTL0_SVSMHOFF;
	PSS->KEY = 0;

	// Enable all SRAM bank retentions prior to going to LPM3 (Deep-sleep)
	SYSCTL->SRAM_BANKRET |= (SYSCTL_SRAM_BANKRET_BNK1_RET
			| SYSCTL_SRAM_BANKRET_BNK2_RET | SYSCTL_SRAM_BANKRET_BNK3_RET
			| SYSCTL_SRAM_BANKRET_BNK4_RET | SYSCTL_SRAM_BANKRET_BNK5_RET
			| SYSCTL_SRAM_BANKRET_BNK6_RET | SYSCTL_SRAM_BANKRET_BNK7_RET);

	// Enable global interrupt
	__enable_irq();

	// Enable Port 1 interrupt on the NVIC
	NVIC->ISER[1] = 1 << ((PORT3_IRQn) & 31);

	// Enter or Re-enter LPM4.5
	// Set the Power Mode 4.5
	PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_LPMR__LPM45;

	// Do not wake up on exit from ISR
	SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;

	// Setting the sleep deep bit
	SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);

	// some BOOT led (blue)
	P2->OUT |= BLUE_LED;
	__delay_cycles(1000000);
	P2->OUT &= ~BLUE_LED;

	// P3.2 as wake-up input pin, clear IFG, enable IE, low-to-high
	P3->SEL0 &= ~WAKEUP;
	P3->DIR &= ~WAKEUP;
	P3->OUT &= ~WAKEUP;
	P3->REN |= WAKEUP;
	P3->IFG &= ~WAKEUP;
	P3->IES &= ~WAKEUP; /*!< Port Interrupt Edge Select */
	P3->IE |= WAKEUP;

	// ---------------------------- start of spi section ----------------------------------

	// Set P1.5 CS low (but is active high)
	P1->DIR |= SPI_CS;
	P1->OUT &= ~SPI_CS;
	__delay_cycles(1000000);

	// Set P1.5, P1.6, and P1.7 as SPI pins functionality
	P1->SEL0 |= BIT5 | BIT6 | BIT7;

	EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST; // Put eUSCI state machine in reset
	EUSCI_B0->CTLW0 = EUSCI_B_CTLW0_SWRST | // Remain eUSCI state machine in reset
			EUSCI_B_CTLW0_MST |             // Set as SPI master
			EUSCI_B_CTLW0_MSB;              // MSB first

	// ACLK, /2, fBitClock = fBRCLK/(UCBRx+1), init USCI state machine
	EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SSEL__ACLK;
	EUSCI_B0->BRW = 0x01;
	EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;

	send_cmd_to_spi(0x0a, 0x0b);

	// ---------------------------- end of spi section ----------------------------------



	__sleep();
	__no_operation();
	// For debugger

	// Blink LED slowly if LPM4.5 not entered properly
	while (1) {
		P1->OUT ^= BIT0;                    // XOR P1.0
		__delay_cycles(1000000);
	}
}

// Port 1 interrupt service routine
void PORT3_IRQHandler(void) {
	P1->OUT |= BIT0;                        // Set P1.0
	__delay_cycles(500000);
	P1->OUT &= ~BIT0;                       // Clear P1.0

	P3->IFG &= ~WAKEUP;                       // Clear P1.1 IFG
}

void boardInit(void) {
	// GPIO Port Configuration for lowest power configuration
	P1->OUT = 0x00;
	P1->DIR = 0xFF;
	P2->OUT = 0x00;
	P2->DIR = 0xFF;
	P3->OUT = 0x00;
	P3->DIR = 0xFF;
	P4->OUT = 0x00;
	P4->DIR = 0xFF;
	P5->OUT = 0x00;
	P5->DIR = 0xFF;
	P6->OUT = 0x00;
	P6->DIR = 0xFF;
	P7->OUT = 0x00;
	P7->DIR = 0xFF;
	P8->OUT = 0x00;
	P8->DIR = 0xFF;
	P9->OUT = 0x00;
	P9->DIR = 0xFF;
	P10->OUT = 0x00;
	P10->DIR = 0xFF;
	PJ->OUT = 0x00;
	PJ->DIR = 0xFF;
}

Have a really nice day. Looking forward to your knowledge.

  • Thank you Kazola,
    I am not immediately aware of any potential difference introduced by the debugger. I will try and reproduce, but wanted to confirm that you are using the launchpad, Rev C silicon, and you are entering LPM4.5.

    Chris
  • kazola said:
    However, it does NOT when unplugged and I press the reset pin.

    Are you using the GCC or TI ARM compiler?

    The reason is that if using GCC with semihosting enabled, the program won't start unless running under the debugger.

  • Hi Chester,

    compiler is TI v.16.6.0,STS :)

    Or something like this, I am not wearing my glasses. Furthermore, I have a blue LED indicating the boot of the program, and it blinks when I press reset :)

  • Hi

    thanks for your help. I just received the MSP432 Launchpad, so should be the last one. It is not the black one, if this is what you are asking. It is red.

    Also, I think it is corretcly entering LPM4.5 since Free Run EnergyTrace indicates 0.0045 uW.
  • kazola said:
    The code works when debugged. However, it does NOT when unplugged and I press the reset pin.

    I can repeat that, on a black MSP432 launchpad with Rev B silicon.

    To investigate performed the following:

    a) Reset the board

    b) Saw the blue LED flash

    c) Put a rising edge on P3.3

    d) Attached the debugger. The debugger showed the program was within the __delay_cycles code inside the PORT3_IRQHandler():

    The Registers view shows that P1.0 should be a high, but yet the red LED is not on.

    Therefore, it appears that the act of the program entering LPM4.5 when the debugger is not attached caused the P1.0 output not to toggle for some reason.

  • Chester Gillon said:
    Therefore, it appears that the act of the program entering LPM4.5 when the debugger is not attached caused the P1.0 output not to toggle for some reason.

    When LPM4.5 is entered the LOCKLPM5 bit in the PCMCTL1 Register is set, which locks the values on the I/O pins.

    As the code doesn't clear the LOCKLPM5 bit , when the code wakes from LPM4.5 the code is unable to control the I/O pins.

    With the code modified to clear the LOCKLPM5 bit upon waking-up from LPM4.5 then when run without the debugger:

    a) The blue LED flashes after a power on, or press of the reset switch.

    b) The red LED flashes after a rising edge on P3.3

    #include "msp.h"
    #include <stdint.h>
    
    #define WAKEUP      BIT3
    #define SPI_CS      BIT3
    #define BLUE_LED    BIT2
    #define GREEN_LED   BIT1
    #define RED_LED     BIT0
    
    static uint8_t RXData[100] = { 0 };
    volatile uint8_t idx_RXData = 0;
    
    void send_cmd_to_spi(uint8_t, uint8_t);
    
    void boardInit(void);
    
    int main(void) {
        WDT_A->CTL = WDT_A_CTL_PW |             // Stop WDT
                WDT_A_CTL_HOLD;
    
        __delay_cycles(1000000);
    
        // Initialize GPIO and clocks
        boardInit();
    
        // Check if the MCU is waking-up from LPM4.5
        if (PCM->CTL1 & PCM_CTL1_LOCKLPM5)
        {
            // Configuring P3 as output and P3.3 (switch) as input with pull-down resistor
            P3->DIR &= ~WAKEUP;
            P3->OUT &= ~WAKEUP;
            P3->REN |= WAKEUP;
            P3->SEL0 = 0;
            P3->SEL1 = 0;
            P3->IE |= WAKEUP;
            P3->IES &= ~WAKEUP; /*!< Port Interrupt Edge Select */
    
            // Clear LPM lock
            PCM->CTL1 = PCM_CTL1_KEY_VAL;
        }
        else
        {
            // Else it is a cold-start
    
            // Configuring P3 as output and P3.3 (switch) as input with pull-down resistor
            // Rest of pins are configured as output low
            P3->DIR = ~WAKEUP;
            P3->OUT &= ~WAKEUP;
            P3->REN |= WAKEUP;                     // Enable pull-down resistor (P3.3 output low)
            P3->SEL0 = 0;
            P3->SEL1 = 0;
            P3->IFG = 0;                        // Clear all P3 interrupt flags
            P3->IE |= WAKEUP;
            P3->IES &= ~WAKEUP; /*!< Port Interrupt Edge Select */
    
            // some BOOT led (blue)
            P2->OUT |= BLUE_LED;
            __delay_cycles(1000000);
            P2->OUT &= ~BLUE_LED;
        }
    
        // Turn off PSS high-side supervisors
        PSS->KEY = PSS_KEY_KEY_VAL;
        PSS->CTL0 |= PSS_CTL0_SVSMHOFF;
        PSS->KEY = 0;
    
        // Enable all SRAM bank retentions prior to going to LPM3 (Deep-sleep)
        SYSCTL->SRAM_BANKRET |= (SYSCTL_SRAM_BANKRET_BNK1_RET
                | SYSCTL_SRAM_BANKRET_BNK2_RET | SYSCTL_SRAM_BANKRET_BNK3_RET
                | SYSCTL_SRAM_BANKRET_BNK4_RET | SYSCTL_SRAM_BANKRET_BNK5_RET
                | SYSCTL_SRAM_BANKRET_BNK6_RET | SYSCTL_SRAM_BANKRET_BNK7_RET);
    
        // Enable global interrupt
        __enable_irq();
    
        // Enable Port 3 interrupt on the NVIC
        NVIC->ISER[1] = 1 << ((PORT3_IRQn) & 31);
    
        // Enter or Re-enter LPM4.5
        // Set the Power Mode 4.5
        PCM->CTL0 = PCM_CTL0_KEY_VAL | PCM_CTL0_LPMR__LPM45;
    
        // Do not wake up on exit from ISR
        SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
    
        // Setting the sleep deep bit
        SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
    
        // ---------------------------- start of spi section ----------------------------------
    
        // Set P1.5 CS low (but is active high)
        P1->DIR |= SPI_CS;
        P1->OUT &= ~SPI_CS;
        __delay_cycles(1000000);
    
        // Set P1.5, P1.6, and P1.7 as SPI pins functionality
        P1->SEL0 |= BIT5 | BIT6 | BIT7;
    
        EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SWRST; // Put eUSCI state machine in reset
        EUSCI_B0->CTLW0 = EUSCI_B_CTLW0_SWRST | // Remain eUSCI state machine in reset
                EUSCI_B_CTLW0_MST |             // Set as SPI master
                EUSCI_B_CTLW0_MSB;              // MSB first
    
        // ACLK, /2, fBitClock = fBRCLK/(UCBRx+1), init USCI state machine
        EUSCI_B0->CTLW0 |= EUSCI_B_CTLW0_SSEL__ACLK;
        EUSCI_B0->BRW = 0x01;
        EUSCI_B0->CTLW0 &= ~EUSCI_B_CTLW0_SWRST;
    
        //send_cmd_to_spi(0x0a, 0x0b);
    
        // ---------------------------- end of spi section ----------------------------------
    
    
    
        __sleep();
        __no_operation();
        // For debugger
    
        // Blink LED slowly if LPM4.5 not entered properly
        while (1) {
            P1->OUT ^= BIT0;                    // XOR P1.0
            __delay_cycles(1000000);
        }
    }
    
    // Port 1 interrupt service routine
    void PORT3_IRQHandler(void) {
        P1->OUT |= BIT0;                        // Set P3.3
        __delay_cycles(500000);
        P1->OUT &= ~BIT0;                       // Clear P3.3
    
        P3->IFG &= ~WAKEUP;                       // Clear P3.3 IFG
    }
    
    void boardInit(void) {
        // GPIO Port Configuration for lowest power configuration
        P1->OUT = 0x00;
        P1->DIR = 0xFF;
        P2->OUT = 0x00;
        P2->DIR = 0xFF;
        P3->OUT = 0x00;
        P3->DIR = 0xFF;
        P4->OUT = 0x00;
        P4->DIR = 0xFF;
        P5->OUT = 0x00;
        P5->DIR = 0xFF;
        P6->OUT = 0x00;
        P6->DIR = 0xFF;
        P7->OUT = 0x00;
        P7->DIR = 0xFF;
        P8->OUT = 0x00;
        P8->DIR = 0xFF;
        P9->OUT = 0x00;
        P9->DIR = 0xFF;
        P10->OUT = 0x00;
        P10->DIR = 0xFF;
        PJ->OUT = 0x00;
        PJ->DIR = 0xFF;
    }
    

    [I didn't check the power consumption when the MSP432 is sleeping in LPM4.5]

  • I'm really thankful to you for confirming this! :)

**Attention** This is a public forum