xref: /btstack/port/msp432p401lp-cc256x/ti/devices/msp432p4xx/driverlib/interrupt.c (revision 5fd0122a3e19d95e11e1f3eb8a08a2b2acb2557e)
1*5fd0122aSMatthias Ringwald /* --COPYRIGHT--,BSD
2*5fd0122aSMatthias Ringwald  * Copyright (c) 2017, Texas Instruments Incorporated
3*5fd0122aSMatthias Ringwald  * All rights reserved.
4*5fd0122aSMatthias Ringwald  *
5*5fd0122aSMatthias Ringwald  * Redistribution and use in source and binary forms, with or without
6*5fd0122aSMatthias Ringwald  * modification, are permitted provided that the following conditions
7*5fd0122aSMatthias Ringwald  * are met:
8*5fd0122aSMatthias Ringwald  *
9*5fd0122aSMatthias Ringwald  * *  Redistributions of source code must retain the above copyright
10*5fd0122aSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer.
11*5fd0122aSMatthias Ringwald  *
12*5fd0122aSMatthias Ringwald  * *  Redistributions in binary form must reproduce the above copyright
13*5fd0122aSMatthias Ringwald  *    notice, this list of conditions and the following disclaimer in the
14*5fd0122aSMatthias Ringwald  *    documentation and/or other materials provided with the distribution.
15*5fd0122aSMatthias Ringwald  *
16*5fd0122aSMatthias Ringwald  * *  Neither the name of Texas Instruments Incorporated nor the names of
17*5fd0122aSMatthias Ringwald  *    its contributors may be used to endorse or promote products derived
18*5fd0122aSMatthias Ringwald  *    from this software without specific prior written permission.
19*5fd0122aSMatthias Ringwald  *
20*5fd0122aSMatthias Ringwald  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21*5fd0122aSMatthias Ringwald  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22*5fd0122aSMatthias Ringwald  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23*5fd0122aSMatthias Ringwald  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24*5fd0122aSMatthias Ringwald  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25*5fd0122aSMatthias Ringwald  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26*5fd0122aSMatthias Ringwald  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
27*5fd0122aSMatthias Ringwald  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
28*5fd0122aSMatthias Ringwald  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
29*5fd0122aSMatthias Ringwald  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
30*5fd0122aSMatthias Ringwald  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31*5fd0122aSMatthias Ringwald  * --/COPYRIGHT--*/
32*5fd0122aSMatthias Ringwald /* Standard Includes */
33*5fd0122aSMatthias Ringwald #include <stdint.h>
34*5fd0122aSMatthias Ringwald 
35*5fd0122aSMatthias Ringwald /* DriverLib Includes */
36*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/debug.h>
37*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/cpu.h>
38*5fd0122aSMatthias Ringwald #include <ti/devices/msp432p4xx/driverlib/interrupt.h>
39*5fd0122aSMatthias Ringwald 
40*5fd0122aSMatthias Ringwald 
41*5fd0122aSMatthias Ringwald //*****************************************************************************
42*5fd0122aSMatthias Ringwald //
43*5fd0122aSMatthias Ringwald // This is a mapping between priority grouping encodings and the number of
44*5fd0122aSMatthias Ringwald // preemption priority bits.
45*5fd0122aSMatthias Ringwald //
46*5fd0122aSMatthias Ringwald //*****************************************************************************
47*5fd0122aSMatthias Ringwald static const uint32_t g_pulPriority[] =
48*5fd0122aSMatthias Ringwald { NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
49*5fd0122aSMatthias Ringwald NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4,
50*5fd0122aSMatthias Ringwald NVIC_APINT_PRIGROUP_5_3, NVIC_APINT_PRIGROUP_6_2,
51*5fd0122aSMatthias Ringwald NVIC_APINT_PRIGROUP_7_1 };
52*5fd0122aSMatthias Ringwald 
53*5fd0122aSMatthias Ringwald //*****************************************************************************
54*5fd0122aSMatthias Ringwald //
55*5fd0122aSMatthias Ringwald // This is a mapping between interrupt number and the register that contains
56*5fd0122aSMatthias Ringwald // the priority encoding for that interrupt.
57*5fd0122aSMatthias Ringwald //
58*5fd0122aSMatthias Ringwald //*****************************************************************************
59*5fd0122aSMatthias Ringwald static const uint32_t g_pulRegs[] =
60*5fd0122aSMatthias Ringwald { 0, NVIC_SYS_PRI1_R, NVIC_SYS_PRI2_R, NVIC_SYS_PRI3_R, NVIC_PRI0_R,
61*5fd0122aSMatthias Ringwald NVIC_PRI1_R, NVIC_PRI2_R, NVIC_PRI3_R, NVIC_PRI4_R, NVIC_PRI5_R,
62*5fd0122aSMatthias Ringwald NVIC_PRI6_R, NVIC_PRI7_R, NVIC_PRI8_R, NVIC_PRI9_R, NVIC_PRI10_R,
63*5fd0122aSMatthias Ringwald NVIC_PRI11_R, NVIC_PRI12_R, NVIC_PRI13_R, NVIC_PRI14_R, NVIC_PRI15_R };
64*5fd0122aSMatthias Ringwald 
65*5fd0122aSMatthias Ringwald //*****************************************************************************
66*5fd0122aSMatthias Ringwald //
67*5fd0122aSMatthias Ringwald // This is a mapping between interrupt number (for the peripheral interrupts
68*5fd0122aSMatthias Ringwald // only) and the register that contains the interrupt enable for that
69*5fd0122aSMatthias Ringwald // interrupt.
70*5fd0122aSMatthias Ringwald //
71*5fd0122aSMatthias Ringwald //*****************************************************************************
72*5fd0122aSMatthias Ringwald static const uint32_t g_pulEnRegs[] =
73*5fd0122aSMatthias Ringwald { NVIC_EN0_R, NVIC_EN1_R };
74*5fd0122aSMatthias Ringwald 
75*5fd0122aSMatthias Ringwald //*****************************************************************************
76*5fd0122aSMatthias Ringwald //
77*5fd0122aSMatthias Ringwald // This is a mapping between interrupt number (for the peripheral interrupts
78*5fd0122aSMatthias Ringwald // only) and the register that contains the interrupt disable for that
79*5fd0122aSMatthias Ringwald // interrupt.
80*5fd0122aSMatthias Ringwald //
81*5fd0122aSMatthias Ringwald //*****************************************************************************
82*5fd0122aSMatthias Ringwald static const uint32_t g_pulDisRegs[] =
83*5fd0122aSMatthias Ringwald { NVIC_DIS0_R, NVIC_DIS1_R };
84*5fd0122aSMatthias Ringwald 
85*5fd0122aSMatthias Ringwald //*****************************************************************************
86*5fd0122aSMatthias Ringwald //
87*5fd0122aSMatthias Ringwald // This is a mapping between interrupt number (for the peripheral interrupts
88*5fd0122aSMatthias Ringwald // only) and the register that contains the interrupt pend for that interrupt.
89*5fd0122aSMatthias Ringwald //
90*5fd0122aSMatthias Ringwald //*****************************************************************************
91*5fd0122aSMatthias Ringwald static const uint32_t g_pulPendRegs[] =
92*5fd0122aSMatthias Ringwald { NVIC_PEND0_R, NVIC_PEND1_R };
93*5fd0122aSMatthias Ringwald 
94*5fd0122aSMatthias Ringwald //*****************************************************************************
95*5fd0122aSMatthias Ringwald //
96*5fd0122aSMatthias Ringwald // This is a mapping between interrupt number (for the peripheral interrupts
97*5fd0122aSMatthias Ringwald // only) and the register that contains the interrupt unpend for that
98*5fd0122aSMatthias Ringwald // interrupt.
99*5fd0122aSMatthias Ringwald //
100*5fd0122aSMatthias Ringwald //*****************************************************************************
101*5fd0122aSMatthias Ringwald static const uint32_t g_pulUnpendRegs[] =
102*5fd0122aSMatthias Ringwald { NVIC_UNPEND0_R, NVIC_UNPEND1_R };
103*5fd0122aSMatthias Ringwald 
104*5fd0122aSMatthias Ringwald //*****************************************************************************
105*5fd0122aSMatthias Ringwald //
106*5fd0122aSMatthias Ringwald //! \internal
107*5fd0122aSMatthias Ringwald //! The default interrupt handler.
108*5fd0122aSMatthias Ringwald //!
109*5fd0122aSMatthias Ringwald //! This is the default interrupt handler for all interrupts.  It simply loops
110*5fd0122aSMatthias Ringwald //! forever so that the system state is preserved for observation by a
111*5fd0122aSMatthias Ringwald //! debugger.  Since interrupts should be disabled before unregistering the
112*5fd0122aSMatthias Ringwald //! corresponding handler, this should never be called.
113*5fd0122aSMatthias Ringwald //!
114*5fd0122aSMatthias Ringwald //! \return None.
115*5fd0122aSMatthias Ringwald //
116*5fd0122aSMatthias Ringwald //*****************************************************************************
IntDefaultHandler(void)117*5fd0122aSMatthias Ringwald static void IntDefaultHandler(void)
118*5fd0122aSMatthias Ringwald {
119*5fd0122aSMatthias Ringwald     //
120*5fd0122aSMatthias Ringwald     // Go into an infinite loop.
121*5fd0122aSMatthias Ringwald     //
122*5fd0122aSMatthias Ringwald     while (1)
123*5fd0122aSMatthias Ringwald     {
124*5fd0122aSMatthias Ringwald     }
125*5fd0122aSMatthias Ringwald }
126*5fd0122aSMatthias Ringwald 
127*5fd0122aSMatthias Ringwald //*****************************************************************************
128*5fd0122aSMatthias Ringwald //
129*5fd0122aSMatthias Ringwald // The processor vector table.
130*5fd0122aSMatthias Ringwald //
131*5fd0122aSMatthias Ringwald // This contains a list of the handlers for the various interrupt sources in
132*5fd0122aSMatthias Ringwald // the system.  The layout of this list is defined by the hardware; assertion
133*5fd0122aSMatthias Ringwald // of an interrupt causes the processor to start executing directly at the
134*5fd0122aSMatthias Ringwald // address given in the corresponding location in this list.
135*5fd0122aSMatthias Ringwald //
136*5fd0122aSMatthias Ringwald //*****************************************************************************
137*5fd0122aSMatthias Ringwald #if defined(__IAR_SYSTEMS_ICC__)
138*5fd0122aSMatthias Ringwald #pragma data_alignment=1024
139*5fd0122aSMatthias Ringwald static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS+1])(void) @ "VTABLE";
140*5fd0122aSMatthias Ringwald #elif defined(__TI_COMPILER_VERSION__)
141*5fd0122aSMatthias Ringwald #pragma DATA_ALIGN(g_pfnRAMVectors, 1024)
142*5fd0122aSMatthias Ringwald #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable")
143*5fd0122aSMatthias Ringwald void (*g_pfnRAMVectors[NUM_INTERRUPTS + 1])(void);
144*5fd0122aSMatthias Ringwald #else
145*5fd0122aSMatthias Ringwald static __attribute__((section("vtable")))
146*5fd0122aSMatthias Ringwald void (*g_pfnRAMVectors[NUM_INTERRUPTS+1])(void) __attribute__((aligned(1024)));
147*5fd0122aSMatthias Ringwald #endif
148*5fd0122aSMatthias Ringwald 
Interrupt_enableMaster(void)149*5fd0122aSMatthias Ringwald bool Interrupt_enableMaster(void)
150*5fd0122aSMatthias Ringwald {
151*5fd0122aSMatthias Ringwald     //
152*5fd0122aSMatthias Ringwald     // Enable processor interrupts.
153*5fd0122aSMatthias Ringwald     //
154*5fd0122aSMatthias Ringwald     return (CPU_cpsie());
155*5fd0122aSMatthias Ringwald }
156*5fd0122aSMatthias Ringwald 
Interrupt_disableMaster(void)157*5fd0122aSMatthias Ringwald bool Interrupt_disableMaster(void)
158*5fd0122aSMatthias Ringwald {
159*5fd0122aSMatthias Ringwald     //
160*5fd0122aSMatthias Ringwald     // Disable processor interrupts.
161*5fd0122aSMatthias Ringwald     //
162*5fd0122aSMatthias Ringwald     return (CPU_cpsid());
163*5fd0122aSMatthias Ringwald }
164*5fd0122aSMatthias Ringwald 
Interrupt_registerInterrupt(uint32_t interruptNumber,void (* intHandler)(void))165*5fd0122aSMatthias Ringwald void Interrupt_registerInterrupt(uint32_t interruptNumber,
166*5fd0122aSMatthias Ringwald         void (*intHandler)(void))
167*5fd0122aSMatthias Ringwald {
168*5fd0122aSMatthias Ringwald     uint32_t ulIdx, ulValue;
169*5fd0122aSMatthias Ringwald 
170*5fd0122aSMatthias Ringwald     //
171*5fd0122aSMatthias Ringwald     // Check the arguments.
172*5fd0122aSMatthias Ringwald     //
173*5fd0122aSMatthias Ringwald     ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
174*5fd0122aSMatthias Ringwald 
175*5fd0122aSMatthias Ringwald     //
176*5fd0122aSMatthias Ringwald     // Make sure that the RAM vector table is correctly aligned.
177*5fd0122aSMatthias Ringwald     //
178*5fd0122aSMatthias Ringwald     ASSERT(((uint32_t) g_pfnRAMVectors & 0x000000ff) == 0);
179*5fd0122aSMatthias Ringwald 
180*5fd0122aSMatthias Ringwald     //
181*5fd0122aSMatthias Ringwald     // See if the RAM vector table has been initialized.
182*5fd0122aSMatthias Ringwald     //
183*5fd0122aSMatthias Ringwald     if (SCB->VTOR != (uint32_t) g_pfnRAMVectors)
184*5fd0122aSMatthias Ringwald     {
185*5fd0122aSMatthias Ringwald         //
186*5fd0122aSMatthias Ringwald         // Copy the vector table from the beginning of FLASH to the RAM vector
187*5fd0122aSMatthias Ringwald         // table.
188*5fd0122aSMatthias Ringwald         //
189*5fd0122aSMatthias Ringwald         ulValue = SCB->VTOR;
190*5fd0122aSMatthias Ringwald         for (ulIdx = 0; ulIdx < (NUM_INTERRUPTS + 1); ulIdx++)
191*5fd0122aSMatthias Ringwald         {
192*5fd0122aSMatthias Ringwald             g_pfnRAMVectors[ulIdx] = (void (*)(void)) HWREG32(
193*5fd0122aSMatthias Ringwald                     (ulIdx * 4) + ulValue);
194*5fd0122aSMatthias Ringwald         }
195*5fd0122aSMatthias Ringwald 
196*5fd0122aSMatthias Ringwald         //
197*5fd0122aSMatthias Ringwald         // Point the NVIC at the RAM vector table.
198*5fd0122aSMatthias Ringwald         //
199*5fd0122aSMatthias Ringwald         SCB->VTOR = (uint32_t) g_pfnRAMVectors;
200*5fd0122aSMatthias Ringwald     }
201*5fd0122aSMatthias Ringwald 
202*5fd0122aSMatthias Ringwald     //
203*5fd0122aSMatthias Ringwald     // Save the interrupt handler.
204*5fd0122aSMatthias Ringwald     //
205*5fd0122aSMatthias Ringwald     g_pfnRAMVectors[interruptNumber] = intHandler;
206*5fd0122aSMatthias Ringwald }
207*5fd0122aSMatthias Ringwald 
Interrupt_unregisterInterrupt(uint32_t interruptNumber)208*5fd0122aSMatthias Ringwald void Interrupt_unregisterInterrupt(uint32_t interruptNumber)
209*5fd0122aSMatthias Ringwald {
210*5fd0122aSMatthias Ringwald     //
211*5fd0122aSMatthias Ringwald     // Check the arguments.
212*5fd0122aSMatthias Ringwald     //
213*5fd0122aSMatthias Ringwald     ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
214*5fd0122aSMatthias Ringwald 
215*5fd0122aSMatthias Ringwald     //
216*5fd0122aSMatthias Ringwald     // Reset the interrupt handler.
217*5fd0122aSMatthias Ringwald     //
218*5fd0122aSMatthias Ringwald     g_pfnRAMVectors[interruptNumber] = IntDefaultHandler;
219*5fd0122aSMatthias Ringwald }
220*5fd0122aSMatthias Ringwald 
Interrupt_setPriorityGrouping(uint32_t bits)221*5fd0122aSMatthias Ringwald void Interrupt_setPriorityGrouping(uint32_t bits)
222*5fd0122aSMatthias Ringwald {
223*5fd0122aSMatthias Ringwald     //
224*5fd0122aSMatthias Ringwald     // Check the arguments.
225*5fd0122aSMatthias Ringwald     //
226*5fd0122aSMatthias Ringwald     ASSERT(bits < NUM_PRIORITY);
227*5fd0122aSMatthias Ringwald 
228*5fd0122aSMatthias Ringwald     //
229*5fd0122aSMatthias Ringwald     // Set the priority grouping.
230*5fd0122aSMatthias Ringwald     //
231*5fd0122aSMatthias Ringwald     uint32_t reg_value;
232*5fd0122aSMatthias Ringwald     uint32_t PriorityGroupTmp = g_pulPriority[bits];
233*5fd0122aSMatthias Ringwald     reg_value  =  SCB->AIRCR;                                                   /* read old register configuration     */
234*5fd0122aSMatthias Ringwald     reg_value &= ~((uint32_t)(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk)); /* clear bits to change                */
235*5fd0122aSMatthias Ringwald     reg_value  =  (reg_value                                   |
236*5fd0122aSMatthias Ringwald                   ((uint32_t)0x5FAUL << SCB_AIRCR_VECTKEY_Pos) |
237*5fd0122aSMatthias Ringwald                   (PriorityGroupTmp << 8U)                      );              /* Insert write key and priority group */
238*5fd0122aSMatthias Ringwald     SCB->AIRCR =  reg_value;
239*5fd0122aSMatthias Ringwald }
240*5fd0122aSMatthias Ringwald 
Interrupt_getPriorityGrouping(void)241*5fd0122aSMatthias Ringwald uint32_t Interrupt_getPriorityGrouping(void)
242*5fd0122aSMatthias Ringwald {
243*5fd0122aSMatthias Ringwald     uint32_t ulLoop, ulValue;
244*5fd0122aSMatthias Ringwald 
245*5fd0122aSMatthias Ringwald     //
246*5fd0122aSMatthias Ringwald     // Read the priority grouping.
247*5fd0122aSMatthias Ringwald     //
248*5fd0122aSMatthias Ringwald     ulValue = SCB->AIRCR & NVIC_APINT_PRIGROUP_M;
249*5fd0122aSMatthias Ringwald 
250*5fd0122aSMatthias Ringwald     //
251*5fd0122aSMatthias Ringwald     // Loop through the priority grouping values.
252*5fd0122aSMatthias Ringwald     //
253*5fd0122aSMatthias Ringwald     for (ulLoop = 0; ulLoop < NUM_PRIORITY; ulLoop++)
254*5fd0122aSMatthias Ringwald     {
255*5fd0122aSMatthias Ringwald         //
256*5fd0122aSMatthias Ringwald         // Stop looping if this value matches.
257*5fd0122aSMatthias Ringwald         //
258*5fd0122aSMatthias Ringwald         if (ulValue == g_pulPriority[ulLoop])
259*5fd0122aSMatthias Ringwald         {
260*5fd0122aSMatthias Ringwald             break;
261*5fd0122aSMatthias Ringwald         }
262*5fd0122aSMatthias Ringwald     }
263*5fd0122aSMatthias Ringwald 
264*5fd0122aSMatthias Ringwald     //
265*5fd0122aSMatthias Ringwald     // Return the number of priority bits.
266*5fd0122aSMatthias Ringwald     //
267*5fd0122aSMatthias Ringwald     return (ulLoop);
268*5fd0122aSMatthias Ringwald }
269*5fd0122aSMatthias Ringwald 
Interrupt_setPriority(uint32_t interruptNumber,uint8_t priority)270*5fd0122aSMatthias Ringwald void Interrupt_setPriority(uint32_t interruptNumber, uint8_t priority)
271*5fd0122aSMatthias Ringwald {
272*5fd0122aSMatthias Ringwald     uint32_t ulTemp;
273*5fd0122aSMatthias Ringwald 
274*5fd0122aSMatthias Ringwald     //
275*5fd0122aSMatthias Ringwald     // Check the arguments.
276*5fd0122aSMatthias Ringwald     //
277*5fd0122aSMatthias Ringwald     ASSERT((interruptNumber >= 4) && (interruptNumber < (NUM_INTERRUPTS+1)));
278*5fd0122aSMatthias Ringwald 
279*5fd0122aSMatthias Ringwald     //
280*5fd0122aSMatthias Ringwald     // Set the interrupt priority.
281*5fd0122aSMatthias Ringwald     //
282*5fd0122aSMatthias Ringwald     ulTemp = HWREG32(g_pulRegs[interruptNumber >> 2]);
283*5fd0122aSMatthias Ringwald     ulTemp &= ~(0xFF << (8 * (interruptNumber & 3)));
284*5fd0122aSMatthias Ringwald     ulTemp |= priority << (8 * (interruptNumber & 3));
285*5fd0122aSMatthias Ringwald     HWREG32 (g_pulRegs[interruptNumber >> 2]) = ulTemp;
286*5fd0122aSMatthias Ringwald }
287*5fd0122aSMatthias Ringwald 
Interrupt_getPriority(uint32_t interruptNumber)288*5fd0122aSMatthias Ringwald uint8_t Interrupt_getPriority(uint32_t interruptNumber)
289*5fd0122aSMatthias Ringwald {
290*5fd0122aSMatthias Ringwald     //
291*5fd0122aSMatthias Ringwald     // Check the arguments.
292*5fd0122aSMatthias Ringwald     //
293*5fd0122aSMatthias Ringwald     ASSERT((interruptNumber >= 4) && (interruptNumber < (NUM_INTERRUPTS+1)));
294*5fd0122aSMatthias Ringwald 
295*5fd0122aSMatthias Ringwald     //
296*5fd0122aSMatthias Ringwald     // Return the interrupt priority.
297*5fd0122aSMatthias Ringwald     //
298*5fd0122aSMatthias Ringwald     return ((HWREG32(g_pulRegs[interruptNumber >> 2])
299*5fd0122aSMatthias Ringwald             >> (8 * (interruptNumber & 3))) & 0xFF);
300*5fd0122aSMatthias Ringwald }
301*5fd0122aSMatthias Ringwald 
Interrupt_enableInterrupt(uint32_t interruptNumber)302*5fd0122aSMatthias Ringwald void Interrupt_enableInterrupt(uint32_t interruptNumber)
303*5fd0122aSMatthias Ringwald {
304*5fd0122aSMatthias Ringwald     //
305*5fd0122aSMatthias Ringwald     // Check the arguments.
306*5fd0122aSMatthias Ringwald     //
307*5fd0122aSMatthias Ringwald     ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
308*5fd0122aSMatthias Ringwald 
309*5fd0122aSMatthias Ringwald     //
310*5fd0122aSMatthias Ringwald     // Determine the interrupt to enable.
311*5fd0122aSMatthias Ringwald     //
312*5fd0122aSMatthias Ringwald     if (interruptNumber == FAULT_MPU)
313*5fd0122aSMatthias Ringwald     {
314*5fd0122aSMatthias Ringwald         //
315*5fd0122aSMatthias Ringwald         // Enable the MemManage interrupt.
316*5fd0122aSMatthias Ringwald         //
317*5fd0122aSMatthias Ringwald         SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
318*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_BUS)
319*5fd0122aSMatthias Ringwald     {
320*5fd0122aSMatthias Ringwald         //
321*5fd0122aSMatthias Ringwald         // Enable the bus fault interrupt.
322*5fd0122aSMatthias Ringwald         //
323*5fd0122aSMatthias Ringwald         SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk;
324*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_USAGE)
325*5fd0122aSMatthias Ringwald     {
326*5fd0122aSMatthias Ringwald         //
327*5fd0122aSMatthias Ringwald         // Enable the usage fault interrupt.
328*5fd0122aSMatthias Ringwald         //
329*5fd0122aSMatthias Ringwald         SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
330*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_SYSTICK)
331*5fd0122aSMatthias Ringwald     {
332*5fd0122aSMatthias Ringwald         //
333*5fd0122aSMatthias Ringwald         // Enable the System Tick interrupt.
334*5fd0122aSMatthias Ringwald         //
335*5fd0122aSMatthias Ringwald         SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
336*5fd0122aSMatthias Ringwald     } else if (interruptNumber >= 16)
337*5fd0122aSMatthias Ringwald     {
338*5fd0122aSMatthias Ringwald         //
339*5fd0122aSMatthias Ringwald         // Enable the general interrupt.
340*5fd0122aSMatthias Ringwald         //
341*5fd0122aSMatthias Ringwald         HWREG32 (g_pulEnRegs[(interruptNumber - 16) / 32]) = 1
342*5fd0122aSMatthias Ringwald                 << ((interruptNumber - 16) & 31);
343*5fd0122aSMatthias Ringwald     }
344*5fd0122aSMatthias Ringwald }
345*5fd0122aSMatthias Ringwald 
Interrupt_disableInterrupt(uint32_t interruptNumber)346*5fd0122aSMatthias Ringwald void Interrupt_disableInterrupt(uint32_t interruptNumber)
347*5fd0122aSMatthias Ringwald {
348*5fd0122aSMatthias Ringwald     //
349*5fd0122aSMatthias Ringwald     // Check the arguments.
350*5fd0122aSMatthias Ringwald     //
351*5fd0122aSMatthias Ringwald     ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
352*5fd0122aSMatthias Ringwald 
353*5fd0122aSMatthias Ringwald     //
354*5fd0122aSMatthias Ringwald     // Determine the interrupt to disable.
355*5fd0122aSMatthias Ringwald     //
356*5fd0122aSMatthias Ringwald     if (interruptNumber == FAULT_MPU)
357*5fd0122aSMatthias Ringwald     {
358*5fd0122aSMatthias Ringwald         //
359*5fd0122aSMatthias Ringwald         // Disable the MemManage interrupt.
360*5fd0122aSMatthias Ringwald         //
361*5fd0122aSMatthias Ringwald         SCB->SHCSR &= ~(SCB_SHCSR_MEMFAULTENA_Msk);
362*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_BUS)
363*5fd0122aSMatthias Ringwald     {
364*5fd0122aSMatthias Ringwald         //
365*5fd0122aSMatthias Ringwald         // Disable the bus fault interrupt.
366*5fd0122aSMatthias Ringwald         //
367*5fd0122aSMatthias Ringwald         SCB->SHCSR &= ~(SCB_SHCSR_BUSFAULTENA_Msk);
368*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_USAGE)
369*5fd0122aSMatthias Ringwald     {
370*5fd0122aSMatthias Ringwald         //
371*5fd0122aSMatthias Ringwald         // Disable the usage fault interrupt.
372*5fd0122aSMatthias Ringwald         //
373*5fd0122aSMatthias Ringwald         SCB->SHCSR &= ~(SCB_SHCSR_USGFAULTENA_Msk);
374*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_SYSTICK)
375*5fd0122aSMatthias Ringwald     {
376*5fd0122aSMatthias Ringwald         //
377*5fd0122aSMatthias Ringwald         // Disable the System Tick interrupt.
378*5fd0122aSMatthias Ringwald         //
379*5fd0122aSMatthias Ringwald         SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);
380*5fd0122aSMatthias Ringwald     } else if (interruptNumber >= 16)
381*5fd0122aSMatthias Ringwald     {
382*5fd0122aSMatthias Ringwald         //
383*5fd0122aSMatthias Ringwald         // Disable the general interrupt.
384*5fd0122aSMatthias Ringwald         //
385*5fd0122aSMatthias Ringwald         HWREG32 (g_pulDisRegs[(interruptNumber - 16) / 32]) = 1
386*5fd0122aSMatthias Ringwald                 << ((interruptNumber - 16) & 31);
387*5fd0122aSMatthias Ringwald     }
388*5fd0122aSMatthias Ringwald }
389*5fd0122aSMatthias Ringwald 
Interrupt_isEnabled(uint32_t interruptNumber)390*5fd0122aSMatthias Ringwald bool Interrupt_isEnabled(uint32_t interruptNumber)
391*5fd0122aSMatthias Ringwald {
392*5fd0122aSMatthias Ringwald     uint32_t ulRet;
393*5fd0122aSMatthias Ringwald 
394*5fd0122aSMatthias Ringwald     //
395*5fd0122aSMatthias Ringwald     // Check the arguments.
396*5fd0122aSMatthias Ringwald     //
397*5fd0122aSMatthias Ringwald     ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
398*5fd0122aSMatthias Ringwald 
399*5fd0122aSMatthias Ringwald     //
400*5fd0122aSMatthias Ringwald     // Initialize the return value.
401*5fd0122aSMatthias Ringwald     //
402*5fd0122aSMatthias Ringwald     ulRet = 0;
403*5fd0122aSMatthias Ringwald 
404*5fd0122aSMatthias Ringwald     //
405*5fd0122aSMatthias Ringwald     // Determine the interrupt to disable.
406*5fd0122aSMatthias Ringwald     //
407*5fd0122aSMatthias Ringwald     if (interruptNumber == FAULT_MPU)
408*5fd0122aSMatthias Ringwald     {
409*5fd0122aSMatthias Ringwald         //
410*5fd0122aSMatthias Ringwald         // Check the MemManage interrupt.
411*5fd0122aSMatthias Ringwald         //
412*5fd0122aSMatthias Ringwald         ulRet = SCB->SHCSR & SCB_SHCSR_MEMFAULTENA_Msk;
413*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_BUS)
414*5fd0122aSMatthias Ringwald     {
415*5fd0122aSMatthias Ringwald         //
416*5fd0122aSMatthias Ringwald         // Check the bus fault interrupt.
417*5fd0122aSMatthias Ringwald         //
418*5fd0122aSMatthias Ringwald         ulRet = SCB->SHCSR & SCB_SHCSR_BUSFAULTENA_Msk;
419*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_USAGE)
420*5fd0122aSMatthias Ringwald     {
421*5fd0122aSMatthias Ringwald         //
422*5fd0122aSMatthias Ringwald         // Check the usage fault interrupt.
423*5fd0122aSMatthias Ringwald         //
424*5fd0122aSMatthias Ringwald         ulRet = SCB->SHCSR & SCB_SHCSR_USGFAULTENA_Msk;
425*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_SYSTICK)
426*5fd0122aSMatthias Ringwald     {
427*5fd0122aSMatthias Ringwald         //
428*5fd0122aSMatthias Ringwald         // Check the System Tick interrupt.
429*5fd0122aSMatthias Ringwald         //
430*5fd0122aSMatthias Ringwald         ulRet = SysTick->CTRL & SysTick_CTRL_ENABLE_Msk;
431*5fd0122aSMatthias Ringwald     } else if (interruptNumber >= 16)
432*5fd0122aSMatthias Ringwald     {
433*5fd0122aSMatthias Ringwald         //
434*5fd0122aSMatthias Ringwald         // Check the general interrupt.
435*5fd0122aSMatthias Ringwald         //
436*5fd0122aSMatthias Ringwald         ulRet = HWREG32(g_pulEnRegs[(interruptNumber - 16) / 32])
437*5fd0122aSMatthias Ringwald                 & (1 << ((interruptNumber - 16) & 31));
438*5fd0122aSMatthias Ringwald     }
439*5fd0122aSMatthias Ringwald     return (ulRet);
440*5fd0122aSMatthias Ringwald }
441*5fd0122aSMatthias Ringwald 
Interrupt_pendInterrupt(uint32_t interruptNumber)442*5fd0122aSMatthias Ringwald void Interrupt_pendInterrupt(uint32_t interruptNumber)
443*5fd0122aSMatthias Ringwald {
444*5fd0122aSMatthias Ringwald     //
445*5fd0122aSMatthias Ringwald     // Check the arguments.
446*5fd0122aSMatthias Ringwald     //
447*5fd0122aSMatthias Ringwald     ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
448*5fd0122aSMatthias Ringwald 
449*5fd0122aSMatthias Ringwald     //
450*5fd0122aSMatthias Ringwald     // Determine the interrupt to pend.
451*5fd0122aSMatthias Ringwald     //
452*5fd0122aSMatthias Ringwald     if (interruptNumber == FAULT_NMI)
453*5fd0122aSMatthias Ringwald     {
454*5fd0122aSMatthias Ringwald         //
455*5fd0122aSMatthias Ringwald         // Pend the NMI interrupt.
456*5fd0122aSMatthias Ringwald         //
457*5fd0122aSMatthias Ringwald         SCB->ICSR |= SCB_ICSR_NMIPENDSET_Msk;
458*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_PENDSV)
459*5fd0122aSMatthias Ringwald     {
460*5fd0122aSMatthias Ringwald         //
461*5fd0122aSMatthias Ringwald         // Pend the PendSV interrupt.
462*5fd0122aSMatthias Ringwald         //
463*5fd0122aSMatthias Ringwald         SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
464*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_SYSTICK)
465*5fd0122aSMatthias Ringwald     {
466*5fd0122aSMatthias Ringwald         //
467*5fd0122aSMatthias Ringwald         // Pend the SysTick interrupt.
468*5fd0122aSMatthias Ringwald         //
469*5fd0122aSMatthias Ringwald         SCB->ICSR |= SCB_ICSR_PENDSTSET_Msk;
470*5fd0122aSMatthias Ringwald     } else if (interruptNumber >= 16)
471*5fd0122aSMatthias Ringwald     {
472*5fd0122aSMatthias Ringwald         //
473*5fd0122aSMatthias Ringwald         // Pend the general interrupt.
474*5fd0122aSMatthias Ringwald         //
475*5fd0122aSMatthias Ringwald         HWREG32 (g_pulPendRegs[(interruptNumber - 16) / 32]) = 1
476*5fd0122aSMatthias Ringwald                 << ((interruptNumber - 16) & 31);
477*5fd0122aSMatthias Ringwald     }
478*5fd0122aSMatthias Ringwald }
479*5fd0122aSMatthias Ringwald 
Interrupt_unpendInterrupt(uint32_t interruptNumber)480*5fd0122aSMatthias Ringwald void Interrupt_unpendInterrupt(uint32_t interruptNumber)
481*5fd0122aSMatthias Ringwald {
482*5fd0122aSMatthias Ringwald     //
483*5fd0122aSMatthias Ringwald     // Check the arguments.
484*5fd0122aSMatthias Ringwald     //
485*5fd0122aSMatthias Ringwald     ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
486*5fd0122aSMatthias Ringwald 
487*5fd0122aSMatthias Ringwald     //
488*5fd0122aSMatthias Ringwald     // Determine the interrupt to unpend.
489*5fd0122aSMatthias Ringwald     //
490*5fd0122aSMatthias Ringwald     if (interruptNumber == FAULT_PENDSV)
491*5fd0122aSMatthias Ringwald     {
492*5fd0122aSMatthias Ringwald         //
493*5fd0122aSMatthias Ringwald         // Unpend the PendSV interrupt.
494*5fd0122aSMatthias Ringwald         //
495*5fd0122aSMatthias Ringwald         SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk;
496*5fd0122aSMatthias Ringwald     } else if (interruptNumber == FAULT_SYSTICK)
497*5fd0122aSMatthias Ringwald     {
498*5fd0122aSMatthias Ringwald         //
499*5fd0122aSMatthias Ringwald         // Unpend the SysTick interrupt.
500*5fd0122aSMatthias Ringwald         //
501*5fd0122aSMatthias Ringwald         SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
502*5fd0122aSMatthias Ringwald     } else if (interruptNumber >= 16)
503*5fd0122aSMatthias Ringwald     {
504*5fd0122aSMatthias Ringwald         //
505*5fd0122aSMatthias Ringwald         // Unpend the general interrupt.
506*5fd0122aSMatthias Ringwald         //
507*5fd0122aSMatthias Ringwald         HWREG32 (g_pulUnpendRegs[(interruptNumber - 16) / 32]) = 1
508*5fd0122aSMatthias Ringwald                 << ((interruptNumber - 16) & 31);
509*5fd0122aSMatthias Ringwald     }
510*5fd0122aSMatthias Ringwald }
511*5fd0122aSMatthias Ringwald 
Interrupt_setPriorityMask(uint8_t priorityMask)512*5fd0122aSMatthias Ringwald void Interrupt_setPriorityMask(uint8_t priorityMask)
513*5fd0122aSMatthias Ringwald {
514*5fd0122aSMatthias Ringwald     CPU_basepriSet(priorityMask);
515*5fd0122aSMatthias Ringwald }
516*5fd0122aSMatthias Ringwald 
Interrupt_getPriorityMask(void)517*5fd0122aSMatthias Ringwald uint8_t Interrupt_getPriorityMask(void)
518*5fd0122aSMatthias Ringwald {
519*5fd0122aSMatthias Ringwald     return (CPU_basepriGet());
520*5fd0122aSMatthias Ringwald }
521*5fd0122aSMatthias Ringwald 
Interrupt_setVectorTableAddress(uint32_t addr)522*5fd0122aSMatthias Ringwald void Interrupt_setVectorTableAddress(uint32_t addr)
523*5fd0122aSMatthias Ringwald {
524*5fd0122aSMatthias Ringwald     SCB->VTOR = addr;
525*5fd0122aSMatthias Ringwald }
526*5fd0122aSMatthias Ringwald 
Interrupt_getVectorTableAddress(void)527*5fd0122aSMatthias Ringwald uint32_t Interrupt_getVectorTableAddress(void)
528*5fd0122aSMatthias Ringwald {
529*5fd0122aSMatthias Ringwald     return SCB->VTOR;
530*5fd0122aSMatthias Ringwald }
531*5fd0122aSMatthias Ringwald 
Interrupt_enableSleepOnIsrExit(void)532*5fd0122aSMatthias Ringwald void Interrupt_enableSleepOnIsrExit(void)
533*5fd0122aSMatthias Ringwald {
534*5fd0122aSMatthias Ringwald     SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
535*5fd0122aSMatthias Ringwald }
536*5fd0122aSMatthias Ringwald 
Interrupt_disableSleepOnIsrExit(void)537*5fd0122aSMatthias Ringwald void Interrupt_disableSleepOnIsrExit(void)
538*5fd0122aSMatthias Ringwald {
539*5fd0122aSMatthias Ringwald     SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;
540*5fd0122aSMatthias Ringwald }
541