⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 led_inth.c

📁 OMAP1030 处理器的ARM 侧硬件测试代码 OMAP1030 是TI的双核处理器
💻 C
字号:
/*==============================================================================
            TEXAS INSTRUMENTS INCORPORATED PROPRIETARY INFORMATION

   Property of Texas Instruments. For Unrestricted Internal Use Only
   Unauthorized reproduction and/or distribution is strictly prohibited.
   This product is protected under copyright law and trade secret law 
   as an unpublished work.  
   Created 2002, (C) Copyright 2002 Texas Instruments.  All rights reserved.

   Filename       : led_intled.c

   Description    : Body file for the ARM Interrupt handler level 1

   Project        : HELEN2, OMAP1610, OMAP32

   Author         : Francis Huguenin/Arnaud Balmelle and Dayo Adeyeye
   Adapted by     : Dayo Adeyeye for Helen2 LED only.

   FUNCTIONS PROVIDED

void INTLED_InitLevel (UWORD8               IntIndex, 
                     INTLED_InterruptKind_t InterruptKind ,
                     INTLED_Priority_t      Priority,
                     INTLED_SensitiveEdge_t SensitiveEdge);

void INTLED_ResetINT(void);

void INTLED_EnableOneIT(UWORD8 IntIndex, BOOL Fiq_or_Irq);

void INTLED_DisableOneIT(UWORD8 IntIndex);

void INTLED_ValidNextInt(INTLED_InterruptKind_t Fiq_or_Irq);

UWORD8 INTLED_GetCurrentInt(BOOL Fiq_or_Irq);

==============================================================================*/

#include "led_top.h"

/*------------------------------------------------------------------------------
 NAME: INTLED_InitLevel: Add an interrupt into the Interrupt Level Registers
 DESCRIPTION : Initialize the given interrupt kind either FIQ or IRQ
               into the Interrupt Level Registers at the position defined
               by IntIndex setting its SensitiveEdge and priority
 PARAMETERS  :
   IntIndex = predefined order number is the IT position
                     into the Interrupt Level Register range 0 .. 160
   InterruptKind   = IRQ of FIQ interrupt, INTLED_FIQ or INTLED_IRQ
   SensEdge        = Define the edge triggered interrupt
                     RISING_EDGE_SENSITIVE or HIGH_LEVEL_SENSITIVE
   Priority        = Priority level of the interrupt
                     0=highest priority
 RETURN VALUE: None
 LIMITATIONS : None
------------------------------------------------------------------------------*/
void INTLED_InitLevel (UWORD8                IntIndex, 
                     INTLED_InterruptKind_t  InterruptKind,
                     INTLED_Priority_t       Priority,
                     INTLED_SensitiveEdge_t  SensitiveEdge) {
  UWORD8 section, It_index_in_section;
  volatile UWORD32* PtLevelReg; // Point to the IntIndex
   
  if(IntIndex < 32) { // First level interrupt handler
    PtLevelReg = (UWORD32*)INTLED_ILR_ADDR + IntIndex;
    *PtLevelReg = ((InterruptKind << INTLED_FIQNIRQ_POSBIT)
		   | (Priority      << INTLED_PRIORITY_POSBIT)
                   | (SensitiveEdge << INTLED_SENSITIVE_EDGE_POSBIT));
  } else {
    section             =  IntIndex/32 - 1;
    It_index_in_section =  IntIndex % 32;

    PtLevelReg = (UWORD32*)(SECTION_INDEX*section + LEV2_INTLED_ILR + 4*It_index_in_section);
    // Note irq is no more fixed 
    *PtLevelReg = ((InterruptKind << INTLED_FIQNIRQ_POSBIT)
                   | (Priority      << INTLED_PRIORITY_POSBIT)
		   | (SensitiveEdge << INTLED_SENSITIVE_EDGE_POSBIT));
		     
    if (InterruptKind == INTLED_IRQ) {
    // init irq on interrupt handler 1 with fix level and Irq
      PtLevelReg = (UWORD32*)INTLED_ILR_ADDR + LEV2_IRQ_LEDINT;
      *PtLevelReg = ((InterruptKind          << INTLED_FIQNIRQ_POSBIT)
		     | (Priority             << INTLED_PRIORITY_POSBIT)
		     | (HIGH_LEVEL_SENSITIVE << INTLED_SENSITIVE_EDGE_POSBIT));
    } else {
      PtLevelReg = (UWORD32*)INTLED_ILR_ADDR + LEV2_FIQ_LEDINT;
      *PtLevelReg = ((InterruptKind          << INTLED_FIQNIRQ_POSBIT)
		     | (Priority             << INTLED_PRIORITY_POSBIT)
		     | (HIGH_LEVEL_SENSITIVE << INTLED_SENSITIVE_EDGE_POSBIT));
    }
  }
}

