📄 stop.c
字号:
rCLKCON=0x7fff0; //Clear STOP_BIT & IDLE_BIT just after exiting STOP mode.
//rCLKSLOW=0x4; //csh (???) debug
#if GPIO_RESTORE
//Restore the port configurations
for(i=0;i<33;i++)
*((U32 *)0x56000000 +i)=portStatus[i];
#endif
//WORK-AROUND. Should be removed!!!
#if 1
//By original design, this should not be here.
#if FCLK==135000000
ChangeMPllValue(82,2,1); // FCLK=135000000Hz
#elif FCLK==180000000
ChangeMPllValue(82,1,1); // FCLK=180000000Hz
#endif
#endif
Led_Display(0xa);
Lcd_EnvidOnOff(1);
Uart_Printf("SRCPND=%x,INTPND=%x\n",rSRCPND,rINTPND);
rINTMSK =~(BIT_EINT0|BIT_RTC|BIT_EINT8_23);
#if 0
Delay(10); //alarm interrupt may needs some long time.
#else
for(i=0;i<10;i++);
#endif
//The Wake-up source is indicated by rSRCPND.
//The corresponding interrupt wiil be occurred here.
rINTMSK =BIT_ALLMSK;
Uart_Printf("Return to Normal Mode.\n");
#if CHECK_SDRAM_SELFREFRESH
Uart_Printf("Check SDRAM for self-refresh test\n");
for(i=_NONCACHE_STARTADDRESS;i<(_NONCACHE_STARTADDRESS+0x400000);i+=4)
{
if(*((U32 *)i)!=(i^0x55555555))
{
Uart_Printf("Mem Error:%x=%x(%x)\n",i,*((U32 *)i),i^0x55555555);
error++;
}
if(error>20)break;
}
if(error)
Uart_Printf("SDRAM self-refresh test:FAILED\n");
else
Uart_Printf("SDRAM self-refresh test:O.K.\n");
#endif
}
void Check_PowerOffWakeUp(void)
{
Uart_Printf("[Power off related registers]\n");
Uart_Printf("GSTATUS2: PWRST=%d OFFRST=%d WDTRST=%d\n",
(rGSTATUS2&(1<<0))!=0,
(rGSTATUS2&(1<<1))!=0,
(rGSTATUS2&(1<<2))!=0);
Uart_Printf("GSTATUS3:%x(0x0,0x%x), GSTATUS4=%x(0x0,0xaaaaaaaa)\n",
rGSTATUS3,(U32)StartPointAfterPowerOffWakeUp,rGSTATUS4);
if(rGSTATUS2&(1<<0))
{
Uart_Printf("Power On Reset\n\n");
rGSTATUS2=(1<<0);
return;
}
if(rGSTATUS2&(1<<1))
{
Uart_Printf("POWER OFF Wake-up\n\n");
rGSTATUS2=(1<<1);
Uart_Printf("EINTPEND=0x%x\n",rEINTPEND);
Uart_Printf("SRCPND=0x%x\n",rSRCPND);
Test_PowerOffMode();
}
if(rGSTATUS2&(1<<2))
{
Uart_Printf("Watchdog Reset\n\n");
rGSTATUS2=(1<<2);
return;
}
}
void Test_PowerOffMode(void)
{
int i;
// U32 portStatus[33];
int error=0;
// int mode;
Uart_Printf("[POWER OFF Mode Test]\n");
Uart_Printf("BATT_FLT pin should be tested.\n");
Uart_Printf("S3C2410 will wake up by RTC alarm(10 sec) or EINT0 .\n");
#if CHECK_SDRAM_SELFREFRESH
Uart_Printf("Check SDRAM for self-refresh test\n");
for(i=_NONCACHE_STARTADDRESS;i<(_NONCACHE_STARTADDRESS+0x400000);i+=4)
{
if(*((U32 *)i)!=(i^0x55555555))
{
Uart_Printf("Mem Error:%x=%x(%x)\n",i,*((U32 *)i),i^0x55555555);
error++;
}
if(error>20)break;
}
if(error)
Uart_Printf("SDRAM self-refresh test:FAILED\n");
else
Uart_Printf("SDRAM self-refresh test:O.K.\n");
#endif
Uart_TxEmpty(0); //Wait until UART0 Tx buffer empty.
// Saving the port configurations is meaningless.
//for(i=0;i<33;i++)
// portStatus[i]=*( (volatile U32 *)0x56000000 + i);
ConfigStopGPIO();
#if CHOOSE_EINT_TYPE
SelectEintType();
#else
rGPFCON=rGPFCON & ~(3<<0)|(2<<0); //PF0=EINT0
rEXTINT0=rEXTINT0&(7<<0)|(0x2<<0); //EINT0=falling edge triggered
#endif
#if 1 //test whether or not the interrupt pending bit retain the wake-up source.
pISR_EINT0=(U32)Eint0Int;
pISR_EINT8_23=(U32)Eint8_23Int;
pISR_RTC=(U32)AlarmInt;
rINTMSK = ~(BIT_EINT0|BIT_EINT8_23|BIT_RTC);
for(i=0;i<100;i++);
rSRCPND = BIT_EINT0|BIT_EINT8_23|BIT_RTC;
rINTPND = BIT_EINT0|BIT_EINT8_23|BIT_RTC;
rEINTPEND=rEINTPEND;
rSRCPND=rSRCPND;
rINTPND=rINTPND;
#endif
rEINTMASK = rEINTMASK&~(1<<11); //SRCPND:EINT8_23 will be set by EINT11 after wake-up.
rINTMSK = BIT_ALLMSK;
// NOTE: Any interrupt can't be used in STOP mode
// because SDRAM is in self-refresh mode and ISR code will access SDRAM.
#if 1
SetAlarmWakeUp();
#endif
rRTCCON=0x0; // R/W disable, 1/32768, Normal(merge), No reset
rADCCON|=(1<<2);
rMISCCR|=(1<<12); //USB port0 = suspend
rMISCCR|=(1<<13); //USB port1 = suspend
rMISCCR|=(1<<2); //Previous state at STOP(?) mode (???)
rGSTATUS3=(U32)StartPointAfterPowerOffWakeUp;
rGSTATUS4=0xaaaaaaaa;
#if EXTERNAL_BUS_HOLDER
//D[31:0] pull-up off. The data bus will not be float by the external bus holder.
//If the pull-up resitsers are turned on,
//there will be the leakage current through the pull-up resister
rMISCCR=rMISCCR|(3<<0);
#else
//D[31:0] pull-up on. The data bus will not be float by pull-up resister.
rMISCCR=rMISCCR&~(3<<0);
#endif
Lcd_EnvidOnOff(0); //Before entering STOP mode, LCD must be off
Uart_Printf("\nNow, I am entering POWER_OFF mode.\n");
Uart_TxEmpty(0); //Wait until UART0 Tx buffer empty.
//=================================================================
// VERY IMPORTANT NOTE
// To enter STOP/SLIDLE mode, MMU TLB-fill operation should be prohibited
// because MTT table is in SDRAM and SDRAM is in the self-refresh mode.
// So, we will fill TLB before entering SDRAM self-refresh
// instead of disabling MMU.
(void)rREFRESH;//To fill TLB for the special register used in EnterPWDN
(void)rCLKCON;
//=================================================================
EnterPWDN(0x7fff8); //POWER_OFF mode
//Never return here.
}
static void __irq BattFaultInt(void)
{
ClearPending(BIT_BAT_FLT);
Uart_Printf("BATT_FAULT interrupt is occurred.\n");
}
void Test_BattFaultInterrupt(void)
{
Uart_Printf("[nBATT_FAULT interrupt Test]\n");
Uart_Printf("Push any key to exit!\n");
pISR_BAT_FLT=(unsigned)BattFaultInt;
rINTMSK=rINTMSK&~(BIT_BAT_FLT);
while(!Uart_GetKey());
}
/************************ POWER OFF Mode by 100hz test ************************/
void Check_PowerOffWakeUp_100Hz(void)
{
/*
Uart_Printf("GSTATUS2: PWRST=%d OFFRST=%d WDTRST=%d\n",
(rGSTATUS2&(1<<0))!=0,
(rGSTATUS2&(1<<1))!=0,
(rGSTATUS2&(1<<2))!=0);
Uart_Printf("GSTATUS3:%x(0x0,0x%x), GSTATUS4=%x(0x0,0xaaaaaaaa)\n",
rGSTATUS3,(U32)StartPointAfterPowerOffWakeUp,rGSTATUS4);
*/
if(rGSTATUS2&(1<<0))
{
Uart_Printf("Power On Reset\n\n");
rGSTATUS2=(1<<0);
return;
}
if(rGSTATUS2&(1<<1))
{
if( *((volatile U32 *)0x33e00000) != 0x12345678 )
{
*((volatile U32 *)0x33e00000)=0x12345678;
*((volatile U32 *)0x33e00004)=0x0;
}
(*(volatile U32 *)0x33e00004)++;
Uart_Printf("wu PO:%d\n",*((volatile U32 *)0x33e00004));
if(rGSTATUS4!=0xaaaaaaaa)
{
Uart_Printf("GSTATUS4 register error rGSTATUS4=%x\n",rGSTATUS4);
while(1);
}
rGSTATUS2=(1<<1);
Test_PowerOffMode_100Hz();
}
if(rGSTATUS2&(1<<2))
{
Uart_Printf("Watchdog Reset\n\n");
rGSTATUS2=(1<<2);
return;
}
}
void Test_PowerOffMode_100Hz(void)
{
int i;
// U32 portStatus[33];
int error=0;
// int mode;
Uart_Printf("[PO 100Hz]\n");
if(Uart_GetKey()!=0)
{
for(i=_NONCACHE_STARTADDRESS;i<(_NONCACHE_STARTADDRESS+0x400000);i+=4)
{
if(*((U32 *)i)!=(i^0x55555555))
{
Uart_Printf("Mem Error:%x=%x(%x)\n",i,*((U32 *)i),i^0x55555555);
error++;
}
if(error>20)break;
}
if(error)
Uart_Printf("SDRAM self-refresh test:FAILED\n");
else
Uart_Printf("SDRAM self-refresh test:O.K.\n");
}
Uart_TxEmpty(0); //Wait until UART0 Tx buffer empty.
// Saving the port configurations is meaningless.
//for(i=0;i<33;i++)
// portStatus[i]=*( (volatile U32 *)0x56000000 + i);
ConfigStopGPIO();
#if 0
SelectEintType();
#else
rGPFCON=rGPFCON & ~(3<<0)|(2<<0); //PF0=EINT0
rEXTINT0=rEXTINT0&(7<<0)|(0x2<<0); //EINT0=falling edge triggered
#endif
#if 1 //test whether or not the interrupt pending bit retain the wake-up source.
pISR_EINT0=(U32)Eint0Int;
pISR_EINT8_23=(U32)Eint8_23Int_100Hz;
pISR_RTC=(U32)AlarmInt;
rINTMSK = ~(BIT_EINT0|BIT_EINT8_23|BIT_RTC);
for(i=0;i<100;i++);
rSRCPND = BIT_EINT0|BIT_EINT8_23|BIT_RTC;
rINTPND = BIT_EINT0|BIT_EINT8_23|BIT_RTC;
rEINTPEND=rEINTPEND;
rSRCPND=rSRCPND;
rINTPND=rINTPND;
#endif
rEINTMASK = rEINTMASK&~(1<<11); //SRCPND:EINT8_23 will be set by EINT11 after wake-up.
rINTMSK = BIT_ALLMSK;
// NOTE: Any interrupt can't be used in STOP mode
// because SDRAM is in self-refresh mode and ISR code will access SDRAM.
#if 0
SetAlarmWakeUp();
#endif
rRTCCON=0x0; // R/W disable, 1/32768, Normal(merge), No reset
rADCCON|=(1<<2);
rMISCCR|=(1<<12); //USB port0 = suspend
rMISCCR|=(1<<13); //USB port1 = suspend
rMISCCR|=(1<<2); //Previous state at STOP(?) mode (???)
rGSTATUS3=(U32)StartPointAfterPowerOffWakeUp;
rGSTATUS4=0xaaaaaaaa;
#if EXTERNAL_BUS_HOLDER
//D[31:0] pull-up off. The data bus will not be float by the external bus holder.
//If the pull-up resitsers are turned on,
//there will be the leakage current through the pull-up resister
rMISCCR=rMISCCR|(3<<0);
#else
//D[31:0] pull-up on. The data bus will not be float by pull-up resister.
rMISCCR=rMISCCR&~(3<<0);
#endif
Lcd_EnvidOnOff(0); //Before entering STOP mode, LCD must be off
Uart_Printf("e. PO\n\n");
Uart_TxEmpty(0); //Wait until UART0 Tx buffer empty.
//=================================================================
// VERY IMPORTANT NOTE
// To enter STOP/SLIDLE mode, MMU TLB-fill operation should be prohibited
// because MTT table is in SDRAM and SDRAM is in the self-refresh mode.
// So, we will fill TLB before entering SDRAM self-refresh
// instead of disabling MMU.
(void)rREFRESH;//To fill TLB for the special register used in EnterPWDN
(void)rCLKCON;
//=================================================================
EnterPWDN(0x7fff8); //POWER_OFF mode
//Never return here.
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -