221 lines
6.8 KiB
C
221 lines
6.8 KiB
C
/* mbed Microcontroller Library
|
|
* CMSIS-style functionality to support dynamic vectors
|
|
*******************************************************************************
|
|
* Copyright (c) 2011 ARM Limited. All rights reserved.
|
|
* All rights reserved.
|
|
*
|
|
* Redistribution and use in source and binary forms, with or without
|
|
* modification, are permitted provided that the following conditions are met:
|
|
*
|
|
* 1. Redistributions of source code must retain the above copyright notice,
|
|
* this list of conditions and the following disclaimer.
|
|
* 2. 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.
|
|
* 3. Neither the name of ARM Limited 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 HOLDER 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.
|
|
*******************************************************************************
|
|
*/
|
|
#ifndef __ARM_ARCH_ISA_ARM
|
|
|
|
#include "cmsis_nvic.h"
|
|
#include "plat_types.h"
|
|
#include "plat_addr_map.h"
|
|
#include "hal_location.h"
|
|
#ifdef __ARMCC_VERSION
|
|
#include "link_sym_armclang.h"
|
|
#endif
|
|
|
|
STATIC_ASSERT(NVIC_NUM_VECTORS * 4 <= VECTOR_SECTION_SIZE, "ERROR: VECTOR_SECTION_SIZE too small!");
|
|
|
|
// The vector table must be aligned to NVIC_NUM_VECTORS-word boundary, rounding up to the next power of two
|
|
// -- 0x100 for 33~64 vectors, and 0x200 for 65~128 vectors
|
|
#ifdef __ARMCC_VERSION
|
|
#define VECTOR_LOC __attribute__((section(".bss.vector_table")))
|
|
#else
|
|
#define VECTOR_LOC __attribute__((section(".vector_table")))
|
|
#endif
|
|
|
|
#define FAULT_HANDLER __attribute__((weak,alias("NVIC_default_handler")))
|
|
|
|
static uint32_t VECTOR_LOC vector_table[NVIC_NUM_VECTORS];
|
|
|
|
void NVIC_DisableAllIRQs(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < (USER_IRQn_QTY + 31) / 32; i++) {
|
|
NVIC->ICER[i] = ~0UL;
|
|
}
|
|
SCB->VTOR = 0;
|
|
}
|
|
|
|
static void NAKED BOOT_TEXT_FLASH_LOC NVIC_default_handler(void)
|
|
{
|
|
asm volatile("_loop:; nop; nop; nop; nop; b _loop;");
|
|
}
|
|
|
|
void FAULT_HANDLER Reset_Handler(void);
|
|
void FAULT_HANDLER NMI_Handler(void);
|
|
void FAULT_HANDLER HardFault_Handler(void);
|
|
void FAULT_HANDLER MemManage_Handler(void);
|
|
void FAULT_HANDLER BusFault_Handler(void);
|
|
void FAULT_HANDLER UsageFault_Handler(void);
|
|
void FAULT_HANDLER SecureFault_Handler(void);
|
|
void FAULT_HANDLER SVC_Handler(void);
|
|
void FAULT_HANDLER DebugMon_Handler(void);
|
|
void FAULT_HANDLER PendSV_Handler(void);
|
|
void FAULT_HANDLER SysTick_Handler(void);
|
|
extern uint32_t __rom_stack[];
|
|
extern uint32_t __stack[];
|
|
|
|
static const uint32_t BOOT_RODATA_FLASH_LOC fault_handlers[NVIC_USER_IRQ_OFFSET] = {
|
|
#if defined(ROM_BUILD) && !defined(ROM_IN_FLASH)
|
|
(uint32_t)__rom_stack,
|
|
#else
|
|
(uint32_t)__stack,
|
|
#endif
|
|
(uint32_t)Reset_Handler,
|
|
(uint32_t)NMI_Handler,
|
|
(uint32_t)HardFault_Handler,
|
|
(uint32_t)MemManage_Handler,
|
|
(uint32_t)BusFault_Handler,
|
|
(uint32_t)UsageFault_Handler,
|
|
(uint32_t)SecureFault_Handler,
|
|
(uint32_t)NVIC_default_handler,
|
|
(uint32_t)NVIC_default_handler,
|
|
(uint32_t)NVIC_default_handler,
|
|
(uint32_t)SVC_Handler,
|
|
(uint32_t)DebugMon_Handler,
|
|
(uint32_t)NVIC_default_handler,
|
|
(uint32_t)PendSV_Handler,
|
|
(uint32_t)SysTick_Handler,
|
|
};
|
|
|
|
void BOOT_TEXT_FLASH_LOC NVIC_InitVectors(void)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < NVIC_NUM_VECTORS; i++) {
|
|
vector_table[i] = (i < ARRAY_SIZE(fault_handlers)) ?
|
|
fault_handlers[i] : (uint32_t)NVIC_default_handler;
|
|
}
|
|
|
|
SCB->VTOR = (uint32_t)vector_table;
|
|
__DSB();
|
|
}
|
|
|
|
void NVIC_SetDefaultFaultHandler(NVIC_DEFAULT_FAULT_HANDLER_T handler)
|
|
{
|
|
int i;
|
|
|
|
for (i = 1; i < ARRAY_SIZE(fault_handlers); i++) {
|
|
if (vector_table[i] == (uint32_t)NVIC_default_handler) {
|
|
vector_table[i] = (uint32_t)handler;
|
|
}
|
|
}
|
|
}
|
|
|
|
IRQn_Type NVIC_GetCurrentActiveIRQ(void)
|
|
{
|
|
IRQn_Type irq = (__get_IPSR() & IPSR_ISR_Msk) - NVIC_USER_IRQ_OFFSET;
|
|
return irq;
|
|
}
|
|
|
|
#ifdef CORE_SLEEP_POWER_DOWN
|
|
|
|
void SRAM_TEXT_LOC NVIC_PowerDownSleep(uint32_t *buf, uint32_t cnt)
|
|
{
|
|
int i;
|
|
uint32_t idx;
|
|
__IO uint32_t *regs;
|
|
|
|
idx = 0;
|
|
for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 31) / 32; i++) {
|
|
buf[idx++] = NVIC->ISER[i];
|
|
}
|
|
#if (__CORTEX_M <= 4)
|
|
regs = (__IO uint32_t *)&NVIC->IP[0];
|
|
#else
|
|
regs = (__IO uint32_t *)&NVIC->IPR[0];
|
|
#endif
|
|
for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 3) / 4; i++) {
|
|
buf[idx++] = regs[i];
|
|
}
|
|
buf[idx++] = SCnSCB->ACTLR;
|
|
buf[idx++] = SCB->ICSR;
|
|
buf[idx++] = SCB->AIRCR;
|
|
buf[idx++] = SCB->SCR;
|
|
buf[idx++] = SCB->CCR;
|
|
#if (__CORTEX_M <= 4)
|
|
regs = (__IO uint32_t *)&SCB->SHP[0];
|
|
#else
|
|
regs = (__IO uint32_t *)&SCB->SHPR[0];
|
|
#endif
|
|
buf[idx++] = regs[0];
|
|
buf[idx++] = regs[1];
|
|
buf[idx++] = regs[2];
|
|
buf[idx++] = SCB->SHCSR;
|
|
buf[idx++] = SysTick->CTRL;
|
|
buf[idx++] = SysTick->LOAD;
|
|
|
|
if (idx > cnt) {
|
|
do { asm volatile("nop \n nop \n nop \n nop"); } while (1);
|
|
}
|
|
}
|
|
|
|
void SRAM_TEXT_LOC NVIC_PowerDownWakeup(uint32_t *buf, uint32_t cnt)
|
|
{
|
|
int i;
|
|
uint32_t idx;
|
|
__IO uint32_t *regs;
|
|
|
|
idx = 0;
|
|
for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 31) / 32; i++) {
|
|
NVIC->ISER[i] = buf[idx++];
|
|
}
|
|
#if (__CORTEX_M <= 4)
|
|
regs = (__IO uint32_t *)&NVIC->IP[0];
|
|
#else
|
|
regs = (__IO uint32_t *)&NVIC->IPR[0];
|
|
#endif
|
|
for (i = 0; i < (NVIC_NUM_VECTORS - NVIC_USER_IRQ_OFFSET + 3) / 4; i++) {
|
|
regs[i] = buf[idx++];
|
|
}
|
|
SCnSCB->ACTLR = buf[idx++];
|
|
SCB->ICSR = buf[idx++];
|
|
SCB->AIRCR = buf[idx++];
|
|
SCB->SCR = buf[idx++];
|
|
SCB->CCR = buf[idx++];
|
|
#if (__CORTEX_M <= 4)
|
|
regs = (__IO uint32_t *)&SCB->SHP[0];
|
|
#else
|
|
regs = (__IO uint32_t *)&SCB->SHPR[0];
|
|
#endif
|
|
regs[0] = buf[idx++];
|
|
regs[1] = buf[idx++];
|
|
regs[2] = buf[idx++];
|
|
SCB->SHCSR = buf[idx++];
|
|
SysTick->CTRL = buf[idx++];
|
|
SysTick->LOAD = buf[idx++];
|
|
|
|
SCB->VTOR = (uint32_t)vector_table;
|
|
SysTick->VAL = 0;
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|