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

📄 intr.c

📁 支持三星原产的S3C2413开发板
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File: interrupt.c
//
//  This file implement major part of interrupt module for S3C3210X SoC.
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <oal.h>
#include <s3c2413.h>
#include <s3c2413_intr.h>
#include <intr.h>
#include "bsp_cfg.h"
#include <drv_glob.h>
 
//extern volatile UINT32 g_oalLastSysIntr; 

// debug message definition.
#define DBG_ON 0
#define DBG_TCH 0
#define DBG_AUDIO 0

#define INTR_SET1	0
#define INTR_SET2	1
#define INTR_SELECT	INTR_SET1	// Not fixed in alpha BSP(recommand set2).
//------------------------------------------------------------------------------
//
//  Globals:  g_pIntrRegs/g_pPortRegs
//
//  The global variables are storing virual address for interrupt and port
//  registers for use in interrupt handling to avoid possible time consumig
//  call to OALPAtoVA function.
//
volatile S3C2413_INTR_REG *g_pIntrRegs; 
static S3C2413_IOPORT_REG *g_pPortRegs;
static volatile S3C2413_ADC_REG		*g_pADCRegs;
static volatile S3C2413_PWM_REG	*g_pPWMRegs;
#ifdef DVS_EN
static S3C2413_LCD_REG	*g_pLCDRegs;
#endif

#ifdef DVS_EN
	BOOL	VSYNCINTR;
	BOOL	CurrStateIdle;
	extern volatile BOOL IDLEflag;
	extern DWORD dwCurrentidle;

	volatile int CurrentState = Active;

	extern DWORD dwPrevTotalTick1000;
	extern DWORD dwPrevTotalTick100;

	extern DWORD dwPrevIdleTick1000;
	extern DWORD dwPrevIdleTick100;

	extern DWORD dwPercentIdle1000;
	extern DWORD dwPercentIdle100;

	extern void DVS_ON(void);
	extern void DVS_OFF(void);
	extern void ChangeVoltage(int);
	extern int GetCurrentVoltage(void);
	extern void CLKDIV124();
	extern void CLKDIV144();
#endif
//  Function pointer to profiling timer ISR routine.
//
PFN_PROFILER_ISR g_pProfilerISR = NULL;
 

//------------------------------------------------------------------------------
//
//  Function:  OALIntrInit
//
//  This function initialize interrupt mapping, hardware and call platform
//  specific initialization.
//
BOOL OALIntrInit()
{
	BOOL rc = FALSE;
	
	OALMSG( OAL_FUNC&&OAL_INTR, (L"+OALInterruptInit\r\n") );

	// Initialize interrupt mapping
	OALIntrMapInit();

	g_pADCRegs		= (S3C2413_ADC_REG*)OALPAtoVA(S3C2413_BASE_REG_PA_ADC, FALSE);
	g_pPWMRegs	= (S3C2413_PWM_REG*)OALPAtoVA(S3C2413_BASE_REG_PA_PWM, FALSE);
	
	// First get uncached virtual addresses
	g_pIntrRegs = (S3C2413_INTR_REG*)OALPAtoVA(
		S3C2413_BASE_REG_PA_INTR, FALSE
	);
	g_pPortRegs = (S3C2413_IOPORT_REG*)OALPAtoVA(
		S3C2413_BASE_REG_PA_IOPORT, FALSE
	);

#ifdef DVS_EN    
    g_pLCDRegs = (S3C2413_LCD_REG *)OALPAtoVA(
    S3C2413_BASE_REG_PA_LCD, FALSE
    );
#endif    
	// Mask and clear external interrupts
	OUTREG32(&g_pPortRegs->EINTMASK, 0xFFFFFFFF);
	OUTREG32(&g_pPortRegs->EINTPEND, 0xFFFFFFFF);

	// Mask and clear internal interrupts
	OUTREG32(&g_pIntrRegs->INTMSK, 0xFFFFFFFF);
	OUTREG32(&g_pIntrRegs->SRCPND, 0xFFFFFFFF);

	// S3C2413 developer notice (page 4) warns against writing a 1 to any
	// 0 bit field in the INTPND register.  Instead we'll write the INTPND
	// value itself.
	OUTREG32(&g_pIntrRegs->INTPND, INREG32(&g_pIntrRegs->INTPND));

#ifdef OAL_BSP_CALLBACKS
	// Give BSP change to initialize subordinate controller
	rc = BSPIntrInit();
#else
	rc = TRUE;
#endif

	OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALInterruptInit(rc = %d)\r\n", rc));
	return rc;
}



