MotorControlModuleSDFM_TMS3.../Projects/EFC_Communication/Platform/device/interrupt.c

529 lines
15 KiB
C
Raw Permalink Normal View History

2024-06-07 11:12:56 +03:00
//###########################################################################
//
// FILE: interrupt.c
//
// TITLE: Driver for the NVIC Interrupt Controller.
//
//###########################################################################
// $TI Release: F2838x Support Library v3.04.00.00 $
// $Release Date: Fri Feb 12 19:08:49 IST 2021 $
// $Copyright:
// Copyright (C) 2021 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.
// $
//###########################################################################
#include "interrupt.h"
//*****************************************************************************
//
// RAM Vector Table to be used as srcVectorTable in
// Interrupt_initRAMVectorTable(). Set the size of the vector table to the
// largest number of interrupts of any device.
//
//*****************************************************************************
#ifndef USE_RTOS
#pragma DATA_ALIGN(vectorTableRAM, 1024U)
#pragma DATA_SECTION(vectorTableRAM, ".vtable")
#pragma WEAK(vectorTableRAM)
void (*vectorTableRAM[NUM_INTERRUPTS])(void);
#endif
//*****************************************************************************
//
// Interrupt_enable()
//
//*****************************************************************************
void
Interrupt_enable(uint32_t interruptNum)
{
//
// Check the arguments.
//
ASSERT(interruptNum < NUM_INTERRUPTS);
//
// Enable the interrupt.
//
if(interruptNum == FAULT_MPU)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) |= NVIC_SHCSRS_MEMFAULTENA;
}
else if(interruptNum == FAULT_BUS)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) |= NVIC_SHCSRS_BUSFAULTENA;
}
else if(interruptNum == FAULT_USAGE)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) |= NVIC_SHCSRS_USGFAULTENA;
}
else if(interruptNum == FAULT_SYSTICK)
{
HWREG(NVIC_BASE + NVIC_O_SYST_CSR) |= NVIC_SYST_CSR_TICKINT;
}
else if(interruptNum >= 16U)
{
HWREG(NVIC_BASE + NVIC_O_ISER0 +
(NVIC_OFFSET_INC * ((interruptNum - 16U) / 32U))) =
(uint32_t)1U << ((interruptNum - 16U) & 0x1FU);
}
else
{
//
// Do Nothing.
//
}
}
//*****************************************************************************
//
// Interrupt_disable()
//
//*****************************************************************************
void
Interrupt_disable(uint32_t interruptNum)
{
//
// Check the arguments.
//
ASSERT(interruptNum <= NUM_INTERRUPTS);
//
// Disable the interrupt.
//
if(interruptNum == FAULT_MPU)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) &= ~NVIC_SHCSRS_MEMFAULTENA;
}
else if(interruptNum == FAULT_BUS)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) &= ~NVIC_SHCSRS_BUSFAULTENA;
}
else if(interruptNum == FAULT_USAGE)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) &= ~NVIC_SHCSRS_USGFAULTENA;
}
else if(interruptNum == FAULT_SYSTICK)
{
HWREG(NVIC_BASE + NVIC_O_SYST_CSR) &= ~NVIC_SYST_CSR_TICKINT;
}
else if(interruptNum >= 16U)
{
HWREG(NVIC_BASE + NVIC_O_ICER0 +
(NVIC_OFFSET_INC * ((interruptNum - 16U) / 32U))) =
(uint32_t)1U << ((interruptNum - 16U) & 0x1FU);
}
else
{
//
// Do Nothing.
//
}
}
//*****************************************************************************
//
// Interrupt_isEnabled()
//
//*****************************************************************************
bool
Interrupt_isEnabled(uint32_t interruptNum)
{
uint32_t status;
//
// Check the arguments.
//
ASSERT(interruptNum <= NUM_INTERRUPTS);
//
// Return the interrupt status
//
if(interruptNum == FAULT_MPU)
{
status = HWREG(NVIC_BASE + NVIC_O_SHCSRS) & NVIC_SHCSRS_MEMFAULTENA;
}
else if(interruptNum == FAULT_BUS)
{
status = HWREG(NVIC_BASE + NVIC_O_SHCSRS) & NVIC_SHCSRS_BUSFAULTENA;
}
else if(interruptNum == FAULT_USAGE)
{
status = HWREG(NVIC_BASE + NVIC_O_SHCSRS) & NVIC_SHCSRS_USGFAULTENA;
}
else if(interruptNum == FAULT_SYSTICK)
{
status = HWREG(NVIC_BASE + NVIC_O_SYST_CSR) & NVIC_SYST_CSR_TICKINT;
}
else if(interruptNum >= 16U)
{
status = HWREG(NVIC_BASE + (uint32_t)NVIC_O_ISER0 +
(NVIC_OFFSET_INC * ((interruptNum - 16U) / 32U))) &
(1U << ((interruptNum - 16U) & 0x1FU));
}
else
{
status = 0U;
}
//
// Return peripheral interrupt status.
//
return(status != 0U);
}
//*****************************************************************************
//
// Interrupt_pend()
//
//*****************************************************************************
void
Interrupt_pend(uint32_t interruptNum)
{
//
// Check the arguments.
//
ASSERT(interruptNum <= NUM_INTERRUPTS);
//
// Pends the corresponding channel interrupt.
//
if(interruptNum == FAULT_NMI)
{
HWREG(NVIC_BASE + NVIC_O_ICSR) |= NVIC_ICSR_NMIPENDSET;
}
else if(interruptNum == FAULT_PENDSV)
{
HWREG(NVIC_BASE + NVIC_O_ICSR) |= NVIC_ICSR_PENDSVSET;
}
else if(interruptNum == FAULT_SYSTICK)
{
HWREG(NVIC_BASE + NVIC_O_ICSR) |= NVIC_ICSR_PENDSTSET;
}
else if(interruptNum == FAULT_SVCALL)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) |= NVIC_SHCSRS_SVCALLPENDED;
}
else if(interruptNum == FAULT_BUS)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) |= NVIC_SHCSRS_BUSFAULTPENDED;
}
else if(interruptNum == FAULT_MPU)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) |= NVIC_SHCSRS_MEMFAULTPENDED;
}
else if(interruptNum == FAULT_USAGE)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) |= NVIC_SHCSRS_USGFAULTPENDED;
}
else if(interruptNum >= 16U)
{
HWREG(NVIC_BASE + NVIC_O_ISPR0 +
(NVIC_OFFSET_INC * ((interruptNum - 16U) / 32U))) =
(uint32_t)1U << ((interruptNum - 16U) & 0x1FU);
}
else
{
//
// Do Nothing.
//
}
}
//*****************************************************************************
//
// Interrupt_unpend()
//
//*****************************************************************************
void
Interrupt_unpend(uint32_t interruptNum)
{
//
// Check the arguments.
//
ASSERT(interruptNum <= NUM_INTERRUPTS);
//
// Unpends the corresponding channel interrupt.
//
if(interruptNum == FAULT_PENDSV)
{
HWREG(NVIC_BASE + NVIC_O_ICSR) |= NVIC_ICSR_PENDSVCLR;
}
else if(interruptNum == FAULT_SYSTICK)
{
HWREG(NVIC_BASE + NVIC_O_ICSR) |= NVIC_ICSR_PENDSTCLR;
}
else if(interruptNum == FAULT_SVCALL)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) &= ~NVIC_SHCSRS_SVCALLPENDED;
}
else if(interruptNum == FAULT_BUS)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) &= ~NVIC_SHCSRS_BUSFAULTPENDED;
}
else if(interruptNum == FAULT_MPU)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) &= ~NVIC_SHCSRS_MEMFAULTPENDED;
}
else if(interruptNum == FAULT_USAGE)
{
HWREG(NVIC_BASE + NVIC_O_SHCSRS) &= ~NVIC_SHCSRS_USGFAULTPENDED;
}
else if(interruptNum >= 16U)
{
HWREG(NVIC_BASE + NVIC_O_ICPR0 +
(NVIC_OFFSET_INC * ((interruptNum - 16U) / 32U))) =
(uint32_t)1U << ((interruptNum - 16U) & (uint32_t)0x1FU);
}
else
{
//
// Do Nothing.
//
}
}
//*****************************************************************************
//
// Interrupt_setPriority()
//
//*****************************************************************************
void
Interrupt_setPriority(uint32_t interruptNum, uint32_t priority)
{
uint32_t offset, shift;
//
// Check the arguments.
//
ASSERT((interruptNum >= 4U) && (interruptNum < NUM_INTERRUPTS));
//
// Set the interrupt priority.
//
if(interruptNum == FAULT_MPU)
{
HWREG(NVIC_BASE + NVIC_O_SHPR1) = (HWREG(NVIC_BASE + NVIC_O_SHPR1) &
~(uint32_t)NVIC_SHPR1_PRI_4_M) |
(priority << NVIC_SHPR1_PRI_4_S);
}
else if(interruptNum == FAULT_BUS)
{
HWREG(NVIC_BASE + NVIC_O_SHPR1) = (HWREG(NVIC_BASE + NVIC_O_SHPR1) &
~(uint32_t)NVIC_SHPR1_PRI_5_M) |
(priority << NVIC_SHPR1_PRI_5_S);
}
else if(interruptNum == FAULT_USAGE)
{
HWREG(NVIC_BASE + NVIC_O_SHPR1) = (HWREG(NVIC_BASE + NVIC_O_SHPR1) &
~(uint32_t)NVIC_SHPR1_PRI_6_M) |
(priority << NVIC_SHPR1_PRI_6_S);
}
else if(interruptNum == FAULT_SVCALL)
{
HWREG(NVIC_BASE + NVIC_O_SHPR2) = (HWREG(NVIC_BASE + NVIC_O_SHPR2) &
~(uint32_t)NVIC_SHPR2_PRI_11_M) |
(priority << NVIC_SHPR2_PRI_11_S);
}
else if(interruptNum == FAULT_PENDSV)
{
HWREG(NVIC_BASE + NVIC_O_SHPR3) = (HWREG(NVIC_BASE + NVIC_O_SHPR3) &
~(uint32_t)NVIC_SHPR3_PRI_14_M) |
(priority << NVIC_SHPR3_PRI_14_S);
}
else if(interruptNum == FAULT_SYSTICK)
{
HWREG(NVIC_BASE + NVIC_O_SHPR3) = (HWREG(NVIC_BASE + NVIC_O_SHPR3) &
~(uint32_t)NVIC_SHPR3_PRI_15_M) |
(priority << NVIC_SHPR3_PRI_15_S);
}
else if(interruptNum >= 16U)
{
offset = (uint32_t)NVIC_OFFSET_INC * ((interruptNum - 16U) / 4U);
shift = ((uint32_t)8U * (interruptNum & 0x3U)) + 5U;
HWREG(NVIC_BASE + NVIC_O_IPR0 + offset) =
(HWREG(NVIC_BASE + (uint32_t)NVIC_O_IPR0 + offset) &
~((uint32_t)NVIC_IPR0_PRI_0_M << shift)) |
(priority << shift);
}
else
{
//
// Do Nothing.
//
}
}
//*****************************************************************************
//
// Interrupt_getPriority()
//
//*****************************************************************************
uint32_t
Interrupt_getPriority(uint32_t interruptNum)
{
uint32_t offset, shift, status;
//
// Check the arguments.
//
ASSERT((interruptNum >= 4U) && (interruptNum < NUM_INTERRUPTS));
//
// Set the interrupt priority.
//
if(interruptNum == FAULT_MPU)
{
status = (HWREG(NVIC_BASE + NVIC_O_SHPR1) & NVIC_SHPR1_PRI_4_M) >>
NVIC_SHPR1_PRI_4_S;
}
else if(interruptNum == FAULT_BUS)
{
status = (HWREG(NVIC_BASE + NVIC_O_SHPR1) & NVIC_SHPR1_PRI_5_M) >>
NVIC_SHPR1_PRI_5_S;
}
else if(interruptNum == FAULT_USAGE)
{
status = (HWREG(NVIC_BASE + NVIC_O_SHPR1) & NVIC_SHPR1_PRI_6_M) >>
NVIC_SHPR1_PRI_6_S;
}
else if(interruptNum == FAULT_SVCALL)
{
status = (HWREG(NVIC_BASE + NVIC_O_SHPR2) & NVIC_SHPR2_PRI_11_M) >>
NVIC_SHPR2_PRI_11_S;
}
else if(interruptNum == FAULT_PENDSV)
{
status = (HWREG(NVIC_BASE + NVIC_O_SHPR3) & NVIC_SHPR3_PRI_14_M) >>
NVIC_SHPR3_PRI_14_S;
}
else if(interruptNum == FAULT_SYSTICK)
{
status = (HWREG(NVIC_BASE + NVIC_O_SHPR3) & NVIC_SHPR3_PRI_15_M) >>
NVIC_SHPR3_PRI_15_S;
}
else if(interruptNum >= 16U)
{
offset = (uint32_t)NVIC_OFFSET_INC * ((interruptNum - 16U) / 4U);
shift = ((uint32_t)8U * (interruptNum & 0x3U)) + 5U;
status = (HWREG(NVIC_BASE + (uint32_t)NVIC_O_IPR0 + offset) >> shift) &
0xFFU;
}
else
{
status = 0U;
}
return(status);
}
//*****************************************************************************
//
// Interrupt_initRAMVectorTable()
//
//*****************************************************************************
void
Interrupt_initRAMVectorTable(void (*srcVectorTable[])(void),
void (*dstVectorTable[])(void))
{
uint32_t index;
//
// Check whether dstVectorTable lies in RAM and is correctly aligned.
//
ASSERT((uint32_t)dstVectorTable >= 0x20000000U);
ASSERT(((uint32_t)dstVectorTable & 0x000003FFU) == 0U);
if(HWREG(NVIC_BASE + NVIC_O_VTOR) != (uint32_t)dstVectorTable)
{
//
// Point the NVIC at the RAM vector table.
//
HWREG(NVIC_BASE + NVIC_O_VTOR) = (uint32_t)dstVectorTable;
}
//
// Copy the ISRs from temp vector table to RAM vector table.
//
for(index = 0U; index < NUM_INTERRUPTS; index++)
{
dstVectorTable[index] = srcVectorTable[index];
}
}
//*****************************************************************************
//
// Interrupt_registerHandler()
//
//*****************************************************************************
void
Interrupt_registerHandler(uint32_t interruptNum, void (*intHandler)(void))
{
uint32_t index, value;
//
// Check the arguments.
//
ASSERT(interruptNum < NUM_INTERRUPTS);
//
// Make sure that the RAM vector table is correctly aligned.
// Check vector table alignment in device datasheet.
//
ASSERT(((uint32_t)vectorTableRAM & 0x000003FFU) == 0U);
//
// See if the RAM vector table has been initialized.
//
if(HWREG(NVIC_BASE + NVIC_O_VTOR) != (uint32_t)vectorTableRAM)
{
//
// Copy the vector table from the beginning of FLASH to the RAM vector
// table.
//
value = HWREG(NVIC_BASE + NVIC_O_VTOR);
for(index = 0U; index < NUM_INTERRUPTS; index++)
{
vectorTableRAM[index] = (void (*)(void))HWREG((index * 4U) + value);
}
//
// Point the NVIC at the RAM vector table.
//
HWREG(NVIC_BASE + NVIC_O_VTOR) = (uint32_t)vectorTableRAM;
}
//
// Save the interrupt handler.
//
vectorTableRAM[interruptNum] = intHandler;
}