📄 off.c
字号:
//
// 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 + -