//------------------------------------------------------------------------------
//
//  Function:  OALIntrRequestIrqs
//
//  This function returns IRQs for CPU/SoC devices based on their
//  physical address.
//
BOOL OALIntrRequestIrqs(DEVICE_LOCATION *pDevLoc, UINT32 *pCount, UINT32 *pIrqs)
{
	BOOL rc = FALSE;

	OALMSG(OAL_INTR&&OAL_FUNC, (
		L"+OALIntrRequestIrqs(0x%08x->%d/%d/0x%08x/%d, 0x%08x, 0x%08x)\r\n",
		pDevLoc, pDevLoc->IfcType, pDevLoc->BusNumber, pDevLoc->LogicalLoc,
		pDevLoc->Pin, pCount, pIrqs
	));

	// This shouldn't happen
	if (*pCount < 1) goto cleanUp;

#ifdef OAL_BSP_CALLBACKS
	rc = BSPIntrRequestIrqs(pDevLoc, pCount, pIrqs);
#endif	

cleanUp:		
	OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrRequestIrqs(rc = %d)\r\n", rc));
	return rc;
}


//------------------------------------------------------------------------------
//
//  Function:  OALIntrEnableIrqs
//

BOOL OALIntrEnableIrqs(UINT32 count, const UINT32 *pIrqs)
{
	BOOL rc = TRUE;
	UINT32 i, mask, IntPendVal;

	OALMSG(OAL_INTR&&OAL_FUNC, (
		L"+OALIntrEnableIrqs(%d, 0x%08x)\r\n", count, pIrqs
	));

	for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
		IntPendVal = pIrqs[i];
#else
		// Give BSP chance to enable IntPendVal on subordinate interrupt controller
		IntPendVal = BSPIntrEnableIrq(pIrqs[i]);
#endif
		if (IntPendVal == OAL_INTR_IRQ_UNDEFINED) continue;

		
		// Depending on IRQ number use internal or external mask register
		if (IntPendVal <= IRQ_ADC) {
			// Use interrupt mask register
			RETAILMSG(DBG_ON,(TEXT("OALIntrEnableIrqs:INTR#[%d].\r\n"), IntPendVal));
			CLRREG32(&g_pIntrRegs->INTMSK, 1<<IntPendVal);

			/*if (IntPendVal==IRQ_ADC)
			{	
				RETAILMSG(DBG_ON,(TEXT("OALIntrEnableIrqs:TOUCH CHANGED\r\n")));			
				g_pIntrRegs->INTMSK &= ~(BIT_ADC);
				g_pIntrRegs->INTSUBMSK &= ~(BIT_SUB_TC);				
			}
			else*/ if (IntPendVal == IRQ_EINT1)
			{
				RETAILMSG(1,(TEXT("OALIntrEnableIrqs:IRQ_EINT1\r\n")));
// org
//				OUTREG32(&g_pPortRegs->EINTPEND, 1<<IntPendVal);
//				CLRREG32(&g_pPortRegs->EINTMASK, 1<<IRQ_EINT1);
//				g_pIntrRegs->INTMSK &= ~(IRQ_EINT1);

				g_pPortRegs->EINTMASK &= ~( BIT_EINT1);
				g_pIntrRegs->INTMSK &= ~(BIT_EINT1);
				
//				RETAILMSG(0,(TEXT("INTMSK : %x, EINTPEND : %x, EINTMASK : %x\n"), 
//					g_pIntrRegs->INTMSK, g_pPortRegs->EINTPEND, g_pPortRegs->EINTMASK));
			}
			else if (IntPendVal == IRQ_EINT0)
			{
//				RETAILMSG(1,(TEXT("OALIntrEnableIrqs:IRQ_EINT0\r\n")));

				g_pPortRegs->EINTMASK &= ~( BIT_EINT0);
				g_pIntrRegs->INTMSK &= ~(BIT_EINT0);
				
				//RETAILMSG(0,(TEXT("INTMSK : %x, EINTPEND : %x, EINTMASK : %x\n"), 
				//g_pIntrRegs->INTMSK, g_pPortRegs->EINTPEND, g_pPortRegs->EINTMASK));
			}

			else if (IntPendVal==IntPendVal - IRQ_EINT4 + 40)
			{	
				RETAILMSG(1,(TEXT("OALIntrEnableIrqs:EINT0 is enable.\r\n")));			
				g_pIntrRegs->INTMSK &= ~(BIT_EINT0);
				g_pIntrRegs->INTSUBMSK &= ~(BIT_SUB_TC);	
				g_pPortRegs->EINTMASK &=  (0xfffffe);
			}
			
		} else if (IntPendVal <= IRQ_EINT7) {
			// Use external mask register
			CLRREG32(&g_pIntrRegs->INTMSK, BIT_EINT4_7);
			CLRREG32(&g_pPortRegs->EINTMASK, 1<<(IntPendVal - IRQ_EINT4 + 4));
		} else if (IntPendVal <= IRQ_EINT23) {
			// Use external mask register
			mask = 1<<(IntPendVal - IRQ_EINT4 + 4);
			OUTREG32(&g_pPortRegs->EINTPEND, mask);
			CLRREG32(&g_pPortRegs->EINTMASK, mask);
			mask = BIT_EINT8_23;
			if ((INREG32(&g_pIntrRegs->INTPND) & mask) != 0) {
				OUTREG32(&g_pIntrRegs->INTPND, mask);
			}
			CLRREG32( &g_pIntrRegs->INTMSK, BIT_EINT8_23);
		} 

		else
		{
			rc = FALSE;
		}
	}		

	OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrEnableIrqs(rc = %d)\r\n", rc));
	return rc;
	
}



