blob: ea0683306421159e577b172ed52ab49ad4e3ed70 [file] [log] [blame]
/* ----------------------------------------------------------------------------
* SAM Software Package License
* ----------------------------------------------------------------------------
* Copyright (c) 2014, 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.
* ----------------------------------------------------------------------------
*/
/** \addtogroup aic_module
*
* The Advanced Interrupt Controller (AIC) is an 8-level priority, individually
* maskable, vectored interrupt controller, providing handling of up to thirty-two interrupt sources.
*
* \section Usage
* <ul>
* <li> Each interrupt source can be enabled or disabled by using the IRQ_EnableIT() and IRQ_DisableIT()</li>
* <li> Configure the AIC interrupt to its requirements and special needs,such as priorty
* level, source type and configure the addresses of the corresponding handler for each interrupt source
* could be setting by IRQ_ConfigureIT(). </li>
* <li> Start conversion by setting ADC_CR_START in ADC_CR. </li>
* </ul>
*
* For more accurate information, please look at the AIC section of the
* Datasheet.
*
* Related files :\n
* \ref aic.c\n
* \ref irq.h\n
*/
/*@{*/
/*@}*/
/**
* \file
*
* Implementation of Advanced Interrupt Controller (AIC) controller.
*
*/
/*----------------------------------------------------------------------------
* Headers
*----------------------------------------------------------------------------*/
#include "chip.h"
#include <stdint.h>
#include <assert.h>
/*----------------------------------------------------------------------------
* Exported functions
*----------------------------------------------------------------------------*/
/**
* \brief Enables interrupts coming from the given AIC and (unique) source (ID_xxx).
*
* \param aic AIC instance.
* \param source Interrupt source to enable.
*/
static void _aic_EnableIT(Aic *aic, uint32_t source)
{
aic->AIC_SSR = AIC_SSR_INTSEL(source);
aic->AIC_IECR = AIC_IECR_INTEN;
}
/**
* \brief Disables interrupts coming from the given AIC and (unique) source (ID_xxx).
*
* \param aic AIC instance.
* \param source Interrupt source to disable.
*/
static void _aic_DisableIT(Aic *aic, uint32_t source)
{
aic->AIC_SSR = AIC_SSR_INTSEL(source);
aic->AIC_IDCR = AIC_IDCR_INTD ;
}
/**
* \brief return if the giving peripheral is H64 Matrix
*
* \param pid peripheral ID
*/
static uint8_t _isH64Matrix(uint32_t pid){
if ((pid == ID_ARM) ||
(pid == ID_XDMAC0) ||
//(pid == ID_PKCC) ||
(pid == ID_AESB) ||
(pid == ID_MPDDRC) ||
(pid == ID_VDEC) ||
(pid == ID_XDMAC1) ||
(pid == ID_LCDC) ||
(pid == ID_ISI) ||
(pid == ID_L2CC))
{
return 1;
} else {
return 0;
}
}
/**
* \brief Enables interrupts coming from the given (unique) source (ID_xxx).
*
* \param source Interrupt source to enable.
*/
void AIC_EnableIT( uint32_t source)
{
volatile unsigned int * pAicFuse = (volatile unsigned int *) REG_SFR_AICREDIR;
if(*pAicFuse)
{
_aic_EnableIT(AIC, source);
}
else
{
if (_isH64Matrix(source)) {
if ( MATRIX0->MATRIX_SPSELR[source / 32] & (1 << (source % 32)))
_aic_EnableIT(AIC, source);
else
_aic_EnableIT(SAIC, source);
} else {
if ( MATRIX1->MATRIX_SPSELR[source / 32] & (1 << (source % 32)))
_aic_EnableIT(AIC, source);
else
_aic_EnableIT(SAIC, source);
}
}
}
/**
* \brief Disables interrupts coming from the given (unique) source (ID_xxx).
*
* \param source Interrupt source to disable.
*/
void AIC_DisableIT(uint32_t source)
{
if (_isH64Matrix(source)) {
if ( MATRIX0->MATRIX_SPSELR[source / 32] & (1 << (source % 32)))
_aic_DisableIT(AIC, source);
else
_aic_DisableIT(SAIC, source);
} else {
if ( MATRIX1->MATRIX_SPSELR[source / 32] & (1 << (source % 32)))
_aic_DisableIT(AIC, source);
else
_aic_DisableIT(SAIC, source);
}
}