/**HEADER********************************************************************
* 
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
* Copyright (c) 2004-2008 Embedded Access Inc.;
* All Rights Reserved
*
* Copyright (c) 1989-2008 ARC International;
* All Rights Reserved
*
*************************************************************************** 
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED 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 FREESCALE OR ITS 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.
*
**************************************************************************
*
* $FileName: int_ctrl_mcf5445.c$
* $Version : 3.0.2.0$
* $Date    : Jun-11-2009$
*
* Comments:
*
*   This file contains definitions for the MFC5445 interrupt controller
*   functions.
*
*END************************************************************************/

#include "mqx_inc.h"
#include "bsp.h"

#if 0

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : compute_icntl_registers
* Returned Value  : uint_32
* Comments        :
*   Compute which registers to touch for the given interrupt number
*
*END*---------------------------------------------------------------------*/

static boolean compute_icntl_registers
   (
      // [IN} Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq,

      // [OUT} Interrupt control register
      volatile uchar _PTR_ _PTR_    ictlr,

      // [OUT} Interrupt mask register
      volatile uint_32 _PTR_ _PTR_  maskr,

      // [OUT} Interrupt mask register bit
      uint_32_ptr                   bit,

      // [OUT} Interrupt clear bit 0
      /*uint_32_ptr                   clear*/
   )
{ /* Body */

   VMCF54XX_ICTRL0_STRUCT_PTR ictrl0;
   VMCF54XX_ICTRL1_STRUCT_PTR ictrl1;

   if (irq >= PSP_INT_FIRST_EXTERNAL) {
      uint_32 index = irq - PSP_INT_FIRST_EXTERNAL;

      if (index < 32) {
         ictrl0 = PSP_GET_ICTRL0_BASE();
         *ictlr = &ictrl0->ICR[index];
         *maskr = &ictrl0->ICTRL.IMRL;
         *bit = 1 << index;
         //*clear = 1;
         return TRUE;
      } /* Endif */

      if (index < 64) {
         ictrl0 = PSP_GET_ICTRL0_BASE();
         *ictlr = &ictrl0->ICR[index];
         *maskr = &ictrl0->ICTRL.IMRH;
         *bit = 1 << (index-32);
         //*clear = 0;
         return TRUE;
      } /* Endif */

      if (index < 96){
         index = irq - MCF5445_ICTRL1_BASEx;
         ictrl1 = PSP_GET_ICTRL1_BASE();
         *ictlr = &ictrl1->ICR[index];
         *maskr = &ictrl1->ICTRL.IMRL;
         *bit = 1 << (index - 64);
         //*clear = &ictrl1->ICTRL.IMRL;
		 
         return TRUE;
      } /* Endif */

      if (index < 128){
         index = irq - MCF5445_ICTRL1_BASEx;
         ictrl1 = PSP_GET_ICTRL1_BASE();
         *ictlr = &ictrl1->ICR[index];
         *maskr = &ictrl1->ICTRL.IMRH;
         *bit = 1 << (index - 96);
         //*clear = 1;
         return TRUE;
      } /* Endif */

   } /* Endif */

   return FALSE;

} /* Endbody */
#endif

/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5445_int_init
* Returned Value  : uint_32
* Comments        :
*   Initialize a specific interrupt in the proper interrupt controller
*
*END*---------------------------------------------------------------------*/

