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

📄 off.c

📁 SAMSUNG S3C6410 CPU BSP for winmobile6
💻 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.
//
// NOTE: stubs are being used - this isn't done

#include <windows.h>
#include <bsp.h>
#include <pmplatform.h>

//#define SLEEP_AGING_TEST

// Vector Address Table Initialize Function in "\common\intr\intr.c"
extern void VICTableInit(void);

#if	(CPU_NAME == S3C6410)
static void InitializeOTGCLK(void);

static void Delay(UINT32 count)
{
	volatile int i, j = 0;
	volatile static int loop = S3C6410_ACLK/100000;
	
	for(;count > 0;count--)
		for(i=0;i < loop; i++) { j++; }
}
#endif

#ifdef DVS_EN
// DVS control function in "\common\timer\dvs.c"
extern void ChangeDVSLevel(SYSTEM_ACTIVE_LEVEL eLevel);
#endif


static UINT32 g_aSleepSave_VIC[100];
static UINT32 g_aSleepSave_GPIO[100];
static UINT32 g_aSleepSave_SysCon[100];
static UINT32 g_aSleepSave_DMACon0[100];
static UINT32 g_aSleepSave_DMACon1[100];
static UINT32 g_aSleepSave_SDMACon0[100];
static UINT32 g_aSleepSave_ONENANDCon0[20];
static UINT32 g_aSleepSave_ONENANDCon1[20];

static UINT32 g_LastWakeupStatus = 0;

static void OEMInitializeSystemTimer(UINT32 msecPerSysTick, UINT32 countsPerMSec, UINT32 countsMargin)
{
	UINT32 countsPerSysTick;
	volatile S3C6410_PWM_REG *pPWMReg;

	// Validate Input parameters
	countsPerSysTick = msecPerSysTick * countsPerMSec;

	// Initialize S3C6410 Timer
	pPWMReg = (S3C6410_PWM_REG*)OALPAtoUA(S3C6410_BASE_REG_PA_PWM);

	// Set Prescaler 1 (Timer2,3,4)
	pPWMReg->TCFG0 = (pPWMReg->TCFG0 & ~(0xff<<8)) | ((SYS_TIMER_PRESCALER-1)<<8);

	// Set Divider MUX for Timer4
	switch(SYS_TIMER_DIVIDER)
	{
	case 1:
		pPWMReg->TCFG1 = (pPWMReg->TCFG1 & ~(0xf<<16)) | (0<<16);
		break;
	case 2:
		pPWMReg->TCFG1 = (pPWMReg->TCFG1 & ~(0xf<<16)) | (1<<16);
		break;
	case 4:
		pPWMReg->TCFG1 = (pPWMReg->TCFG1 & ~(0xf<<16)) | (2<<16);
		break;
	case 8:
		pPWMReg->TCFG1 = (pPWMReg->TCFG1 & ~(0xf<<16)) | (3<<16);
		break;
	case 16:
		pPWMReg->TCFG1 = (pPWMReg->TCFG1 & ~(0xf<<16)) | (4<<16);
		break;
	default:
		pPWMReg->TCFG1 = (pPWMReg->TCFG1 & ~(0xf<<16)) | (0<<16);
		break;
	}

	// Set Timer4 Count Buffer Register
	pPWMReg->TCNTB4 = countsPerSysTick;

	// Timer4 Clear Interrupt Pending
	//pPWMReg->TINT_CSTAT |= (1<<9);	// Do not use OR/AND operation on TINTC_CSTAT
	pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(pPWMReg->TINT_CSTAT) | TIMER4_PENDING_CLEAR;

	// Timer4 Interrupt Enable
	//pPWMReg->TINT_CSTAT |= (1<<4);	// Do not use OR/AND operation on TINTC_CSTAT
	pPWMReg->TINT_CSTAT = TINT_CSTAT_INTMASK(pPWMReg->TINT_CSTAT) | TIMER4_INTERRUPT_ENABLE;

	// Start Timer4 in Auto Reload mode (Fixed Tick!!!)
	pPWMReg->TCON &= ~(0x7<<20);

	pPWMReg->TCON |= (1<<21);			// Update TCNTB4
	pPWMReg->TCON &= ~(1<<21);

	pPWMReg->TCON |= (1<<22)|(1<<20);	// Auto-reload Mode, Timer4 Start
}

