2 * -------------------------------------------
3 * MSP432 DriverLib - v3_10_00_09
4 * -------------------------------------------
6 * --COPYRIGHT--,BSD,BSD
7 * Copyright (c) 2014, Texas Instruments Incorporated
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
17 * * Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
21 * * Neither the name of Texas Instruments Incorporated nor the names of
22 * its contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
27 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
29 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
32 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
33 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
34 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
35 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 /* Standard Includes */
40 /* DriverLib Includes */
43 #include <interrupt.h>
44 #include <hw_memmap.h>
46 //*****************************************************************************
48 // This is a mapping between priority grouping encodings and the number of
49 // preemption priority bits.
51 //*****************************************************************************
52 static const uint32_t g_pulPriority[] =
53 { NVIC_APINT_PRIGROUP_0_8, NVIC_APINT_PRIGROUP_1_7, NVIC_APINT_PRIGROUP_2_6,
54 NVIC_APINT_PRIGROUP_3_5, NVIC_APINT_PRIGROUP_4_4,
55 NVIC_APINT_PRIGROUP_5_3, NVIC_APINT_PRIGROUP_6_2,
56 NVIC_APINT_PRIGROUP_7_1 };
58 //*****************************************************************************
60 // This is a mapping between interrupt number and the register that contains
61 // the priority encoding for that interrupt.
63 //*****************************************************************************
64 static const uint32_t g_pulRegs[] =
65 { 0, NVIC_SYS_PRI1_R, NVIC_SYS_PRI2_R, NVIC_SYS_PRI3_R, NVIC_PRI0_R,
66 NVIC_PRI1_R, NVIC_PRI2_R, NVIC_PRI3_R, NVIC_PRI4_R, NVIC_PRI5_R,
67 NVIC_PRI6_R, NVIC_PRI7_R, NVIC_PRI8_R, NVIC_PRI9_R, NVIC_PRI10_R,
68 NVIC_PRI11_R, NVIC_PRI12_R, NVIC_PRI13_R, NVIC_PRI14_R, NVIC_PRI15_R };
70 //*****************************************************************************
72 // This is a mapping between interrupt number (for the peripheral interrupts
73 // only) and the register that contains the interrupt enable for that
76 //*****************************************************************************
77 static const uint32_t g_pulEnRegs[] =
78 { NVIC_EN0_R, NVIC_EN1_R };
80 //*****************************************************************************
82 // This is a mapping between interrupt number (for the peripheral interrupts
83 // only) and the register that contains the interrupt disable for that
86 //*****************************************************************************
87 static const uint32_t g_pulDisRegs[] =
88 { NVIC_DIS0_R, NVIC_DIS1_R };
90 //*****************************************************************************
92 // This is a mapping between interrupt number (for the peripheral interrupts
93 // only) and the register that contains the interrupt pend for that interrupt.
95 //*****************************************************************************
96 static const uint32_t g_pulPendRegs[] =
97 { NVIC_PEND0_R, NVIC_PEND1_R };
99 //*****************************************************************************
101 // This is a mapping between interrupt number (for the peripheral interrupts
102 // only) and the register that contains the interrupt unpend for that
105 //*****************************************************************************
106 static const uint32_t g_pulUnpendRegs[] =
107 { NVIC_UNPEND0_R, NVIC_UNPEND1_R };
109 //*****************************************************************************
112 //! The default interrupt handler.
114 //! This is the default interrupt handler for all interrupts. It simply loops
115 //! forever so that the system state is preserved for observation by a
116 //! debugger. Since interrupts should be disabled before unregistering the
117 //! corresponding handler, this should never be called.
121 //*****************************************************************************
122 static void IntDefaultHandler(void)
125 // Go into an infinite loop.
132 //*****************************************************************************
134 // The processor vector table.
136 // This contains a list of the handlers for the various interrupt sources in
137 // the system. The layout of this list is defined by the hardware; assertion
138 // of an interrupt causes the processor to start executing directly at the
139 // address given in the corresponding location in this list.
141 //*****************************************************************************
143 #pragma data_alignment=1024
144 static __no_init void (*g_pfnRAMVectors[NUM_INTERRUPTS+1])(void) @ "VTABLE";
146 #pragma DATA_ALIGN(g_pfnRAMVectors, 1024)
147 #pragma DATA_SECTION(g_pfnRAMVectors, ".vtable")
148 void (*g_pfnRAMVectors[NUM_INTERRUPTS + 1])(void);
150 static __attribute__((section("vtable")))
151 void (*g_pfnRAMVectors[NUM_INTERRUPTS+1])(void) __attribute__((aligned(1024)));
154 bool Interrupt_enableMaster(void)
157 // Enable processor interrupts.
159 return (CPU_cpsie());
162 bool Interrupt_disableMaster(void)
165 // Disable processor interrupts.
167 return (CPU_cpsid());
170 void Interrupt_registerInterrupt(uint32_t interruptNumber,
171 void (*intHandler)(void))
173 uint32_t ulIdx, ulValue;
176 // Check the arguments.
178 ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
181 // Make sure that the RAM vector table is correctly aligned.
183 ASSERT(((uint32_t) g_pfnRAMVectors & 0x000000ff) == 0);
186 // See if the RAM vector table has been initialized.
188 if (SCB->VTOR != (uint32_t) g_pfnRAMVectors)
191 // Copy the vector table from the beginning of FLASH to the RAM vector
195 for (ulIdx = 0; ulIdx < (NUM_INTERRUPTS + 1); ulIdx++)
197 g_pfnRAMVectors[ulIdx] = (void (*)(void)) HWREG32(
198 (ulIdx * 4) + ulValue);
202 // Point the NVIC at the RAM vector table.
204 SCB->VTOR = (uint32_t) g_pfnRAMVectors;
208 // Save the interrupt handler.
210 g_pfnRAMVectors[interruptNumber] = intHandler;
213 void Interrupt_unregisterInterrupt(uint32_t interruptNumber)
216 // Check the arguments.
218 ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
221 // Reset the interrupt handler.
223 g_pfnRAMVectors[interruptNumber] = IntDefaultHandler;
226 void Interrupt_setPriorityGrouping(uint32_t bits)
229 // Check the arguments.
231 ASSERT(bits < NUM_PRIORITY);
234 // Set the priority grouping.
236 SCB->AIRCR = SCB_AIRCR_VECTKEY_Msk | g_pulPriority[bits];
239 uint32_t Interrupt_getPriorityGrouping(void)
241 uint32_t ulLoop, ulValue;
244 // Read the priority grouping.
246 ulValue = SCB->AIRCR & NVIC_APINT_PRIGROUP_M;
249 // Loop through the priority grouping values.
251 for (ulLoop = 0; ulLoop < NUM_PRIORITY; ulLoop++)
254 // Stop looping if this value matches.
256 if (ulValue == g_pulPriority[ulLoop])
263 // Return the number of priority bits.
268 void Interrupt_setPriority(uint32_t interruptNumber, uint8_t priority)
273 // Check the arguments.
275 ASSERT((interruptNumber >= 4) && (interruptNumber < (NUM_INTERRUPTS+1)));
278 // Set the interrupt priority.
280 ulTemp = HWREG32(g_pulRegs[interruptNumber >> 2]);
281 ulTemp &= ~(0xFF << (8 * (interruptNumber & 3)));
282 ulTemp |= priority << (8 * (interruptNumber & 3));
283 HWREG32 (g_pulRegs[interruptNumber >> 2]) = ulTemp;
286 uint8_t Interrupt_getPriority(uint32_t interruptNumber)
289 // Check the arguments.
291 ASSERT((interruptNumber >= 4) && (interruptNumber < (NUM_INTERRUPTS+1)));
294 // Return the interrupt priority.
296 return ((HWREG32(g_pulRegs[interruptNumber >> 2])
297 >> (8 * (interruptNumber & 3))) & 0xFF);
300 void Interrupt_enableInterrupt(uint32_t interruptNumber)
303 // Check the arguments.
305 ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
308 // Determine the interrupt to enable.
310 if (interruptNumber == FAULT_MPU)
313 // Enable the MemManage interrupt.
315 SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk;
316 } else if (interruptNumber == FAULT_BUS)
319 // Enable the bus fault interrupt.
321 SCB->SHCSR |= SCB_SHCSR_BUSFAULTENA_Msk;
322 } else if (interruptNumber == FAULT_USAGE)
325 // Enable the usage fault interrupt.
327 SCB->SHCSR |= SCB_SHCSR_USGFAULTENA_Msk;
328 } else if (interruptNumber == FAULT_SYSTICK)
331 // Enable the System Tick interrupt.
333 SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
334 } else if (interruptNumber >= 16)
337 // Enable the general interrupt.
339 HWREG32 (g_pulEnRegs[(interruptNumber - 16) / 32]) = 1
340 << ((interruptNumber - 16) & 31);
344 void Interrupt_disableInterrupt(uint32_t interruptNumber)
347 // Check the arguments.
349 ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
352 // Determine the interrupt to disable.
354 if (interruptNumber == FAULT_MPU)
357 // Disable the MemManage interrupt.
359 SCB->SHCSR &= ~(SCB_SHCSR_MEMFAULTENA_Msk);
360 } else if (interruptNumber == FAULT_BUS)
363 // Disable the bus fault interrupt.
365 SCB->SHCSR &= ~(SCB_SHCSR_BUSFAULTENA_Msk);
366 } else if (interruptNumber == FAULT_USAGE)
369 // Disable the usage fault interrupt.
371 SCB->SHCSR &= ~(SCB_SHCSR_USGFAULTENA_Msk);
372 } else if (interruptNumber == FAULT_SYSTICK)
375 // Disable the System Tick interrupt.
377 SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);
378 } else if (interruptNumber >= 16)
381 // Disable the general interrupt.
383 HWREG32 (g_pulDisRegs[(interruptNumber - 16) / 32]) = 1
384 << ((interruptNumber - 16) & 31);
388 bool Interrupt_isEnabled(uint32_t interruptNumber)
393 // Check the arguments.
395 ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
398 // Initialize the return value.
403 // Determine the interrupt to disable.
405 if (interruptNumber == FAULT_MPU)
408 // Check the MemManage interrupt.
410 ulRet = SCB->SHCSR & SCB_SHCSR_MEMFAULTENA_Msk;
411 } else if (interruptNumber == FAULT_BUS)
414 // Check the bus fault interrupt.
416 ulRet = SCB->SHCSR & SCB_SHCSR_BUSFAULTENA_Msk;
417 } else if (interruptNumber == FAULT_USAGE)
420 // Check the usage fault interrupt.
422 ulRet = SCB->SHCSR & SCB_SHCSR_USGFAULTENA_Msk;
423 } else if (interruptNumber == FAULT_SYSTICK)
426 // Check the System Tick interrupt.
428 ulRet = SysTick->CTRL & SysTick_CTRL_ENABLE_Msk;
429 } else if (interruptNumber >= 16)
432 // Check the general interrupt.
434 ulRet = HWREG32(g_pulEnRegs[(interruptNumber - 16) / 32])
435 & (1 << ((interruptNumber - 16) & 31));
440 void Interrupt_pendInterrupt(uint32_t interruptNumber)
443 // Check the arguments.
445 ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
448 // Determine the interrupt to pend.
450 if (interruptNumber == FAULT_NMI)
453 // Pend the NMI interrupt.
455 SCB->ICSR |= SCB_ICSR_NMIPENDSET_Msk;
456 } else if (interruptNumber == FAULT_PENDSV)
459 // Pend the PendSV interrupt.
461 SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
462 } else if (interruptNumber == FAULT_SYSTICK)
465 // Pend the SysTick interrupt.
467 SCB->ICSR |= SCB_ICSR_PENDSTSET_Msk;
468 } else if (interruptNumber >= 16)
471 // Pend the general interrupt.
473 HWREG32 (g_pulPendRegs[(interruptNumber - 16) / 32]) = 1
474 << ((interruptNumber - 16) & 31);
478 void Interrupt_unpendInterrupt(uint32_t interruptNumber)
481 // Check the arguments.
483 ASSERT(interruptNumber < (NUM_INTERRUPTS+1));
486 // Determine the interrupt to unpend.
488 if (interruptNumber == FAULT_PENDSV)
491 // Unpend the PendSV interrupt.
493 SCB->ICSR |= SCB_ICSR_PENDSVCLR_Msk;
494 } else if (interruptNumber == FAULT_SYSTICK)
497 // Unpend the SysTick interrupt.
499 SCB->ICSR |= SCB_ICSR_PENDSTCLR_Msk;
500 } else if (interruptNumber >= 16)
503 // Unpend the general interrupt.
505 HWREG32 (g_pulUnpendRegs[(interruptNumber - 16) / 32]) = 1
506 << ((interruptNumber - 16) & 31);
510 void Interrupt_setPriorityMask(uint8_t priorityMask)
512 CPU_basepriSet(priorityMask);
515 uint8_t Interrupt_getPriorityMask(void)
517 return (CPU_basepriGet());
520 void Interrupt_setVectorTableAddress(uint32_t addr)
525 uint32_t Interrupt_getVectorTableAddress(void)
530 void Interrupt_enableSleepOnIsrExit(void)
532 SCB->SCR |= SCB_SCR_SLEEPONEXIT_Msk;
535 void Interrupt_disableSleepOnIsrExit(void)
537 SCB->SCR &= ~SCB_SCR_SLEEPONEXIT_Msk;