uint_32 _mcf5445_int_init
   (
      // [IN} Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq,

      // [IN} Interrupt priority level
      _int_level                level,

      // [IN} Unmask the interrupt now?
      boolean                   unmask
   )
{
    _mqx_int idx;
    uint_32 temp;

    if (irq >= PSP_INT_FIRST_EXTERNAL) {
        idx = irq - PSP_INT_FIRST_EXTERNAL;
   
        temp = _psp_get_sr();
        _psp_set_sr(temp | 0x0700);
        
        if (idx < 64) {
            PSP_GET_ICTRL0_BASE()->ICR[idx] = level & 7;
            
            if (unmask)
                PSP_GET_ICTRL0_BASE()->CIMR = MCF54XX_ICTRL_IMR_N(idx);
            else
                PSP_GET_ICTRL0_BASE()->SIMR = MCF54XX_ICTRL_IMR_N(idx);
        }
        else {
            idx -= 64;
            PSP_GET_ICTRL1_BASE()->ICR[idx] = level & 7;
            
            if (unmask)
                PSP_GET_ICTRL1_BASE()->CIMR = MCF54XX_ICTRL_IMR_N(idx);
            else
                PSP_GET_ICTRL1_BASE()->SIMR = MCF54XX_ICTRL_IMR_N(idx);
        }
        
        _psp_set_sr(temp);
    
        return MQX_OK;
    }
    
    return MQX_INVALID_PARAMETER;

#if 0
   volatile uchar _PTR_   ictrl;
   volatile uint_32 _PTR_ maskr;
   uint_32 bit, /*clear, */mask;
   uint_32 temp;

   if (compute_icntl_registers(irq,&ictrl,&maskr,&bit/*,&clear*/)) {
      temp = _psp_get_sr();
      _psp_set_sr(temp | 0x0700);
      mask = *maskr; // & ~clear;
      if (!unmask) {
         *maskr = mask | bit;
      } /* Endif */
      *ictrl = level & 7;
      if (unmask) {
         *maskr = mask & ~bit;
      } /* Endif */
      _psp_set_sr(temp);
      return MQX_OK;
   } /* Endif */

   return MQX_INVALID_PARAMETER;
#endif
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5445_int_unmask
* Returned Value  : uint_32
* Comments        :
*   Clear the mask bit that inhibits the interrupt
*
*END*---------------------------------------------------------------------*/

uint_32 _mcf5445_int_unmask
   (
      // [IN} Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq
   )
{ /* Body */
    _mqx_int idx;

    if (irq >= PSP_INT_FIRST_EXTERNAL) {
        idx = irq - PSP_INT_FIRST_EXTERNAL;
   
        if (idx < 64) {
            PSP_GET_ICTRL0_BASE()->CIMR = MCF54XX_ICTRL_IMR_N(idx);
        }
        else {
            PSP_GET_ICTRL1_BASE()->CIMR = MCF54XX_ICTRL_IMR_N(idx - 64);
        }
    
        return MQX_OK;
    }
    
    return MQX_INVALID_PARAMETER;
} /* Endbody */


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5445_int_mask
* Returned Value  : uint_32
* Comments        :
*   Set the mask bit that inhibits the interrupt
*
*END*---------------------------------------------------------------------*/

uint_32 _mcf5445_int_mask
   (
      // [IN} Interrupt number
      PSP_INTERRUPT_TABLE_INDEX irq
   )
{
    _mqx_int idx;

    if (irq >= PSP_INT_FIRST_EXTERNAL) {
        idx = irq - PSP_INT_FIRST_EXTERNAL;
   
        if (idx < 64) {
            PSP_GET_ICTRL0_BASE()->SIMR = MCF54XX_ICTRL_IMR_N(idx);
        }
        else {
            PSP_GET_ICTRL1_BASE()->SIMR = MCF54XX_ICTRL_IMR_N(idx - 64);
        }
    
        return MQX_OK;
    }
    
    return MQX_INVALID_PARAMETER;
}


/*FUNCTION*-----------------------------------------------------------------
*
* Function Name   : _mcf5445_int_mask_all
* Returned Value  : void
* Comments        :
*   Mask all external interrupts
*
*END*---------------------------------------------------------------------*/

void  _mcf5445_int_mask_all
   (
      void
   )
{ /* Body */

   PSP_GET_ICTRL0_BASE()->SIMR = MCF54XX_ICTRL_IMR_ALL;
   PSP_GET_ICTRL1_BASE()->SIMR = MCF54XX_ICTRL_IMR_ALL;

} /* Endbody */

/* EOF */