static void S3C6410_WakeUpSource_Configure(void)
{
	volatile S3C6410_SYSCON_REG *pSysConReg;
	volatile S3C6410_GPIO_REG *pGPIOReg;
#ifdef	SLEEP_AGING_TEST
	volatile S3C6410_RTC_REG *pRTCReg;
#endif

	pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE);
	pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
#ifdef	SLEEP_AGING_TEST
	pRTCReg = (S3C6410_RTC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_RTC, FALSE);
#endif

	// Wake Up Source Mask
	pSysConReg->PWR_CFG = (pSysConReg->PWR_CFG & ~(0x1FF80))
							|(1<<16)	// MMC2		(Disabled, Only for Stop)
							|(1<<15)	// MMC1		(Disabled, Only for Stop)
							|(1<<14)	// MMC0		(Disabled, Only for Stop)
							|(1<<13)	// HSI		(Disabled)
							|(1<<12)	// Touch		(Disabled, Only for Stop)
#ifdef	SLEEP_AGING_TEST
							|(0<<11)	// RTC Tick	(Enabled)
#else
							|(1<<11)	// RTC Tick	(Disabled)
#endif
							|(0<<10)	// RTC ALARM	(Enabled)
							|(1<<9)		// MSM		(Disabled)
#ifdef	REMOVE_KBD_WAKEUP_SRC		// Remove Keypad I/F from wake up source. if keyboard driver is not loaded
							|(1<<8)		// Keypad		(Disabled)
#else
							|(0<<8)		// Keypad		(Enabled)
#endif
							|(1<<7);		// Battery Fault	(Disabled)

	//-----------------
	// External Interrupt
	//-----------------
	// Power Button EINT[11] (GPN[11] is Retention Port)
	pGPIOReg->GPNCON = (pGPIOReg->GPNCON & ~(0x3<<22)) | (0x2<<22);	// GPN[11] as EINT[11]

	pSysConReg->EINT_MASK = 0x0FFFFFFF;		// Mask All EINT Wake Up Source at Sleep
	pSysConReg->EINT_MASK &= ~(1<<11);		// Enable EINT[11] as Wake Up Source at Sleep

	//-----------------
	// Keypad I/F
	//-----------------
#if	(CPU_NAME == S3C6400)
	pGPIOReg->GPKCON1 = 0x33333333;	// GPK[15:8] -> Keypad ROW[7:0]
	pGPIOReg->GPLCON0 = 0x33333333;		// GPL[7:0] -> Keypad COL[7:0]
#endif

	//-----------------
	// RTC Tick
	//-----------------
#ifdef	SLEEP_AGING_TEST
	pRTCReg->TICCNT = 0x4000;	// 0.5 sec @ 32.768KHz
	pRTCReg->RTCCON |= (1<<8);	// Tick Timer Enable
#endif

	// TODO: WAKEUP_STAT is set before Sleep ???
	// Clear All Wake Up Status bits
	pSysConReg->WAKEUP_STAT = 0xfff;
}

