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.

Simultaneous use of port1 & port2 interrupt on MSP432 not working MSP-EXP432P401R

I am modifying example "msp432p401_p1_03", where an external interrupt is generated for port1.1 with the button. I'm using CCS 6.1.2.00015

I have extended this example to do the same for port2.7, with another button (for argument's sake).

But it is not working; only interrupt 1 is generated, as was provided in the example.

If I change the order in ISER[ ] the program doesn't work at all.

NVIC->ISER[2] = 1 << ((PORT2_IRQn) & 31);

NVIC->ISER[1] = 1 << ((PORT1_IRQn) & 31);

I also tried

NVIC_EnableIRQ(PORT1_IRQn); // Enable PORT1 Interrupt
NVIC_EnableIRQ(PORT2_IRQn); // Enable PORT2 Interrupt

but that doesn't work either: as long as interrupt 2 has not been generated, interrupt 1 works. Once interrupt 2 has been generated, interrupt 1 stops functioning.

Questions:

1) what to do?

2) does anybody know where to get information about practical use of the NVIC?

Here is the code:

#include "msp.h"
int main(void)
{
    /* Hold the watchdog */
    WDTCTL = WDTPW | WDTHOLD;

    P1DIR = ~(uint8_t) BIT1;			    // p1.1 input
    P2DIR = ~(uint8_t) BIT7;                // p2.7 input

    P1REN = BIT1;                           // Enable pull-up resistor P1.1
    P2REN = BIT7;                           // Enable pull-up resistor P2.7

    P1IFG = 0;                              // Clear all P1 interrupt flags
    P2IFG = 0;                              // Clear all P2 interrupt flags

    P1IE = BIT1;                            // Enable interrupt for P1.1
    P2IE = BIT7;                            // Enable interrupt for P2.7

    P1IES = BIT1;                               // Interrupt on high-to-low transition
    P2IES = BIT7;                               // Interrupt on high-to-low transition

  //  NVIC_EnableIRQ(PORT1_IRQn);     // Enable PORT1 Interrupt
  //  NVIC_EnableIRQ(PORT2_IRQn);     // Enable PORT2 Interrupt

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

    /* Configure Port J */
    PJDIR |= (BIT2 | BIT3); PJOUT &= ~(BIT2 | BIT3);

    /* PJ.0 & PJ.1 configured for XT1 */
    PJSEL0 |= BIT0 | BIT1;
    PJSEL1 &= ~(BIT0 | BIT1);

    /* Starting LFXT in non-bypass mode without a timeout. */
    CS->KEY = CS_KEY_VAL ;
    CS->CTL1 &= ~(CS_CTL1_SELA_MASK | CS_CTL1_SELB);
    CS->CTL1 |= CS_CTL1_SELA__LFXTCLK;                // Source LFXTCLK to ACLK & BCLK
    CS->CTL2 &= ~(CS_CTL2_LFXTDRIVE_MASK);               // Configure to lowest drive-strength    
    CS->CTL2 |= CS_CTL2_LFXT_EN;
    while (CS->IFG & CS_IFG_LFXTIFG)
        CS->CLRIFG |= CS_IFG_LFXTIFG;
    CS->KEY = 0;
    /* Turn off PSS high-side supervisors */
    PSS->KEY = PSS_KEY_KEY_VAL;
    PSS->CTL0 |= PSS_CTL0_SVSMHOFF;
    PSS->KEY = 0;

    /* Enable PCM rude mode, which allows to device to enter LPM3 without waiting for peripherals */
    PCM->CTL1 = PCM_CTL0_KEY_VAL | PCM_CTL1_FORCE_LPM_ENTRY;

    /* Enable all SRAM bank retentions prior to going to LPM3  */
    SYSCTL->SRAM_BANKRET |= SYSCTL_SRAM_BANKRET_BNK7_RET;
    __enable_interrupt();
    SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;           // Do not wake up on exit from ISR


    /* Setting the sleep deep bit */
    SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
    /* Go to LPM3 */
    __sleep();
}

