📄 led_inth.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 + -