static void S3C6410_WakeUpSource_Detect(void)
{
	volatile S3C6410_SYSCON_REG *pSysConReg;
	volatile S3C6410_GPIO_REG *pGPIOReg;
#ifdef	SLEEP_AGING_TEST
	volatile S3C6410_RTC_REG *pRTCReg;
#endif

	pSysConReg = (S3C6410_SYSCON_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_SYSCON, FALSE);
	pGPIOReg = (S3C6410_GPIO_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_GPIO, FALSE);
#ifdef	SLEEP_AGING_TEST
	pRTCReg = (S3C6410_RTC_REG *)OALPAtoVA(S3C6410_BASE_REG_PA_RTC, FALSE);
#endif

	g_LastWakeupStatus = pSysConReg->WAKEUP_STAT;

	switch(g_LastWakeupStatus)
	{
	case 0x1:	// External Interrupt
		//pSysConReg->WAKEUP_STAT = 0x1;	// Clear EINT_WAKEUP State Bit
		if (pGPIOReg->EINT0PEND&(1<<11))		// Power Button : EINT[11]
		{
			g_oalWakeSource = SYSWAKE_POWER_BUTTON;	// OEMWAKE_EINT11;
			pGPIOReg->EINT0PEND = (1<<11);	// Clear Pending (Power Button Driver No Need to Handle Wake Up Interrupt)
		}
		else
		{
			// TODO: To Be implemented...
			g_oalWakeSource = SYSWAKE_UNKNOWN;
		}
		break;
	case 0x2:	// RTC Alarm
		g_oalWakeSource = OEMWAKE_RTC_ALARM;
		//pSysConReg->WAKEUP_STAT = 0x2;		// Clear RTC_ALARM_WAKEUP State Bit
		break;
	case 0x4:	// RTC Tick
		g_oalWakeSource = OEMWAKE_RTC_TICK;
		//pSysConReg->WAKEUP_STAT = 0x4;		// Clear RTC_TICK_WAKEUP State Bit
#ifdef	SLEEP_AGING_TEST
			pRTCReg->RTCCON &= ~(1<<8);	// Tick Timer Disable
			pRTCReg->INTP = 0x1;				// Clear RTC Tick Interrupt Pending
#endif
		break;
	case 0x10:	// Keypad
		g_oalWakeSource = OEMWAKE_KEYPAD;
		//pSysConReg->WAKEUP_STAT = 0x10;	// Clear KEY_WAKEUP State Bit
		break;
	case 0x20:	// MSM
		g_oalWakeSource = OEMWAKE_MSM;
		//pSysConReg->WAKEUP_STAT = 0x20;	// Clear MSM_WAKEUP State Bit
		break;
	case 0x40:	// BATFLT
		g_oalWakeSource = OEMWAKE_BATTERY_FAULT;
		//pSysConReg->WAKEUP_STAT = 0x40;	// Clear BATFLT_WAKEUP State Bit
		break;
	case 0x80:	// WRESET
		g_oalWakeSource = OEMWAKE_WARM_RESET;
		//pSysConReg->WAKEUP_STAT = 0x80;	// Clear WRESET_WAKEUP State Bit
		break;
	case 0x100:	// HSI
		g_oalWakeSource = OEMWAKE_HSI;
		//pSysConReg->WAKEUP_STAT = 0x100;	// Clear HSI_WAKEUP State Bit
		break;
	default:		// Unknown or Multiple Wakeup Source ???
		g_oalWakeSource = SYSWAKE_UNKNOWN;
		break;
	}

	// Clear All Wake Up Status bits
	pSysConReg->WAKEUP_STAT = 0xfff;

	// EINT_MASK in SysCon Also Effective in Normal State
	// Unmask all bit for External Interrupt at Normal Mode
	pSysConReg->EINT_MASK = 0x0;
}

static void S3C6410_SaveState_VIC(void *pVIC0, void *pVIC1, UINT32 *pBuffer)
{
	volatile S3C6410_VIC_REG *pVIC0Reg;
	volatile S3C6410_VIC_REG *pVIC1Reg;

	pVIC0Reg = (S3C6410_VIC_REG *)pVIC0;
	pVIC1Reg = (S3C6410_VIC_REG *)pVIC1;

	*pBuffer++ = pVIC0Reg->VICINTSELECT;
	*pBuffer++ = pVIC0Reg->VICINTENABLE;
	*pBuffer++ = pVIC0Reg->VICSOFTINT;
	*pBuffer++ = pVIC1Reg->VICINTSELECT;
	*pBuffer++ = pVIC1Reg->VICINTENABLE;
	*pBuffer++ = pVIC1Reg->VICSOFTINT;

	// Do not Save VICVECTADDRXX
	// Reinitialize Vector Address Table with VICTableInit()
}

