blob: 1e61aa12e63c1f63bb946bc99bf4d6a17c9d9677 [file] [log] [blame]
/* ----------------------------------------------------------------------------
* ATMEL Microcontroller Software Support
* ----------------------------------------------------------------------------
* Copyright (c) 2008, Atmel Corporation
*
* All rights reserved.
*
* 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 disclaimer below.
*
* Atmel's name may not be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
* DISCLAIMED. IN NO EVENT SHALL ATMEL 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.
* ----------------------------------------------------------------------------
*/
//------------------------------------------------------------------------------
// Headers
//------------------------------------------------------------------------------
#include "board.h"
#include "irq.h"
#include "exceptions.h"
#include <utility/trace.h>
/// The index of IRQ handler in the exception table
#define NVIC_IRQ_HANDLER_INDEX 16
//------------------------------------------------------------------------------
// Global functions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
/// Configures an interrupt in the NVIC. The interrupt is identified by its
/// source (AT91C_ID_xxx) and is configured to a specified priority and
/// interrupt handler function. priority is the value that will be put in NVIC_IPRx
/// and the function address will be set in "ExceptionTable". The parameter priority
/// will include the preemptionPriority and the subPriority, where the subPriority
/// defined in the B[7:0] of the parameter "priority", and the preemptionPriority defined
/// in the B[15:8] of the parameter "priority".
/// The interrupt is disabled before configuration, so it is useless
/// to do it before calling this function. When NVIC_ConfigureIT returns, the
/// interrupt will always be disabled and cleared; it must be enabled by a
/// call to NVIC_EnableIT().
/// \param source Interrupt source to configure.
/// \param priority Pre-emption priority (B[15:8] )+ subPriority (B[7:0])
/// \param handler Interrupt handler function.
//------------------------------------------------------------------------------
void IRQ_ConfigureIT(
unsigned int source,
//unsigned int preemptionPriority,
//unsigned int subPriority,
unsigned int priority,
IntFunc handler)
{
unsigned int priGroup = __NVIC_PRIO_BITS;
unsigned int nPre = 7 - priGroup;
unsigned int nSub = priGroup + 1;
unsigned int preemptionPriority;
unsigned int subPriority;
unsigned int IRQpriority;
preemptionPriority = (priority & 0xff00) >> 8;
subPriority = (priority & 0xff);
// Disable the interrupt first
NVIC_DisableIRQ((IRQn_Type)source);
// Clear any pending status
NVIC_ClearPendingIRQ((IRQn_Type)source);
// Configure interrupt handler
//if (handler == 0) handler = IrqHandlerNotUsed;
// GetExceptionTable()[NVIC_IRQ_HANDLER_INDEX + source] = handler;
if (subPriority >= (0x01 << nSub))
subPriority = (0x01 << nSub) - 1;
if (preemptionPriority >= (0x01 << nPre))
preemptionPriority = (0x01 << nPre) - 1;
IRQpriority = (subPriority | (preemptionPriority << nSub));
NVIC_SetPriority((IRQn_Type)source, IRQpriority);
}
//------------------------------------------------------------------------------
/// Enables interrupt coming from the given (unique) source (AT91C_ID_xxx).
/// \param source Interrupt source to enable.
//------------------------------------------------------------------------------
void IRQ_EnableIT(unsigned int source)
{
NVIC_EnableIRQ((IRQn_Type)source);
}
//------------------------------------------------------------------------------
/// Disables interrupt coming from the given (unique) source (AT91C_ID_xxx).
/// \param source Interrupt source to disable.
//------------------------------------------------------------------------------
void IRQ_DisableIT(unsigned int source)
{
NVIC_DisableIRQ((IRQn_Type)source);
}
//------------------------------------------------------------------------------
/// Set interrupt pending bit from the given (unique) source (AT91C_ID_xxx).
/// \param source Interrupt source to set.
//------------------------------------------------------------------------------
void NVIC_SetPending(unsigned int source)
{
NVIC_SetPendingIRQ((IRQn_Type)source);
}
//------------------------------------------------------------------------------
/// Clear interrupt pending bit from the given (unique) source (AT91C_ID_xxx).
/// \param source Interrupt source to clear.
//------------------------------------------------------------------------------
void NVIC_ClrPending(unsigned int source)
{
NVIC_ClearPendingIRQ((IRQn_Type)source);
}
#if !defined(USE_CMSIS_on)
//------------------------------------------------------------------------------
/// Use the Software Trigger Interrupt Register to pend an interrupt.
/// \param source Interrupt source to trigger.
//------------------------------------------------------------------------------
void NVIC_Swi(unsigned int source)
{
AT91C_BASE_NVIC->NVIC_STIR = source;
}
#endif