void PORT1_IRQHandler(void)
{
    if(P1IFG & BIT1){
    	P1OUT^=BIT0;
    }
    P1IFG &= ~BIT1;
}

void PORT2_IRQHandler(void)
{
    if(P2IFG & BIT7){
    	P1OUT^=BIT0;
    }
    P2IFG &= ~BIT7;
}


  • Hi mime,

     Please change your code from

        NVIC->ISER[2] = 1 << ((PORT2_IRQn) & 31);

    to

        NVIC->ISER[1] = 1 << ((PORT2_IRQn) & 31);

    Hopefully that should the trick. At the same time please take a look at the section 6.6.2 in the MSP432 datasheet (Table 6-12 NVIC Interrupts)

      Best regards,

        David

  • Hi David,

    thanks for the quick reply. Unfortunately, using ISER[1] for both interrupts didn't work; it just causes the same behaviour that I described earlier when switching the ISER order. In both cases, interrupt 1 ISR works as long as interrupt 2 hasn't been triggered, and PORT2 ISR is never executed

    Also, putting a hardware breakpoint in the PORT1 ISR only works when the PORT2 ISR has not been triggered yet, whereas triggering the PORT2 ISR doesn't ever land on a hardware breakpoint in the PORT2 ISR.

    So it seems that for the PORT2 interrupt, the program doesn't jump to the right program code and then gets lost.

    Strangely enough, if PORT2 interrupt gets given ISER[2], then the PORT1 ISR keeps working fine, even when interrupt 2 is triggered (although it still doesn't perform the PORT2 ISR).

    Summarising: 

    PORT1 with ISER[1], PORT2 with ISER[2]  ==> PORT1 ISR works always, PORT2 ISR never executed

    PORT1 with ISER[1], PORT2 with ISER[1] ==> PORT1 ISR works as long as PORT2 interrupt has not been triggered, PORT2 ISR never executed

    PORT1 with ISER[2], PORT2 with ISER[1] ==> PORT1 ISR never executed, PORT2 ISR never executed.

    Here comes a bit of a rant:

    Thank you for the datasheet link, but I was hoping for something more higher level, a walk-through, if you will. I have quite a bit of experience on other processor families, including NVIC, so I know what to do, I just don't know how to do it on this particular solution.

    In the meantime, I found http://dev.ti.com/tirex/#/?link=MSPWare%2FDevices%2FMSP432P4XX%2FMSP432P401R

    and http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP432_Driver_Library/latest/exports/driverlib/doc/MSP432P4xx/html/driverlib_html/index.html

    This is what I am looking for... if it had examples. Now I'm trying to paste in things like:

    Interrupt_registerInterrupt(PORT1_IRQn,PORT1_IRQHandler());
        Interrupt_registerInterrupt(PORT2_IRQn,PORT2_IRQHandler());
    
        Interrupt_setPriority(PORT1_IRQn,1);
        Interrupt_setPriority(PORT2_IRQn,2);
    
        Interrupt_enableInterrupt( PORT1_IRQn);
        Interrupt_enableInterrupt( PORT2_IRQn);

    but it complains that 

    "function "PORT1_IRQHandler" declared implicitly" and "argument of type "int" is incompatible with parameter of type "void (*)(void)".

    Which is of course true, because what I tried would have been too easy. But without an example I'm stuck there. The API documentation is not more helpful there either, because:

    "The use of this function (directly or indirectly via a peripheral driver interrupt register function) moves the interrupt vector table from flash to SRAM. Therefore, care must be taken when linking the application to ensure that the SRAM vector table is located at the beginning of SRAM; otherwise the NVIC does not look in the correct portion of memory for the vector table (it requires the vector table be on a 1 kB memory alignment). Normally, the SRAM vector table is so placed via the use of linker scripts. See the discussion of compile-time versus run-time interrupt handler registration in the introduction to this chapter.This function is only used if the customer wants to specify the interrupt handler at run time. In most cases, this is done through means of the user setting the ISR function pointer in the startup file. Refer Refer to the Module Operation section for more details."

    So basically, the driverlib does not offer an easier way to just register an ISR, but an easier way to do something really complicated. Not an easy way of doingsomething that should just be easy.

    Then I found an example, "interrupt priority masking":

    http://dev.ti.com/tirex/#/?link=MSPWare%2FLibraries%2FDriver%20Library%2FMSP432P4xx%2FExample%20Projects%2FINTERRUPT

    Strangely enough, the example uses functions that are not described in the online API of the driverlib.

    http://dev.ti.com/tirex/#/?link=MSPWare%2FLibraries%2FDriver%20Library%2FMSP432P4xx%2FAPI%20Programmer's%20Guide

    Anyway, here's the new code:

    
    

    #include "msp.h"
    #include "C:\ti\msp430\MSPWare_3_20_00_37\driverlib\driverlib\MSP432P4xx\driverlib.h"
    #include "C:\ti\msp430\MSPWare_3_20_00_37\driverlib\driverlib\MSP432P4xx\gpio.h"
    
    #include <stdbool.h>
    #include <stdint.h>
    
    int main(void)
    {
        /* Hold the watchdog */
        WDTCTL = WDTPW | WDTHOLD;
    
        P1DIR = ~(uint8_t) BIT1;			    // p1.1 input
        P2DIR = ~(uint8_t) BIT7;                // p2.7 input
    
        P1REN = BIT1;                           // Enable pull-up resistor P1.1
        P2REN = BIT7;                           // Enable pull-up resistor P2.7
    
        P1IFG = 0;                              // Clear all P1 interrupt flags
        P2IFG = 0;                              // Clear all P2 interrupt flags
    
        P1IE = BIT1;                            // Enable interrupt for P1.1
        P2IE = BIT7;                            // Enable interrupt for P2.7
    
        P1IES = BIT1;                               // Interrupt on high-to-low transition
        P2IES = BIT7;                               // Interrupt on high-to-low transition
    
      //  NVIC_EnableIRQ(PORT1_IRQn);     // Enable PORT1 Interrupt
      //  NVIC_EnableIRQ(PORT2_IRQn);     // Enable PORT2 Interrupt
    
       // NVIC->ISER[2] = 1 << ((PORT2_IRQn) & 31);
       // NVIC->ISER[1] = 1 << ((PORT1_IRQn) & 31);     // Enable Port 1 interrupt on the NVIC
    
    
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, GPIO_PIN7);
    
    
        /* Configuring interrupt priorities and setting the priority mask to 0x40 */
    	MAP_Interrupt_setPriority(INT_PORT1, 0x20);
    	MAP_Interrupt_setPriority(INT_PORT2, 0x40);
    
    	/* Enabling interrupts */
    	MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
    	MAP_GPIO_enableInterrupt(GPIO_PORT_P2, GPIO_PIN7);
    
    	MAP_Interrupt_enableInterrupt(INT_PORT1);
    	MAP_Interrupt_enableInterrupt(INT_PORT2);
    
    
        /* Configure Port J */
        PJDIR |= (BIT2 | BIT3); PJOUT &= ~(BIT2 | BIT3);
    
        /* PJ.0 & PJ.1 configured for XT1 */
        PJSEL0 |= BIT0 | BIT1;
        PJSEL1 &= ~(BIT0 | BIT1);
    
        /* Starting LFXT in non-bypass mode without a timeout. */
        CS->KEY = CS_KEY_VAL ;
        CS->CTL1 &= ~(CS_CTL1_SELA_MASK | CS_CTL1_SELB);
        CS->CTL1 |= CS_CTL1_SELA__LFXTCLK;                // Source LFXTCLK to ACLK & BCLK
        CS->CTL2 &= ~(CS_CTL2_LFXTDRIVE_MASK);               // Configure to lowest drive-strength    
        CS->CTL2 |= CS_CTL2_LFXT_EN;
        while (CS->IFG & CS_IFG_LFXTIFG)
            CS->CLRIFG |= CS_IFG_LFXTIFG;
        CS->KEY = 0;
        /* Turn off PSS high-side supervisors */
        PSS->KEY = PSS_KEY_KEY_VAL;
        PSS->CTL0 |= PSS_CTL0_SVSMHOFF;
        PSS->KEY = 0;
    
        /* Enable PCM rude mode, which allows to device to enter LPM3 without waiting for peripherals */
        PCM->CTL1 = PCM_CTL0_KEY_VAL | PCM_CTL1_FORCE_LPM_ENTRY;
    
        /* Enable all SRAM bank retentions prior to going to LPM3  */
        SYSCTL->SRAM_BANKRET |= SYSCTL_SRAM_BANKRET_BNK7_RET;
        __enable_interrupt();
        SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;           // Do not wake up on exit from ISR
    
    
        /* Setting the sleep deep bit */
        SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk);
        /* Go to LPM3 */
        __sleep();
    }
    
    void PORT1_IRQHandler(void)
    {
        if(P1IFG & BIT1){
        	P1OUT^=BIT0;
        }
        P1IFG &= ~BIT1;
    }
    
    void PORT2_IRQHandler(void)
    {
        if(P2IFG & BIT7){
        	P1OUT^=BIT0;
        }
        P2IFG &= ~BIT7;
    }
    
    

    The changes I have made have MAP in the function name. This driverlib has a very readable syntax, which I find great. Unfortunately, I couldn't get the example to work, because the linker is unhappy:

    symbol in file 
    --------- ---------------- 
    GPIO_clearInterruptFlag ./msp432p401_p1_03.obj
    GPIO_enableInterrupt ./msp432p401_p1_03.obj

    error #10234-D: unresolved symbols remain
    error #10010: errors encountered during linking; "msp432p401_p1_03.out" not built

    It seems the linker doesn't know where to find the functions (?)

    best,

    mime

  • Hi mime,

     Sorry to hear that you are still having problmes. Quick question, did you make any modification to your startup file (startup_msp432p401r_ccs.c)??

    If not, please make sure that you include PORT2_IRQHandler similar to PORT1_IRQHandler.

    And retry scenario:

    PORT1 with ISER[1], PORT2 with ISER[1] ==> PORT1 ISR works as long as PORT2 interrupt has not been triggered, PORT2 ISR never executed

    In regards to your driverlib question, you are missing some include folders in your project and the driverlib.lib so I would recommend the following:

    1. Import a driverlib project using resource explorer:

    2. Add your code for the P2.7 interrupt (main.c)

        /* Configuring P2.7 as an input and enabling interrupts */
        MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2, GPIO_PIN7);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, GPIO_PIN7);
        MAP_GPIO_enableInterrupt(GPIO_PORT_P2, GPIO_PIN7);
        MAP_Interrupt_enableInterrupt(INT_PORT2);
    
    void PORT2_IRQHandler(void) { uint32_t status; status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P2); MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, status); /* Toggling the output on the LED */ if(status & GPIO_PIN7) { MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0); } }

    3. Add the Port2 ISR in the interrupt Vector table (startup_msp432p401r_ccs.c)

        defaultISR,                             /* DMA_INT0 ISR              */
        PORT1_IRQHandler,                       /* PORT1 ISR                 */
    	PORT2_IRQHandler,                       /* PORT2 ISR                 */
        defaultISR,                             /* PORT3 ISR                 */
    

    I'm also attaching my code.

    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v3_10_00_09 
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2014, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    //*****************************************************************************
    //
    // Copyright (C) 2012 - 2015 Texas Instruments Incorporated - http://www.ti.com/
    //
    // Redistribution and use in source and binary forms, with or without
    // modification, are permitted provided that the following conditions
    // are met:
    //
    //  Redistributions of source code must retain the above copyright
    //  notice, this list of conditions and the following disclaimer.
    //
    //  Redistributions in binary form must reproduce the above copyright
    //  notice, this list of conditions and the following disclaimer in the
    //  documentation and/or other materials provided with the
    //  distribution.
    //
    //  Neither the name of Texas Instruments Incorporated nor the names of
    //  its contributors may be used to endorse or promote products derived
    //  from this software without specific prior written permission.
    //
    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    //
    // MSP432 Family Interrupt Vector Table for CGT
    //
    //****************************************************************************
    
    #include <stdint.h>
    
    /* Forward declaration of the default fault handlers. */
    static void resetISR(void);
    static void nmiISR(void);
    static void faultISR(void);
    static void defaultISR(void);
    
    
    /* External declaration for the reset handler that is to be called when the */
    /* processor is started                                                     */
    extern void _c_int00(void);
    
    /* External declaration for system initialization function                  */
    extern void SystemInit(void);
    
    /* Linker variable that marks the top of the stack. */
    extern unsigned long __STACK_END;
    
    
    /* External declarations for the interrupt handlers used by the application. */
    extern void PORT1_IRQHandler (void);
    extern void PORT2_IRQHandler (void);
    
    /* Interrupt vector table.  Note that the proper constructs must be placed on this to  */
    /* ensure that it ends up at physical address 0x0000.0000 or at the start of          */
    /* the program if located at a start address other than 0.                            */
    #pragma RETAIN(interruptVectors)
    #pragma DATA_SECTION(interruptVectors, ".intvecs")
    void (* const interruptVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_END),
                                                /* The initial stack pointer */
        resetISR,                               /* The reset handler         */
        nmiISR,                                 /* The NMI handler           */
        faultISR,                               /* The hard fault handler    */
        defaultISR,                             /* The MPU fault handler     */
        defaultISR,                             /* The bus fault handler     */
        defaultISR,                             /* The usage fault handler   */
        0,                                      /* Reserved                  */
        0,                                      /* Reserved                  */
        0,                                      /* Reserved                  */
        0,                                      /* Reserved                  */
        defaultISR,                             /* SVCall handler            */
        defaultISR,                             /* Debug monitor handler     */
        0,                                      /* Reserved                  */
        defaultISR,                             /* The PendSV handler        */
        defaultISR,                             /* The SysTick handler       */
        defaultISR,                             /* PSS ISR                   */
        defaultISR,                             /* CS ISR                    */
        defaultISR,                             /* PCM ISR                   */
        defaultISR,                             /* WDT ISR                   */
        defaultISR,                             /* FPU ISR                   */
        defaultISR,                             /* FLCTL ISR                 */
        defaultISR,                             /* COMP0 ISR                 */
        defaultISR,                             /* COMP1 ISR                 */
        defaultISR,                             /* TA0_0 ISR                 */
        defaultISR,                             /* TA0_N ISR                 */
        defaultISR,                             /* TA1_0 ISR                 */
        defaultISR,                             /* TA1_N ISR                 */
        defaultISR,                             /* TA2_0 ISR                 */
        defaultISR,                             /* TA2_N ISR                 */
        defaultISR,                             /* TA3_0 ISR                 */
        defaultISR,                             /* TA3_N ISR                 */
        defaultISR,                             /* EUSCIA0 ISR               */
        defaultISR,                             /* EUSCIA1 ISR               */
        defaultISR,                             /* EUSCIA2 ISR               */
        defaultISR,                             /* EUSCIA3 ISR               */
        defaultISR,                             /* EUSCIB0 ISR               */
        defaultISR,                             /* EUSCIB1 ISR               */
        defaultISR,                             /* EUSCIB2 ISR               */
        defaultISR,                             /* EUSCIB3 ISR               */
        defaultISR,                             /* ADC14 ISR                 */
        defaultISR,                             /* T32_INT1 ISR              */
        defaultISR,                             /* T32_INT2 ISR              */
        defaultISR,                             /* T32_INTC ISR              */
        defaultISR,                             /* AES ISR                   */
        defaultISR,                             /* RTC ISR                   */
        defaultISR,                             /* DMA_ERR ISR               */
        defaultISR,                             /* DMA_INT3 ISR              */
        defaultISR,                             /* DMA_INT2 ISR              */
        defaultISR,                             /* DMA_INT1 ISR              */
        defaultISR,                             /* DMA_INT0 ISR              */
        PORT1_IRQHandler,                       /* PORT1 ISR                 */
    	PORT2_IRQHandler,                       /* PORT2 ISR                 */
        defaultISR,                             /* PORT3 ISR                 */
        defaultISR,                             /* PORT4 ISR                 */
        defaultISR,                             /* PORT5 ISR                 */
        defaultISR,                             /* PORT6 ISR                 */
        defaultISR,                             /* Reserved 41               */
        defaultISR,                             /* Reserved 42               */
        defaultISR,                             /* Reserved 43               */
        defaultISR,                             /* Reserved 44               */
        defaultISR,                             /* Reserved 45               */
        defaultISR,                             /* Reserved 46               */
        defaultISR,                             /* Reserved 47               */
        defaultISR,                             /* Reserved 48               */
        defaultISR,                             /* Reserved 49               */
        defaultISR,                             /* Reserved 50               */
        defaultISR,                             /* Reserved 51               */
        defaultISR,                             /* Reserved 52               */
        defaultISR,                             /* Reserved 53               */
        defaultISR,                             /* Reserved 54               */
        defaultISR,                             /* Reserved 55               */
        defaultISR,                             /* Reserved 56               */
        defaultISR,                             /* Reserved 57               */
        defaultISR,                             /* Reserved 58               */
        defaultISR,                             /* Reserved 59               */
        defaultISR,                             /* Reserved 60               */
        defaultISR,                             /* Reserved 61               */
        defaultISR,                             /* Reserved 62               */
        defaultISR                              /* Reserved 63               */
    };
    
    
    /* This is the code that gets called when the processor first starts execution */
    /* following a reset event.  Only the absolutely necessary set is performed,   */
    /* after which the application supplied entry() routine is called.  Any fancy  */
    /* actions (such as making decisions based on the reset cause register, and    */
    /* resetting the bits in that register) are left solely in the hands of the    */
    /* application.                                                                */
    void resetISR(void)
    {
        SystemInit();
    
        /* Jump to the CCS C Initialization Routine. */
        __asm("    .global _c_int00\n"
              "    b.w     _c_int00");
    }
    
    /* This is the code that gets called when the processor receives a NMI.  This  */
    /* simply enters an infinite loop, preserving the system state for examination */
    /* by a debugger.                                                              */
    static void nmiISR(void)
    {
        /* Fault trap exempt from ULP advisor */
        #pragma diag_push
        #pragma CHECK_ULP("-2.1")
    
        /* Enter an infinite loop. */
        while(1)
        {
        }
    
        #pragma diag_pop
    }
    
    
    /* This is the code that gets called when the processor receives a fault        */
    /* interrupt.  This simply enters an infinite loop, preserving the system state */
    /* for examination by a debugger.                                               */
    static void faultISR(void)
    {
        /* Fault trap exempt from ULP advisor */
        #pragma diag_push
        #pragma CHECK_ULP("-2.1")
    
        /* Enter an infinite loop. */
        while(1)
        {
        }
    
        #pragma diag_pop
    }
    
    
    /* This is the code that gets called when the processor receives an unexpected  */
    /* interrupt.  This simply enters an infinite loop, preserving the system state */
    /* for examination by a debugger.                                               */
    static void defaultISR(void)
    {
        /* Fault trap exempt from ULP advisor */
        #pragma diag_push
        #pragma CHECK_ULP("-2.1")
    
        /* Enter an infinite loop. */
        while(1)
        {
        }
    
        #pragma diag_pop
    }
    

    /*
     * -------------------------------------------
     *    MSP432 DriverLib - v3_10_00_09 
     * -------------------------------------------
     *
     * --COPYRIGHT--,BSD,BSD
     * Copyright (c) 2014, Texas Instruments Incorporated
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * *  Redistributions of source code must retain the above copyright
     *    notice, this list of conditions and the following disclaimer.
     *
     * *  Redistributions in binary form must reproduce the above copyright
     *    notice, this list of conditions and the following disclaimer in the
     *    documentation and/or other materials provided with the distribution.
     *
     * *  Neither the name of Texas Instruments Incorporated nor the names of
     *    its contributors may be used to endorse or promote products derived
     *    from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
     * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * --/COPYRIGHT--*/
    /*******************************************************************************
     * MSP432 GPIO - Input Interrupt
     *
     * Description: This example demonstrates a very simple use case of the
     * DriverLib GPIO APIs. P1.1 (which has a switch connected to it) is configured
     * as an input with interrupts enabled and P1.0 (which has an LED connected)
     * is configured as an output. When the switch is pressed, the LED output
     * is toggled.
     *
     *                MSP432P401
     *             ------------------
     *         /|\|                  |
     *          | |                  |
     *          --|RST         P1.0  |---> P1.0 LED
     *            |                  |
     *            |            P1.1  |<--Toggle Switch
     *            |                  |
     *            |                  |
     *
     * Author: Timothy Logan
     ******************************************************************************/
    /* DriverLib Includes */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    
    #include <stdbool.h>
    
    int main(void)
    {
        volatile uint32_t ii;
    
        /* Halting the Watchdog */
        MAP_WDT_A_holdTimer();
    
        /* Configuring P1.0 as output and P1.1 (switch) as input */
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
    
        /* Configuring P1.1 as an input and enabling interrupts */
        MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
        MAP_Interrupt_enableInterrupt(INT_PORT1);
    
        /* Configuring P2.7 as an input and enabling interrupts */
        MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2, GPIO_PIN7);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, GPIO_PIN7);
        MAP_GPIO_enableInterrupt(GPIO_PORT_P2, GPIO_PIN7);
        MAP_Interrupt_enableInterrupt(INT_PORT2);
    
    
        /* Enabling SRAM Bank Retention */
        MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);
        
        /* Enabling MASTER interrupts */
        MAP_Interrupt_enableMaster();   
    
        /* Going to LPM3 */
        while (1)
        {
            MAP_PCM_gotoLPM3();
        }
    }
    
    /* GPIO ISR */
    void PORT1_IRQHandler(void)
    {
        uint32_t status;
    
        status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
    
        /* Toggling the output on the LED */
        if(status & GPIO_PIN1)
        {
            MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
        }
    
    }
    
    void PORT2_IRQHandler(void)
    {
        uint32_t status;
    
        status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P2);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, status);
    
        /* Toggling the output on the LED */
        if(status & GPIO_PIN7)
        {
            MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
        }
    
    }
    

    Hopefully this helps.

      David

  • Hi David,

    when I saw the first lines of your post I realised that that was going to solve things.. and it did!

    It also explains the behaviour; if an ISR is not found, the program goes into an infinite loop.

    Many thanks. If it's not too much trouble, could you tell me where I could find the documentation that talks about the startup_* file?

    Another question: I'd like to include files to the project myself. But I can't figure out how.

    In the project tree, I expanded "includes" and tried to right-click and left-click, but there are no mouse menus popping up.

    There is nothing under the "project" pull down menu at the top.

    Also: I'm very confused about the gpio_input_interrupt.c example. I tried to make that example work, just as the mspware example.

    The strange thing is: ISR_PORT1 is working, and toggles the LED. ISR_PORT2 is also working: it arrives when I put a hardware trigger on

     if(status & GPIO_PIN7)


    But it never enters the if statement! It fails to recognise that PIN7 was the pin that triggered the interrupt. When I hover over "status" with the mouse pointer during during a hardware breakpoint on "if(status & GPIO_PIN7), status is always 0. (and I did add "volatile" to tell the compiler to hang on to that variable).

    Here is the code:

    void PORT2_IRQHandler(void)
    {
        volatile uint32_t status;
    
        status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P2);
    
        /* Toggling the output on the LED */
        if(status & GPIO_PIN7)
        {
            MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
        }
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, status);
    
    }

    The code works fine when I'm using the ISR code from the previous example. It seems that "status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P2);" doesn't work. Or I may be overlooking something. 

    I couldn't figure out how to attach a file, so here's the full code:

    /* DriverLib Includes */
    #include "driverlib.h"
    
    /* Standard Includes */
    #include <stdint.h>
    
    #include <stdbool.h>
    
    int main(void)
    {
        volatile uint32_t ii;
    
        /* Halting the Watchdog */
        MAP_WDT_A_holdTimer();
    
        /* Configuring P1.0 as output and P1.1 (switch) as input */
        MAP_GPIO_setAsOutputPin(GPIO_PORT_P1, GPIO_PIN0);
       // MAP_GPIO_setAsOutputPin(GPIO_PORT_P2, GPIO_PIN7);
    
    
        /* Configuring P1.1 as an input and enabling interrupts */
        MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_setAsInputPinWithPullUpResistor(GPIO_PORT_P2, GPIO_PIN7);
    
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, GPIO_PIN7);
    
        MAP_GPIO_enableInterrupt(GPIO_PORT_P1, GPIO_PIN1);
        MAP_GPIO_enableInterrupt(GPIO_PORT_P2, GPIO_PIN7);
    
        MAP_Interrupt_enableInterrupt(INT_PORT1);
        MAP_Interrupt_enableInterrupt(INT_PORT2);
    
    
        /* Enabling SRAM Bank Retention */
        MAP_SysCtl_enableSRAMBankRetention(SYSCTL_SRAM_BANK1);
        
        /* Enabling MASTER interrupts */
        MAP_Interrupt_enableMaster();   
    
        /* Going to LPM3 */
        while (1)
        {
            MAP_PCM_gotoLPM3();
        }
    }
    
    /* GPIO ISR */
    void PORT1_IRQHandler(void)
    {
        uint32_t status;
    
        status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P1);
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P1, status);
    
        /* Toggling the output on the LED */
        if(status & GPIO_PIN1)
        {
            MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
        }
    
    }
    
    void PORT2_IRQHandler(void)
    {
        volatile uint32_t status;
    
        status = MAP_GPIO_getEnabledInterruptStatus(GPIO_PORT_P2);
    
        /* Toggling the output on the LED */
        if(status & GPIO_PIN7)
        {
            MAP_GPIO_toggleOutputOnPin(GPIO_PORT_P1, GPIO_PIN0);
        }
        MAP_GPIO_clearInterruptFlag(GPIO_PORT_P2, status);
    
    }
    

  • Hello,


    I have the same problem. The status from

    "status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P2);"

    is always 0. I have 2 interrupts correctly managed in _ccs.c.

    Another information is that when I use the code in CCs with the previous version of driverlib (before CMSIS update), it works. But when I use it with the update version (in another PC, providing the code conversion for MSP432 code) it doesn't work, even if the code does not have any compiling error. The problem is that status = GPIO_getEnabledInterruptStatus(GPIO_PORT_P2) is always 0.




    Many thanks
  • I have the same problem with the follwoing thread: e2e.ti.com/.../532315

**Attention** This is a public forum