/*------------------------------------------------------------------------------
 NAME        : INTLED_ResetIT
 DESCRIPTION : Reset all the pending INT, Reset INTLED level 2 and all INT
 PARAMETERS  : None
 RETURN VALUE: None
 LIMITATIONS : None
------------------------------------------------------------------------------*/
void INTLED_ResetINT(void) {
  REG32(LEV2_INTLED_OCP_CFG) = 0x2;
  while(REG32(ARMINTLED_L20_BASE_ADDR+INTLED_STATUS_OFFSET) == 0x0) {};
}

/*------------------------------------------------------------------------------
 MACRO       : INTLED_EnableOneIT: Unmask the selected interrupt
 DESCRIPTION : Unmask the given Interrupt or Enable one interrupt
 PARAMETERS  :
   Interrupt = Interrupt number(range 0..159) corresponding to the INT
               Fiq_or_Irq:  INTLED_IRQ or INTLED_FIQ
               See Interrupt Configuration above.
 RETURN VALUE: None
 LIMITATIONS : Must be called on Incoming INT
------------------------------------------------------------------------------*/
void INTLED_EnableOneIT(UWORD8 IntIndex, BOOL Fiq_or_Irq) {
  UWORD8 section, It_index_in_section;

  if(IntIndex < 32) { //Clear the ITR register and UnMask bit
    ClearBitIndex(REG32(INTLED_ITR_ADDR),IntIndex);
    ClearBitIndex(REG32(INTLED_MIR_ADDR),IntIndex);
  } else {           //Clear the ITR register and UnMask bit
    section             =  IntIndex/32 - 1;
    It_index_in_section =  IntIndex % 32;
    
    ClearBitIndex(REG32(SECTION_INDEX*section + LEV2_INTLED_ITR),It_index_in_section);
    ClearBitIndex(REG32(SECTION_INDEX*section + LEV2_INTLED_MIR),It_index_in_section);
    // UnMask IRQ INT on level 1
    
    if (Fiq_or_Irq == INTLED_IRQ)
       ClearBitIndex(REG32(INTLED_MIR_ADDR),LEV2_IRQ_LEDINT);
    else // INTLED_FIQ
       ClearBitIndex(REG32(INTLED_MIR_ADDR),LEV2_FIQ_LEDINT);
    }
}

/*------------------------------------------------------------------------------
 MACRO       : INTLED_DisableOneIT: Mask the selected interrupt
 DESCRIPTION : Mask the given Interrupt or Disable one interrupt
 PARAMETERS  :
   Interrupt = Interrupt number(range 0..159) corresponding to the INT
               See Interrupt Configuration above.
 RETURN VALUE: None
 LIMITATIONS : None
------------------------------------------------------------------------------*/
void INTLED_DisableOneIT(UWORD8 IntIndex) {
  UWORD8 section, It_index_in_section;

  if(IntIndex<32) {
    *(UWORD32*)INTLED_MIR_ADDR |= (1 << IntIndex);
  } else {
    section             =  IntIndex/32 - 1;
    It_index_in_section =  IntIndex % 32;
    *(UWORD32*)(SECTION_INDEX*section + LEV2_INTLED_MIR) |= (1 << It_index_in_section);
  }
}