//------------------------------------------------------------------------------
//
//  Function:  OALIntrDisableIrqs
//

VOID OALIntrDisableIrqs(UINT32 count, const UINT32 *pIrqs)
{
	UINT32 i, mask, IntPendVal;

	OALMSG(OAL_INTR&&OAL_FUNC, (
		L"+OALIntrDisableIrqs(%d, 0x%08x)\r\n", count, pIrqs
	));

	for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
		IntPendVal = pIrqs[i];
#else
		// Give BSP chance to disable IntPendVal on subordinate interrupt controller
		IntPendVal = BSPIntrDisableIrq(pIrqs[i]);
		if (IntPendVal == OAL_INTR_IRQ_UNDEFINED) continue;
#endif
		// Depending on IRQ number use internal or external mask register
		if (IntPendVal <= IRQ_ADC) {
			// Use interrupt mask register
			mask = 1<<IntPendVal;
			SETREG32(&g_pIntrRegs->INTMSK, mask);
		/*	RETAILMSG(DBG_ON,(TEXT("OALIntrDisableIrqs:INTR#[%d].\r\n"), IntPendVal));
			
			if (IntPendVal==IRQ_ADC)
			{	
				g_pIntrRegs->INTMSK |= (BIT_ADC);
				g_pIntrRegs->INTSUBMSK |= (BIT_SUB_TC);				
				RETAILMSG(DBG_ON,(TEXT("OALIntrDisableIrqs:TOUCH CHANGED\r\n")));
			}*/
			if (IntPendVal==IRQ_EINT0)
			{	
				g_pIntrRegs->INTMSK |= (BIT_EINT0);
				g_pIntrRegs->INTSUBMSK |= (BIT_SUB_TC);				
				RETAILMSG(DBG_ON,(TEXT("OALIntrDisableIrqs:TOUCH CHANGED\r\n")));
			}
		} 
		else if (IntPendVal <= IRQ_EINT23) {
			// Use external mask register
			mask = 1<<(IntPendVal - IRQ_EINT4 + 4);
			SETREG32(&g_pPortRegs->EINTMASK, mask);
		}
	}

	OALMSG(OAL_INTR&&OAL_FUNC, (L"-OALIntrDisableIrqs\r\n"));
}




//------------------------------------------------------------------------------
//
//  Function:  OALIntrDoneIrqs
//

VOID OALIntrDoneIrqs(UINT32 count, const UINT32 *pIrqs)
{
	UINT32 i, mask, IntPendVal;

	OALMSG(OAL_INTR&&OAL_VERBOSE, (
		L"+OALIntrDoneIrqs(%d, 0x%08x)\r\n", count, pIrqs
	));

	for (i = 0; i < count; i++) {
#ifndef OAL_BSP_CALLBACKS
		IntPendVal = pIrqs[i];
#else
		// Give BSP chance to finish IntPendVal on subordinate interrupt controller
		IntPendVal = BSPIntrDoneIrq(pIrqs[i]);
#endif	
		// Depending on IRQ number use internal or external mask register

⌨️ 快捷键说明

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