static void S3C6410_RestoreState_VIC(void *pVIC0, void *pVIC1, UINT32 *pBuffer)
{
	volatile S3C6410_VIC_REG *pVIC0Reg;
	volatile S3C6410_VIC_REG *pVIC1Reg;

	pVIC0Reg = (S3C6410_VIC_REG *)pVIC0;
	pVIC1Reg = (S3C6410_VIC_REG *)pVIC1;

	pVIC0Reg->VICINTSELECT = *pBuffer++;
	pVIC0Reg->VICINTENABLE = *pBuffer++;
	pVIC0Reg->VICSOFTINT = *pBuffer++;
	pVIC1Reg->VICINTSELECT = *pBuffer++;
	pVIC1Reg->VICINTENABLE = *pBuffer++;
	pVIC1Reg->VICSOFTINT = *pBuffer++;

	// Do not Restore VICVECTADDRXX
	// Reinitialize Vector Address Table with VICTableInit()
	VICTableInit();
}

static void S3C6410_SaveState_GPIO(void *pGPIO, UINT32 *pBuffer)
{
	volatile S3C6410_GPIO_REG *pGPIOReg;

	pGPIOReg = (S3C6410_GPIO_REG *)pGPIO;

	// GPIO A
	*pBuffer++ = pGPIOReg->GPACON;		// 000
	*pBuffer++ = pGPIOReg->GPADAT;		// 004
	*pBuffer++ = pGPIOReg->GPAPUD;		// 008
	//GPACONSLP;						// 00c
	//GPAPUDSLP;						// 010

	// GPIO B
	*pBuffer++ = pGPIOReg->GPBCON;		// 020
	*pBuffer++ = pGPIOReg->GPBDAT;		// 024
	*pBuffer++ = pGPIOReg->GPBPUD;		// 028
	//GPBCONSLP;						// 02c
	//GPBPUDSLP;						// 030

	// GPIO C
	*pBuffer++ = pGPIOReg->GPCCON;		// 040
	*pBuffer++ = pGPIOReg->GPCDAT;		// 044
	*pBuffer++ = pGPIOReg->GPCPUD;		// 048
	//GPCCONSLP;						// 04c
	//GPCPUDSLP;						// 050

	// GPIO D
	*pBuffer++ = pGPIOReg->GPDCON;		// 060
	*pBuffer++ = pGPIOReg->GPDDAT;		// 064
	*pBuffer++ = pGPIOReg->GPDPUD;		// 068
	//GPDCONSLP;						// 06c
	//GPDPUDSLP;						// 070

	// GPIO E
	*pBuffer++ = pGPIOReg->GPECON;		// 080
	*pBuffer++ = pGPIOReg->GPEDAT;		// 084
	*pBuffer++ = pGPIOReg->GPEPUD;		// 088
	//GPECONSLP;						// 08c
	//GPEPUDSLP;						// 090

	// GPIO F
	*pBuffer++ = pGPIOReg->GPFCON;		// 0a0
	*pBuffer++ = pGPIOReg->GPFDAT;		// 0a4
	*pBuffer++ = pGPIOReg->GPFPUD;		// 0a8
	//GPFCONSLP;						// 0ac
	//GPFPUDSLP;						// 0b0

	// GPIO G
	*pBuffer++ = pGPIOReg->GPGCON;		// 0c0
	*pBuffer++ = pGPIOReg->GPGDAT;		// 0c4
	*pBuffer++ = pGPIOReg->GPGPUD;		// 0c8
	//GPGCONSLP;						// 0cc
	//GPGPUDSLP;						// 0d0

	// GPIO H
	*pBuffer++ = pGPIOReg->GPHCON0;	// 0e0
	*pBuffer++ = pGPIOReg->GPHCON1;	// 0e4
	*pBuffer++ = pGPIOReg->GPHDAT;		// 0e8
	*pBuffer++ = pGPIOReg->GPHPUD;		// 0ec
	//GPHCONSLP;						// 0f0
	//GPHPUDSLP;						// 0f4

	// GPIO I
	*pBuffer++ = pGPIOReg->GPICON;		// 100
	*pBuffer++ = pGPIOReg->GPIDAT;		// 104
	*pBuffer++ = pGPIOReg->GPIPUD;		// 108
	//GPICONSLP;						// 10c
	//GPIPUDSLP;						// 110

	// GPIO J
	*pBuffer++ = pGPIOReg->GPJCON;		// 120
	*pBuffer++ = pGPIOReg->GPJDAT;		// 124
	*pBuffer++ = pGPIOReg->GPJPUD;		// 128
	//GPJCONSLP;						// 12c
	//GPJPUDSLP;						// 130

	// GPIO K
	*pBuffer++ = pGPIOReg->GPKCON0;	// 800
	*pBuffer++ = pGPIOReg->GPKCON1;	// 804
	*pBuffer++ = pGPIOReg->GPKDAT;		// 808
	*pBuffer++ = pGPIOReg->GPKPUD;		// 80c

	// GPIO L
	*pBuffer++ = pGPIOReg->GPLCON0;	// 810
	*pBuffer++ = pGPIOReg->GPLCON1;	// 814
	*pBuffer++ = pGPIOReg->GPLDAT;		// 818
	*pBuffer++ = pGPIOReg->GPLPUD;		// 81c

	// GPIO M
	*pBuffer++ = pGPIOReg->GPMCON;		// 820
	*pBuffer++ = pGPIOReg->GPMDAT;		// 824
	*pBuffer++ = pGPIOReg->GPMPUD;		// 828

	// GPIO N
	*pBuffer++ = pGPIOReg->GPNCON;		// 830
	*pBuffer++ = pGPIOReg->GPNDAT;		// 834
	*pBuffer++ = pGPIOReg->GPNPUD;		// 838

	// GPIO O
	*pBuffer++ = pGPIOReg->GPOCON;		// 140
	*pBuffer++ = pGPIOReg->GPODAT;		// 144
	*pBuffer++ = pGPIOReg->GPOPUD;		// 148
	//GPOCONSLP;						// 14c
	//GPOPUDSLP;						// 150

	// GPIO P
	*pBuffer++ = pGPIOReg->GPPCON;		// 160
	*pBuffer++ = pGPIOReg->GPPDAT;		// 164
	*pBuffer++ = pGPIOReg->GPPPUD;		// 168
	//GPPCONSLP;						// 16c
	//GPPPUDSLP;						// 170

	// GPIO Q
	*pBuffer++ = pGPIOReg->GPQCON;		// 180
	*pBuffer++ = pGPIOReg->GPQDAT;		// 184
	*pBuffer++ = pGPIOReg->GPQPUD;		// 188
	//GPQCONSLP;						// 18c
	//GPQPUDSLP;						// 190

	// Special Port Control
	*pBuffer++ = pGPIOReg->SPCON;			// 1a0
	//SPCONSLP;								// 880	// Configure for Sleep Mode

	// Memory Port Control
	*pBuffer++ = pGPIOReg->MEM0CONSTOP;	// 1b0
	*pBuffer++ = pGPIOReg->MEM1CONSTOP;	// 1b4

	*pBuffer++ = pGPIOReg->MEM0CONSLP0;	// 1c0
	*pBuffer++ = pGPIOReg->MEM0CONSLP1;	// 1c4
	*pBuffer++ = pGPIOReg->MEM1CONSLP;		// 1c8

	*pBuffer++ = pGPIOReg->MEM0DRVCON;	// 1d0
	*pBuffer++ = pGPIOReg->MEM1DRVCON;	// 1d4

	// External Interrupt
	*pBuffer++ = pGPIOReg->EINT12CON;		// 200

⌨️ 快捷键说明

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