/*-----------------------------------------------------------------------
 MACRO : INTLED_ValidNextInt: Validate the next INT depending on the current
 DESCRIPTION : Acknowledge the active interrupt and return the origin of the 
               interrupt (binary format) by reading the Source IRQ/FIQ register.
               In case of sensitive edge Interrupt, the IT register bit is
               deactivated when reading the Source IRQ/FIQ register otherwise,
               it's reset when the corresponding interrupt becomes inactive.
               After processing the Interrupt FIQ/IRQ sequence,
   Set the dedicated bit NEW_IQ_AGR/NEW_FIQ/AGR of Control Register
   in order to reset IRQ Output and Source IRQ/FIQ register and thus,
   to allow a new IRQ/FIQ catching.
 PARAMETERS  : Fiq_or_Irq: Identify the kind of interrupt: either FIQ/IRQ
 RETURN VALUE: None
 LIMITATIONS : Must be called after the end of IT treatment to enable
               a new interrupt catching
-----------------------------------------------------------------------*/
void INTLED_ValidNextInt (INTLED_InterruptKind_t Fiq_or_Irq) {
  UWORD16 ActivIntIndex1, ActivIntIndex2;

  if (Fiq_or_Irq == INTLED_IRQ)
     ActivIntIndex1=(*(UWORD8 *)(INTLED_SIR_IRQ_ADDR)) & 0x1F;
  else // INTLED_FIQ
     ActivIntIndex1=(*(UWORD8 *)(INTLED_SIR_FIQ_ADDR)) & 0x1F;
     
  //Test if the interrupt comes from the second handler
  if (ActivIntIndex1 == LEV2_IRQ_LEDINT) { //Valid next Irq on handler2
     ActivIntIndex2 = (*(UWORD8 *)(LEV2_INTLED_SIR_IRQ)) & 0x1F;
     ActivIntIndex2 = ActivIntIndex2 + 32;
     SetBitIndex(REG32(LEV2_INTLED_ICR),INTLED_IRQ);
  }
   
  if (ActivIntIndex1 == LEV2_FIQ_LEDINT) { //Valid next Fiq on handler2
     ActivIntIndex2 = (*(UWORD8 *)(LEV2_INTLED_SIR_FIQ)) & 0x1F;
     ActivIntIndex2 = ActivIntIndex2 + 32;
     SetBitIndex(REG32(LEV2_INTLED_ICR),INTLED_FIQ);
  }
  
  //Valid next Irq on handler1
  SetBitIndex(REG32(INTLED_ICR_ADDR),Fiq_or_Irq);
}

/*------------------------------------------------------------------------------
 MACRO       : INTLED_GetCurrentInt, Get all the pending interrupts
 DESCRIPTION : Get the current It and valid the next one
 PARAMETERS  : Fiq_or_Irq:  INTLED_IRQ or INTLED_FIQ
 RETURN VALUE: Number of the active and acknowledged Interrupt
 LIMITATIONS : Must be called on Incoming IT
------------------------------------------------------------------------------*/
UWORD8 INTLED_GetCurrentInt (BOOL Fiq_or_Irq) {
  UWORD8 ActivIntIndex;

  if (Fiq_or_Irq == INTLED_IRQ)
    ActivIntIndex=(*(UWORD8 *)(INTLED_SIR_IRQ_ADDR)) & 0x1F;
  else  // INTLED_FIQ
    ActivIntIndex=(*(UWORD8 *)(INTLED_SIR_FIQ_ADDR)) & 0x1F;
     
  //Test if the interrupt comes from the second handler
  if (ActivIntIndex==LEV2_IRQ_LEDINT) {
    ActivIntIndex=(*(UWORD32 *)(LEV2_INTLED_SIR_IRQ)) & 0x7F;
    ActivIntIndex=ActivIntIndex+32;
  }
   
  if (ActivIntIndex==LEV2_FIQ_LEDINT) {
    ActivIntIndex=(*(UWORD32 *)(LEV2_INTLED_SIR_FIQ)) & 0x7F;
    ActivIntIndex=ActivIntIndex+32;
  }
  
  return(ActivIntIndex);
}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -