503 lines
18 KiB
C
503 lines
18 KiB
C
|
//###########################################################################
|
||
|
//
|
||
|
// FILE: interrupt.h
|
||
|
//
|
||
|
// TITLE: C28x Interrupt (PIE) driver.
|
||
|
//
|
||
|
//###########################################################################
|
||
|
// $Copyright:
|
||
|
// Copyright (C) 2022 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.
|
||
|
// $
|
||
|
//###########################################################################
|
||
|
|
||
|
#ifndef INTERRUPT_H
|
||
|
#define INTERRUPT_H
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// If building with a C++ compiler, make all of the definitions in this header
|
||
|
// have a C binding.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#ifdef __cplusplus
|
||
|
extern "C"
|
||
|
{
|
||
|
#endif
|
||
|
|
||
|
#ifdef __TMS320C28XX__
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! \addtogroup interrupt_api Interrupt
|
||
|
//! @{
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
|
||
|
#include <stdbool.h>
|
||
|
#include <stdint.h>
|
||
|
#include "inc/hw_ints.h"
|
||
|
#include "inc/hw_memmap.h"
|
||
|
#include "inc/hw_pie.h"
|
||
|
#include "inc/hw_types.h"
|
||
|
#include "cpu.h"
|
||
|
#include "debug.h"
|
||
|
|
||
|
|
||
|
#ifndef DOXYGEN_PDF_IGNORE
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// The following are values that can be passed to the Interrupt_enableInCPU()
|
||
|
// and Interrupt_disableInCPU() functions as the cpuInterrupt parameter.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#define INTERRUPT_CPU_INT1 0x1U //!< CPU Interrupt Number 1
|
||
|
#define INTERRUPT_CPU_INT2 0x2U //!< CPU Interrupt Number 2
|
||
|
#define INTERRUPT_CPU_INT3 0x4U //!< CPU Interrupt Number 3
|
||
|
#define INTERRUPT_CPU_INT4 0x8U //!< CPU Interrupt Number 4
|
||
|
#define INTERRUPT_CPU_INT5 0x10U //!< CPU Interrupt Number 5
|
||
|
#define INTERRUPT_CPU_INT6 0x20U //!< CPU Interrupt Number 6
|
||
|
#define INTERRUPT_CPU_INT7 0x40U //!< CPU Interrupt Number 7
|
||
|
#define INTERRUPT_CPU_INT8 0x80U //!< CPU Interrupt Number 8
|
||
|
#define INTERRUPT_CPU_INT9 0x100U //!< CPU Interrupt Number 9
|
||
|
#define INTERRUPT_CPU_INT10 0x200U //!< CPU Interrupt Number 10
|
||
|
#define INTERRUPT_CPU_INT11 0x400U //!< CPU Interrupt Number 11
|
||
|
#define INTERRUPT_CPU_INT12 0x800U //!< CPU Interrupt Number 12
|
||
|
#define INTERRUPT_CPU_INT13 0x1000U //!< CPU Interrupt Number 13
|
||
|
#define INTERRUPT_CPU_INT14 0x2000U //!< CPU Interrupt Number 14
|
||
|
#define INTERRUPT_CPU_DLOGINT 0x4000U //!< CPU Data Log Interrupt
|
||
|
#define INTERRUPT_CPU_RTOSINT 0x8000U //!< CPU RTOS Interrupt
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// The following are values that can be passed to the Interrupt_clearACKGroup()
|
||
|
// function as the group parameter.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#define INTERRUPT_ACK_GROUP1 0x1U //!< Acknowledge PIE Interrupt Group 1
|
||
|
#define INTERRUPT_ACK_GROUP2 0x2U //!< Acknowledge PIE Interrupt Group 2
|
||
|
#define INTERRUPT_ACK_GROUP3 0x4U //!< Acknowledge PIE Interrupt Group 3
|
||
|
#define INTERRUPT_ACK_GROUP4 0x8U //!< Acknowledge PIE Interrupt Group 4
|
||
|
#define INTERRUPT_ACK_GROUP5 0x10U //!< Acknowledge PIE Interrupt Group 5
|
||
|
#define INTERRUPT_ACK_GROUP6 0x20U //!< Acknowledge PIE Interrupt Group 6
|
||
|
#define INTERRUPT_ACK_GROUP7 0x40U //!< Acknowledge PIE Interrupt Group 7
|
||
|
#define INTERRUPT_ACK_GROUP8 0x80U //!< Acknowledge PIE Interrupt Group 8
|
||
|
#define INTERRUPT_ACK_GROUP9 0x100U //!< Acknowledge PIE Interrupt Group 9
|
||
|
#define INTERRUPT_ACK_GROUP10 0x200U //!< Acknowledge PIE Interrupt Group 10
|
||
|
#define INTERRUPT_ACK_GROUP11 0x400U //!< Acknowledge PIE Interrupt Group 11
|
||
|
#define INTERRUPT_ACK_GROUP12 0x800U //!< Acknowledge PIE Interrupt Group 12
|
||
|
#endif
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Prototypes for the APIs.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! \internal
|
||
|
//! The default interrupt handler.
|
||
|
//!
|
||
|
//! This is the default interrupt handler. The Interrupt_initVectorTable()
|
||
|
//! function sets all vectors to this function. Also, when an interrupt is
|
||
|
//! unregistered using the Interrupt_unregister() function, this handler takes
|
||
|
//! its place. This should never be called during normal operation.
|
||
|
//!
|
||
|
//! The ESTOP0 statement is for debug purposes only. Remove and replace with an
|
||
|
//! appropriate error handling routine for your program.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
Interrupt_defaultHandler(void);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! \internal
|
||
|
//! The default illegal instruction trap interrupt handler.
|
||
|
//!
|
||
|
//! This is the default interrupt handler for an illegal instruction trap
|
||
|
//! (ITRAP). The Interrupt_initVectorTable() function sets the appropriate
|
||
|
//! vector to this function. This should never be called during normal
|
||
|
//! operation.
|
||
|
//!
|
||
|
//! The ESTOP0 statement is for debug purposes only. Remove and replace with
|
||
|
//! an appropriate error handling routine for your program.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
Interrupt_illegalOperationHandler(void);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! \internal
|
||
|
//! The default non-maskable interrupt handler.
|
||
|
//!
|
||
|
//! This is the default interrupt handler for a non-maskable interrupt (NMI).
|
||
|
//! The Interrupt_initVectorTable() function sets the appropriate vector to
|
||
|
//! this function. This should never be called during normal operation.
|
||
|
//!
|
||
|
//! The ESTOP0 statement is for debug purposes only. Remove and replace with an
|
||
|
//! appropriate error handling routine for your program.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
Interrupt_nmiHandler(void);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Allows the CPU to process interrupts.
|
||
|
//!
|
||
|
//! This function clears the global interrupt mask bit (INTM) in the CPU,
|
||
|
//! allowing the processor to respond to interrupts.
|
||
|
//!
|
||
|
//! \return Returns \b true if interrupts were disabled when the function was
|
||
|
//! called or \b false if they were initially enabled.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline bool
|
||
|
Interrupt_enableGlobal(void)
|
||
|
{
|
||
|
//
|
||
|
// Enable processor interrupts.
|
||
|
//
|
||
|
return(((__enable_interrupts() & 0x1U) != 0U) ? true : false);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Stops the CPU from processing interrupts.
|
||
|
//!
|
||
|
//! This function sets the global interrupt mask bit (INTM) in the CPU,
|
||
|
//! preventing the processor from receiving maskable interrupts.
|
||
|
//!
|
||
|
//! \return Returns \b true if interrupts were already disabled when the
|
||
|
//! function was called or \b false if they were initially enabled.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline bool
|
||
|
Interrupt_disableGlobal(void)
|
||
|
{
|
||
|
//
|
||
|
// Disable processor interrupts.
|
||
|
//
|
||
|
return(((__disable_interrupts() & 0x1U) != 0U) ? true : false);
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Registers a function to be called when an interrupt occurs.
|
||
|
//!
|
||
|
//! \param interruptNumber specifies the interrupt in question.
|
||
|
//! \param handler is a pointer to the function to be called.
|
||
|
//!
|
||
|
//! This function is used to specify the handler function to be called when the
|
||
|
//! given interrupt is asserted to the processor. When the interrupt occurs,
|
||
|
//! if it is enabled (via Interrupt_enable()), the handler function will be
|
||
|
//! called in interrupt context. Since the handler function can preempt other
|
||
|
//! code, care must be taken to protect memory or peripherals that are accessed
|
||
|
//! by the handler and other non-handler code.
|
||
|
//!
|
||
|
//! The available \e interruptNumber values are supplied in
|
||
|
//! <tt>inc/hw_ints.h</tt>.
|
||
|
//!
|
||
|
//! \note This function assumes that the PIE has been enabled. See
|
||
|
//! Interrupt_initModule().
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
Interrupt_register(uint32_t interruptNumber, void (*handler)(void))
|
||
|
{
|
||
|
uint32_t address;
|
||
|
|
||
|
//
|
||
|
// Calculate appropriate address for the interrupt number
|
||
|
//
|
||
|
address = (uint32_t)PIEVECTTABLE_BASE +
|
||
|
(((interruptNumber & 0xFFFF0000U) >> 16U) * 2U);
|
||
|
|
||
|
//
|
||
|
// Copy ISR address into PIE table
|
||
|
//
|
||
|
EALLOW;
|
||
|
HWREG(address) = (uint32_t)handler;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Unregisters the function to be called when an interrupt occurs.
|
||
|
//!
|
||
|
//! \param interruptNumber specifies the interrupt in question.
|
||
|
//!
|
||
|
//! This function is used to indicate that a default handler
|
||
|
//! Interrupt_defaultHandler() should be called when the given interrupt is
|
||
|
//! asserted to the processor. Call Interrupt_disable() to disable
|
||
|
//! the interrupt before calling this function.
|
||
|
//!
|
||
|
//! The available \e interruptNumber values are supplied in
|
||
|
//! <tt>inc/hw_ints.h</tt>.
|
||
|
//!
|
||
|
//! \sa Interrupt_register() for important information about registering
|
||
|
//! interrupt handlers.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
Interrupt_unregister(uint32_t interruptNumber)
|
||
|
{
|
||
|
uint32_t address;
|
||
|
|
||
|
//
|
||
|
// Calculate appropriate address for the interrupt number
|
||
|
//
|
||
|
address = (uint32_t)PIEVECTTABLE_BASE +
|
||
|
(((interruptNumber & 0xFFFF0000U) >> 16U) * 2U);
|
||
|
|
||
|
//
|
||
|
// Copy default ISR address into PIE table
|
||
|
//
|
||
|
EALLOW;
|
||
|
HWREG(address) = (uint32_t)Interrupt_defaultHandler;
|
||
|
EDIS;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Enables CPU interrupt channels
|
||
|
//!
|
||
|
//! \param cpuInterrupt specifies the CPU interrupts to be enabled.
|
||
|
//!
|
||
|
//! This function enables the specified interrupts in the CPU. The
|
||
|
//! \e cpuInterrupt parameter is a logical OR of the values
|
||
|
//! \b INTERRUPT_CPU_INTx where x is the interrupt number between 1 and 14,
|
||
|
//! \b INTERRUPT_CPU_DLOGINT, and \b INTERRUPT_CPU_RTOSINT.
|
||
|
//!
|
||
|
//! \note Note that interrupts 1-12 correspond to the PIE groups with those
|
||
|
//! same numbers.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
Interrupt_enableInCPU(uint16_t cpuInterrupt)
|
||
|
{
|
||
|
//
|
||
|
// Set the interrupt bits in the CPU.
|
||
|
//
|
||
|
IER |= cpuInterrupt;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Disables CPU interrupt channels
|
||
|
//!
|
||
|
//! \param cpuInterrupt specifies the CPU interrupts to be disabled.
|
||
|
//!
|
||
|
//! This function disables the specified interrupts in the CPU. The
|
||
|
//! \e cpuInterrupt parameter is a logical OR of the values
|
||
|
//! \b INTERRUPT_CPU_INTx where x is the interrupt number between 1 and 14,
|
||
|
//! \b INTERRUPT_CPU_DLOGINT, and \b INTERRUPT_CPU_RTOSINT.
|
||
|
//!
|
||
|
//! \note Note that interrupts 1-12 correspond to the PIE groups with those
|
||
|
//! same numbers.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
Interrupt_disableInCPU(uint16_t cpuInterrupt)
|
||
|
{
|
||
|
//
|
||
|
// Clear the interrupt bits in the CPU.
|
||
|
//
|
||
|
IER &= ~cpuInterrupt;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Acknowledges PIE Interrupt Group
|
||
|
//!
|
||
|
//! \param group specifies the interrupt group to be acknowledged.
|
||
|
//!
|
||
|
//! The specified interrupt group is acknowledged and clears any interrupt
|
||
|
//! flag within that respective group.
|
||
|
//!
|
||
|
//! The \e group parameter must be a logical OR of the following:
|
||
|
//! \b INTERRUPT_ACK_GROUP1, \b INTERRUPT_ACK_GROUP2, \b INTERRUPT_ACK_GROUP3
|
||
|
//! \b INTERRUPT_ACK_GROUP4, \b INTERRUPT_ACK_GROUP5, \b INTERRUPT_ACK_GROUP6
|
||
|
//! \b INTERRUPT_ACK_GROUP7, \b INTERRUPT_ACK_GROUP8, \b INTERRUPT_ACK_GROUP9
|
||
|
//! \b INTERRUPT_ACK_GROUP10, \b INTERRUPT_ACK_GROUP11,
|
||
|
//! \b INTERRUPT_ACK_GROUP12.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
Interrupt_clearACKGroup(uint16_t group)
|
||
|
{
|
||
|
//
|
||
|
// Set interrupt group acknowledge bits
|
||
|
//
|
||
|
HWREGH(PIECTRL_BASE + PIE_O_ACK) = group;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Enables the PIE block.
|
||
|
//!
|
||
|
//! This function enables the vector fetching for the peripheral interrupts by
|
||
|
//! enabling the PIE block.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
Interrupt_enablePIE(void)
|
||
|
{
|
||
|
HWREGH(PIECTRL_BASE + PIE_O_CTRL) |= PIE_CTRL_ENPIE;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Disables the PIE block.
|
||
|
//!
|
||
|
//! This function disables the vector fetching for the peripheral interrupts by
|
||
|
//! disabling the PIE block. PIEACK, PIEIFR, and PIEIER registers can be
|
||
|
//! accessed even when the PIE block is disabled.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
static inline void
|
||
|
Interrupt_disablePIE(void)
|
||
|
{
|
||
|
HWREGH(PIECTRL_BASE + PIE_O_CTRL) &= ~PIE_CTRL_ENPIE;
|
||
|
}
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Initializes the PIE control registers by setting them to a known state.
|
||
|
//!
|
||
|
//! This function initializes the PIE control registers. After globally
|
||
|
//! disabling interrupts and enabling the PIE, it clears all of the PIE
|
||
|
//! interrupt enable bits and interrupt flags.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
Interrupt_initModule(void);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Initializes the PIE vector table by setting all vectors to a default
|
||
|
//! handler function.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
Interrupt_initVectorTable(void);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Enables an interrupt.
|
||
|
//!
|
||
|
//! \param interruptNumber specifies the interrupt to be enabled.
|
||
|
//!
|
||
|
//! The specified interrupt is enabled in the interrupt controller. Other
|
||
|
//! enables for the interrupt (such as at the peripheral level) are unaffected
|
||
|
//! by this function.
|
||
|
//!
|
||
|
//! The available \e interruptNumber values are supplied in
|
||
|
//! <tt>inc/hw_ints.h</tt>.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
Interrupt_enable(uint32_t interruptNumber);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
//! Disables an interrupt.
|
||
|
//!
|
||
|
//! \param interruptNumber specifies the interrupt to be disabled.
|
||
|
//!
|
||
|
//! The specified interrupt is disabled in the interrupt controller. Other
|
||
|
//! enables for the interrupt (such as at the peripheral level) are unaffected
|
||
|
//! by this function.
|
||
|
//!
|
||
|
//! The available \e interruptNumber values are supplied in
|
||
|
//! <tt>inc/hw_ints.h</tt>.
|
||
|
//!
|
||
|
//! \return None.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern void
|
||
|
Interrupt_disable(uint32_t interruptNumber);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Extern compiler intrinsic prototypes. See compiler User's Guide for details.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
extern uint16_t __disable_interrupts(void);
|
||
|
extern uint16_t __enable_interrupts(void);
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Close the Doxygen group.
|
||
|
//! @}
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
|
||
|
#endif // #ifdef __TMS320C28XX__
|
||
|
|
||
|
//*****************************************************************************
|
||
|
//
|
||
|
// Mark the end of the C bindings section for C++ compilers.
|
||
|
//
|
||
|
//*****************************************************************************
|
||
|
#ifdef __cplusplus
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#endif // INTERRUPT_H
|