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.

Interrupt Priority Mask

I have clarification question on the interrupt priority mask (IPM) and its interaction with Software Generated Interrupts (SGI). 

We're using the IPM to mask off interrupts via IntPriorityMaskGet and IntPriorityMaskSet.  The expectation we have is that setting the interrupt priority mask to 32 it will block interrupts of priority 32 and above.

We then within some of these area where the IPM has been set do an SGI via a call to IntTrigger expecting that since the priority of the called for interrupt is masked (it has a higher priority number) then the interrupt will be help off until the priority mask in increased above the priority of the interrupt generated.

That's the behaviour I expect, The datasheet I have does not explicitly state that this is the behaviour (or that it is not).  The documentation on IntTrigger states that the behaviour is the same as of the HW interrupt had been set but the subsequent wording is rather less emphatic. And since the HW documentation is silent on the issue I do need further clarification.

Robert

  • Hello Robert,

    Has the priority been set on the interrupts that need to be masked using IntPrioritySet?

    Regards
    Amit
  • Yes, Amit

    Robert
  • I will, of course, verify

    Robert
  • Verified that we do set interrupt priorities.

    Amit, given your question, can I take it that using PriorityMask is supposed to block interrupts of lower priority even when triggered via IntTrigger?

    Robert
  • Hello Robert,

    I would need to study the NVIC block (as documentation is not clear) to be able to answer the question.
    But from a programming model it would make sense "not" to block the SW Interrupt. The reason why I think so is because the HW interrupt is not under control of the SW and is triggered by the interaction of a module with the external source. On the other hand a SW interrupt is under SW control and can be deferred in SW when performing a critical operation either through a semaphore like _lock_.
    The same argument may apply the other way be stating that this would incur additional program flow change.

    Regards
    Amit
  • Amit Ashara said:
    I would need to study the NVIC block (as documentation is not clear) to be able to answer the question.

    Please do, it's turning into an important item for us.

    Amit Ashara said:
    But from a programming model it would make sense "not" to block the SW Interrupt.

    I know of at least two use cases where the reverse is true.  I've got to head out but Ill elucidate further when I get back.

    In the meantime could you also check if setting int_pending will have the same problem (assume IntTrigger does).  I'd like to have a backup to get this to work if possible.

    Robert

  • Hello Robert,

    Good news. So the "reverse" theory was correct. I got a test which now sets the priority of different interrupts and uses the mask to mask lower priority interrupts while keeping higher priority interrupts still unmasked. By keeping 4 break points at the Interrupt Handlers, and changing the priority I can get only the one's unmasked to break.

    Attached the code for your reference.

    //*****************************************************************************
    //
    // ektm4c129_i2c_master.c - I2C Master with High Speed Data Transfer
    //
    // Copyright (c) 2013-2015 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 2.1.1.71 of the EK-TM4C1294XL Firmware Package.
    //
    //*****************************************************************************
    #include <stdint.h>
    #include <stdbool.h>
    #include "inc/hw_gpio.h"
    #include "inc/hw_i2c.h"
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "inc/hw_nvic.h"
    #include "inc/hw_sysctl.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/i2c.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    
    //*****************************************************************************
    //
    //! \addtogroup example_list
    //! <h1>ektm4c129_i2c_master (ektm4c129_i2c_master)</h1>
    //!
    //! A Simple I2C Master Code for Performing Data Transfer with a high speed
    //! capable Slave using Interrupts
    //
    //*****************************************************************************
    
    //*****************************************************************************
    //
    // Interrupt Handler for I2C Master Interface
    //
    //*****************************************************************************
    void
    GPIOPortAIntHandler(void)
    {
    	IntPendClear(INT_GPIOA);
    	GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_0, GPIO_PIN_0);
    
    }
    
    void
    GPIOPortBIntHandler(void)
    {
    	IntPendClear(INT_GPIOB);
    	GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, GPIO_PIN_0);
    
    }
    
    void
    GPIOPortCIntHandler(void)
    {
    	IntPendClear(INT_GPIOC);
    	GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_0, GPIO_PIN_0);
    
    }
    
    void
    GPIOPortDIntHandler(void)
    {
    	IntPendClear(INT_GPIOD);
    	GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, GPIO_PIN_0);
    
    }
    //*****************************************************************************
    //
    // Main Program to Configure the I2C Master and or Slave
    //
    //*****************************************************************************
    int
    main(void)
    {
    	//
    	// Enable GPIO for Configuring the I2C Interface Pins
    	//
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
    
    	//
    	// Configure Pins for I2C Interface
    	//
    	GPIOPinTypeGPIOOutput(GPIO_PORTA_BASE, GPIO_PIN_0);
    	GPIOPinTypeGPIOOutput(GPIO_PORTB_BASE, GPIO_PIN_0);
    	GPIOPinTypeGPIOOutput(GPIO_PORTC_BASE, GPIO_PIN_0);
    	GPIOPinTypeGPIOOutput(GPIO_PORTD_BASE, GPIO_PIN_0);
    	GPIOPinWrite(GPIO_PORTA_BASE, GPIO_PIN_0, 0x0);
    	GPIOPinWrite(GPIO_PORTB_BASE, GPIO_PIN_0, 0x0);
    	GPIOPinWrite(GPIO_PORTC_BASE, GPIO_PIN_0, 0x0);
    	GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_0, 0x0);
    
    	IntEnable(INT_GPIOA);
    	IntEnable(INT_GPIOB);
    	IntEnable(INT_GPIOC);
    	IntEnable(INT_GPIOD);
    
    	//
    	// Setup Interrupt Priority
    	//
    	IntPrioritySet(INT_GPIOA,0xE0);
    	IntPrioritySet(INT_GPIOB,0x80);
    	IntPrioritySet(INT_GPIOC,0x20);
    	IntPrioritySet(INT_GPIOD,0x00);
    
    	IntPriorityMaskSet(0xE0);
    
    	IntMasterEnable();
    
    	SysCtlDelay(100);
    	IntTrigger(INT_GPIOA);
    	SysCtlDelay(100);
    	IntTrigger(INT_GPIOB);
    	SysCtlDelay(100);
    	IntTrigger(INT_GPIOC);
    	SysCtlDelay(100);
    	IntTrigger(INT_GPIOD);
    
    	while(1);
    }
    

    //*****************************************************************************
    //
    // startup_ccs.c - Startup code for use with TI's Code Composer Studio.
    //
    // Copyright (c) 2013-2015 Texas Instruments Incorporated.  All rights reserved.
    // Software License Agreement
    // 
    // Texas Instruments (TI) is supplying this software for use solely and
    // exclusively on TI's microcontroller products. The software is owned by
    // TI and/or its suppliers, and is protected under applicable copyright
    // laws. You may not combine this software with "viral" open-source
    // software in order to form a larger program.
    // 
    // THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS.
    // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT
    // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY
    // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
    // DAMAGES, FOR ANY REASON WHATSOEVER.
    // 
    // This is part of revision 2.1.1.63 of the EK-TM4C1294XL Firmware Package.
    //
    //*****************************************************************************
    
    #include <stdint.h>
    #include "inc/hw_nvic.h"
    #include "inc/hw_types.h"
    
    //*****************************************************************************
    //
    // Forward declaration of the default fault handlers.
    //
    //*****************************************************************************
    void ResetISR(void);
    static void NmiSR(void);
    static void FaultISR(void);
    static void IntDefaultHandler(void);
    
    //*****************************************************************************
    //
    // External declaration for the reset handler that is to be called when the
    // processor is started
    //
    //*****************************************************************************
    extern void _c_int00(void);
    extern void GPIOPortAIntHandler(void);
    extern void GPIOPortBIntHandler(void);
    extern void GPIOPortCIntHandler(void);
    extern void GPIOPortDIntHandler(void);
    
    //*****************************************************************************
    //
    // Linker variable that marks the top of the stack.
    //
    //*****************************************************************************
    extern uint32_t __STACK_TOP;
    
    //*****************************************************************************
    //
    // The 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 DATA_SECTION(g_pfnVectors, ".intvecs")
    void (* const g_pfnVectors[])(void) =
    {
        (void (*)(void))((uint32_t)&__STACK_TOP),
                                                // The initial stack pointer
        ResetISR,                               // The reset handler
        NmiSR,                                  // The NMI handler
        FaultISR,                               // The hard fault handler
        IntDefaultHandler,                      // The MPU fault handler
        IntDefaultHandler,                      // The bus fault handler
        IntDefaultHandler,                      // The usage fault handler
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // SVCall handler
        IntDefaultHandler,                      // Debug monitor handler
        0,                                      // Reserved
        IntDefaultHandler,                      // The PendSV handler
        IntDefaultHandler,                      // The SysTick handler
        GPIOPortAIntHandler,                    // GPIO Port A
    	GPIOPortBIntHandler,                    // GPIO Port B
    	GPIOPortCIntHandler,                    // GPIO Port C
    	GPIOPortDIntHandler,                    // GPIO Port D
        IntDefaultHandler,                      // GPIO Port E
        IntDefaultHandler,                      // UART0 Rx and Tx
        IntDefaultHandler,                      // UART1 Rx and Tx
        IntDefaultHandler,                      // SSI0 Rx and Tx
    	IntDefaultHandler,                      // I2C0 Master and Slave
        IntDefaultHandler,                      // PWM Fault
        IntDefaultHandler,                      // PWM Generator 0
        IntDefaultHandler,                      // PWM Generator 1
        IntDefaultHandler,                      // PWM Generator 2
        IntDefaultHandler,                      // Quadrature Encoder 0
        IntDefaultHandler,                      // ADC Sequence 0
        IntDefaultHandler,                      // ADC Sequence 1
        IntDefaultHandler,                      // ADC Sequence 2
        IntDefaultHandler,                      // ADC Sequence 3
        IntDefaultHandler,                      // Watchdog timer
        IntDefaultHandler,                      // Timer 0 subtimer A
        IntDefaultHandler,                      // Timer 0 subtimer B
        IntDefaultHandler,                      // Timer 1 subtimer A
        IntDefaultHandler,                      // Timer 1 subtimer B
        IntDefaultHandler,                      // Timer 2 subtimer A
        IntDefaultHandler,                      // Timer 2 subtimer B
        IntDefaultHandler,                      // Analog Comparator 0
        IntDefaultHandler,                      // Analog Comparator 1
        IntDefaultHandler,                      // Analog Comparator 2
        IntDefaultHandler,                      // System Control (PLL, OSC, BO)
        IntDefaultHandler,                      // FLASH Control
        IntDefaultHandler,                      // GPIO Port F
        IntDefaultHandler,                      // GPIO Port G
        IntDefaultHandler,                      // GPIO Port H
        IntDefaultHandler,                      // UART2 Rx and Tx
        IntDefaultHandler,                      // SSI1 Rx and Tx
        IntDefaultHandler,                      // Timer 3 subtimer A
        IntDefaultHandler,                      // Timer 3 subtimer B
    	IntDefaultHandler,                      // I2C1 Master and Slave
        IntDefaultHandler,                      // CAN0
        IntDefaultHandler,                      // CAN1
        IntDefaultHandler,                      // Ethernet
        IntDefaultHandler,                      // Hibernate
        IntDefaultHandler,                      // USB0
        IntDefaultHandler,                      // PWM Generator 3
        IntDefaultHandler,                      // uDMA Software Transfer
        IntDefaultHandler,                      // uDMA Error
        IntDefaultHandler,                      // ADC1 Sequence 0
        IntDefaultHandler,                      // ADC1 Sequence 1
        IntDefaultHandler,                      // ADC1 Sequence 2
        IntDefaultHandler,                      // ADC1 Sequence 3
        IntDefaultHandler,                      // External Bus Interface 0
    	IntDefaultHandler,                      // GPIO Port J
        IntDefaultHandler,                      // GPIO Port K
        IntDefaultHandler,                      // GPIO Port L
        IntDefaultHandler,                      // SSI2 Rx and Tx
        IntDefaultHandler,                      // SSI3 Rx and Tx
        IntDefaultHandler,                      // UART3 Rx and Tx
        IntDefaultHandler,                      // UART4 Rx and Tx
        IntDefaultHandler,                      // UART5 Rx and Tx
        IntDefaultHandler,                      // UART6 Rx and Tx
        IntDefaultHandler,                      // UART7 Rx and Tx
        IntDefaultHandler,                      // I2C2 Master and Slave
        IntDefaultHandler,                      // I2C3 Master and Slave
        IntDefaultHandler,                      // Timer 4 subtimer A
        IntDefaultHandler,                      // Timer 4 subtimer B
        IntDefaultHandler,                      // Timer 5 subtimer A
        IntDefaultHandler,                      // Timer 5 subtimer B
        IntDefaultHandler,                      // FPU
        0,                                      // Reserved
        0,                                      // Reserved
        IntDefaultHandler,                      // I2C4 Master and Slave
        IntDefaultHandler,                      // I2C5 Master and Slave
        IntDefaultHandler,                      // GPIO Port M
        IntDefaultHandler,                      // GPIO Port N
        0,                                      // Reserved
        IntDefaultHandler,                      // Tamper
        IntDefaultHandler,                      // GPIO Port P (Summary or P0)
        IntDefaultHandler,                      // GPIO Port P1
        IntDefaultHandler,                      // GPIO Port P2
        IntDefaultHandler,                      // GPIO Port P3
        IntDefaultHandler,                      // GPIO Port P4
        IntDefaultHandler,                      // GPIO Port P5
        IntDefaultHandler,                      // GPIO Port P6
        IntDefaultHandler,                      // GPIO Port P7
        IntDefaultHandler,                      // GPIO Port Q (Summary or Q0)
        IntDefaultHandler,                      // GPIO Port Q1
        IntDefaultHandler,                      // GPIO Port Q2
        IntDefaultHandler,                      // GPIO Port Q3
        IntDefaultHandler,                      // GPIO Port Q4
        IntDefaultHandler,                      // GPIO Port Q5
        IntDefaultHandler,                      // GPIO Port Q6
        IntDefaultHandler,                      // GPIO Port Q7
        IntDefaultHandler,                      // GPIO Port R
        IntDefaultHandler,                      // GPIO Port S
        IntDefaultHandler,                      // SHA/MD5 0
        IntDefaultHandler,                      // AES 0
        IntDefaultHandler,                      // DES3DES 0
        IntDefaultHandler,                      // LCD Controller 0
        IntDefaultHandler,                      // Timer 6 subtimer A
        IntDefaultHandler,                      // Timer 6 subtimer B
        IntDefaultHandler,                      // Timer 7 subtimer A
        IntDefaultHandler,                      // Timer 7 subtimer B
        IntDefaultHandler,                      // I2C6 Master and Slave
        IntDefaultHandler,                      // I2C7 Master and Slave
        IntDefaultHandler,                      // HIM Scan Matrix Keyboard 0
        IntDefaultHandler,                      // One Wire 0
        IntDefaultHandler,                      // HIM PS/2 0
        IntDefaultHandler,                      // HIM LED Sequencer 0
        IntDefaultHandler,                      // HIM Consumer IR 0
        IntDefaultHandler,                      // I2C8 Master and Slave
        IntDefaultHandler,                      // I2C9 Master and Slave
        IntDefaultHandler                       // GPIO Port T
    };
    
    //*****************************************************************************
    //
    // 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)
    {
        //
        // Jump to the CCS C initialization routine.  This will enable the
        // floating-point unit as well, so that does not need to be done here.
        //
        __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
    NmiSR(void)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // 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)
    {
        //
        // Enter an infinite loop.
        //
        while(1)
        {
        }
    }
    
    //*****************************************************************************
    //
    // 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
    IntDefaultHandler(void)
    {
        //
        // Go into an infinite loop.
        //
        while(1)
        {
        }
    }
    

    Regards

    Amit

  • That is good news Amit, that's how I hoped/expected it should work.

    I promised I'd explain why it's useful to have that feature.  I've used it in two different cases.  The idea is similar in both.

    The first is where you have a high frequency interrupt. The process for dealing with interrupt is quite fast and easily dealt with (Acknowledge the interrupt, gather the data).  Dealing with the collected data takes too long for the interrupt, if done there you will lose interrupts (The average is low enough not to overload the CPU).  In addition you are either not using a full fledged RTOS or the overhead to making the interrupt RTOS compatible is to large.  The solution is to do the smallest amount of processing in the device interrupt.  This does something like put the data into a FIFO (one w/o RTOS hooks). The device interrupt triggers the lower priority interrupt as needed to do more processing and/or communicate with the RTOS. Since this triggered interrupt is lower priority it will be pre-empted by the device interrupt as needed.

    The second case uses the interrupts as part of a real time kernel.  The built in interrupt prioritization give the tasks a simple priority structure. You can build a simple single stack run-to-completion kernel quite easily this way.

    Robert

  • We're starting to get enough information to start talking about what we are seeing.  We are narrowing in on the conditions that cause what led us to ask the question.

    We dump out various values via the SWO and we observe the following

    • The interrupt priorities appear to be set correctly Read via IntPriorityGet
    • When we read the current priority within the interrupt via  IntPriorityMaskGet() and it is always zero

    Is there some situation where the micro will not set the priority mask on entry to the interrupt?  That seems odd, I'm kind of reaching at the moment.

    It's like the priority masking needs to be initialized but there is not indication anywhere that it needs to be. Just that it is not followed with a value of zero (which would make 0 and 0xFF identical).

    Robert

  • Hello Robert.

    As you see in the code, there is nothing extra that I had to do. Did it work on your end as it worked on my setup?

    Sounds like if PRIMASK has not been set. It is a CPU register accessible through MRS and MSR instructions. A small asm API may be needed to see if it indeed is the cause.

    Regards
    Amit
  • Yes, we figured that out last Friday.  We were testing as I wrote the last, after I reflected on what could possibly be different in your code from what we were doing.  It's an oversight that the documentation doesn't mention this1.

    Actually we have discovered two oversights in the documentation.

    First is the priority Mask (PRIMASK).  The documentation states that the current priority mask is ignored if it is 0 (fair enough, that would act as another interrupt disable method).  It also states that the priority in the interrupt will become the priority when the interrupt fires.  The logical inference tis that an occurrence of an interrupt will load the priority mask and thus interrupts of a lower priority will be blocked.  Nowhere that I have found so far is it mentioned that this is not the case.  That being the case the default behaviour without previously setting up PRIMASK appears to be one that would enforce interrupt priorities. IE the ONLY reason to set PRIMASK before enabling interrupts is to disable some subset of them. This, unfortunately turns out not to be that case. This is the ultimate cause of our problems.

    The second documentation oversight is that it appears that the low order bits in the priority mask are cleared (hard to tell whether it is on write or read). We found that if we read back from PRIMASK after setting it to 4 we read a value of 0. This means that any setting of PRIMASK below 32 will also not enable interrupt priorities.  I see nowhere in the documentation that this is even hinted at. The documentation states the lower bits are ignored, not cleared.

    Robert

    1 - Neither did your example code BTW, I just took it as a typical example shortcut rather than a needed initialization step.  Definitely NOT a criticism, it was good, clear code.

  • Hello Robert,

    1. I did try the code w/o setting PRIMASK and it worked as expected. Hence the code. But since you mentioned it that it is not working, then the only logical explanation was PRIMASK. Thus my code never had it. Now it could be that CCS is handling the same (though it should not be doing such an operation in c_init). I have not got to the point to debug the same.
    2. The PRIMASK is a single bit field. So writing a 4 will not be a valid as it is the bit-0 that is RW.

    I love the feedback (honest criticism is worth 1000 false praises)

    Regards
    Amit
  • Actually your code does have a PRIMASK set just after the interrupts are set up. That's what made me think I was on the right track to suggest testing with PRIMASK set before starting and indeed doing so meant that it read non-zero in the interrupt.

    This one line early in main

    IntPriorityMaskSet(0xFF);

    made all the difference.

    For 2, I gathered it was something like that but it's never mentioned in the documentation that the low order bits are discarded (it's the 3 high order bits that exist BTW).

    Robert
  • Hello Robert,

    I think may be I am confused.

    The PRIMASK is different from the NVIC_PRIORITY registers. The API IntPriorityMaskSet sets the BASEPR register. So there are 3 registers

    1. BASEPRI which is used to set the Priority Mask.
    2. NVIC_PRI register for individual interrupt
    3. PRIMASK which is used to enable the Priority Mask.

    Regards
    Amit
  • Amit Ashara said:
    1. BASEPRI which is used to set the Priority Mask.
    2. NVIC_PRI register for individual interrupt

    I've been using the API nomenclature so these are what I was referring to.

    Amit Ashara said:
    3. PRIMASK which is used to enable the Priority Mask.

    I had to go find this.  It wouldn't fit the symptoms though since if set it would disable all interrupts and the interrupts were happening (it's also cleared on reset so only if you set it somewhere would it have an effect). 

    That's the bit that IntMasterDisable/Enable use. I hadn't twigged to the name earlier.

    Robert

    If the API uses Priority Mask to not mean PRIMASK (AKA the Priority Mask Register) expect confusion as the result. Perhaps another point to touch on in the documentation since it's probably way too late to change the naming for clarity.

  • Hello Robert,

    PRIMASK is not supposed to touch the CPSIE instruction function. It must be over the CPSIE for priority. And that is how I read it. But you do make a point on what the end affect is w/o the use of PRIMASK.

    Regards
    Amit
  • Other way around I think Amit. At least as the library uses it. It only reads PRIMASK and uses cpsie and cpsid to manipulate the bit.

    In any case I wasn't expecting to find another register being referred to as Priority Mask other than the one referred to by the API via SetPriorityMask. I'm sure I skimmed over it when reading the documentation but hadn't clued into the fact that API and micro were using the same term to refer to distinct registers.

    Robert
  • Hello Robert,

    Yes it gets confusing. I was reading the NVIC section and then landed into INTCTRL register description where I spotted the register PRIMASK

    Regards
    Amit