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

📄 idle.c

📁 这是三星公司的arm7 s3c44b0x芯片的所有外设中断程序
💻 C
字号:
//44BTEST : idle.c
#include "..\inc\44b.h"
#include "..\inc\44blib.h"
#include "..\inc\def.h"
#include "..\inc\idle.h"
#include "..\inc\rtc.h"
void SLIdleMode(void); //160x240
int debug;
int t0cnt,t1cnt;
void __irq Eint45Int(void)
{
	rEXTINPND=0xf; //clear EXTINPND reg.
	rI_ISPC=BIT_EINT4567;
	Uart_Printf("EINT45 ISR is occurred for wake-up from IDLE mode.\n");
}
void __irq Timer0Int(void)
{
	int i;
	//for(i=0;i<10000;i++);
	rI_ISPC=BIT_TIMER0;
	for(i=0;i<100;i++); //why???
	t0cnt++;
}
void __irq Timer1Int(void)
{
	rI_ISPC=BIT_TIMER1;
	t1cnt++;
}
void __irq AlarmInt(void)
{
	rI_ISPC=BIT_RTC;
	Uart_Printf("ALARM ISR is occurred for wake-up from IDLE mode.\n");
}
void __irq SlEint45Int(void)
{
	rEXTINPND=0xf; //clear EXTINPND reg.
	rI_ISPC=BIT_EINT4567;
	debug=1;
	//????
	//why does not this interrupt occur in SL-IDLE mode?
	//????
}
void __irq SlAlarmInt(void)
{
	//If you have to use the internal peripherals,
	//you must configure CLKCON,CLKSLOW,PLL
	rI_ISPC=BIT_RTC;
	debug=2;
}
/**********************
* IDLE mode test *
**********************/
void Test_IdleMode(void)
{
	int i;
	int extintMode;
	Uart_Printf("[IDLE Mode Test]\n");
	Uart_Printf("Check the current cunsumption. Push the buttons to exit IDLE mode.\n");
	Uart_Printf("After 10 seconds, S3C44B0X will wake up by RTC alarm interrupt.\n");
	Uart_Printf("S3C44B0X will also wake up by EINT4/5.\n");
	Uart_Printf("1.L-LEVEL 2.H-LEVEL 3.F-EDGE 4.R-EDGE 5.B-EDGE\n");
	Uart_Printf("Select the external interrupt type. Press the number!!!\n");
	extintMode=Uart_Getch();
	Uart_TxEmpty(0); //Wait until UART0 Tx buffer empty.
	rPCONG=0xf00; //PG2=EINT2
	switch(extintMode)
	{
	case '1':
		rEXTINT=0x0; //low
		break;
	case '2':
		rEXTINT=0x11111111; //high
		break;
	case '3':
		rEXTINT=0x22222222; //falling
		break;
	case '4':
		rEXTINT=0x44444444; //rising
		break;
	case '5':
		rEXTINT=0x66666666; //both edge
		break;
	default:
		break;
	}
	Rtc_Init();
	rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reset
	rALMYEAR=TESTYEAR2 ;
	rALMMON =TESTMONTH2;
	rALMDAY =TESTDAY2 ;
	rALMHOUR=TESTHOUR2 ;
	rALMMIN =TESTMIN2 ;
	rALMSEC =TESTSEC2+9;
	rRTCALM=0x7f;
	rI_ISPC=BIT_EINT4567|BIT_RTC; //to clear the previous pending status.
	Uart_Printf("rINTPND=%x\n",rINTPND);
	pISR_EINT4567=(U32)Eint45Int;
	pISR_RTC=(U32)AlarmInt;
	rINTMSK=~(BIT_GLOBAL|BIT_EINT4567|BIT_RTC);
	for(i=0;i<2;i++); //wait until the pended interrupt is executed.
	rCLKCON=0x7ff8|0x4; //enter IDLE mode.
	//Uart_Getch();
	for(i=0;i<10;i++); //wait until S3C44B0X enters IDLE mode.
	// wait EINT[7:0] interrupt or alarm wake-up
	rCLKCON=0x7ff8;
	//turn-off IDLE bit on rCLKCON to synchronize rCLKCON with the real mode.
	Uart_Printf("Return to Normal Mode.\n");
	rINTMSK=BIT_GLOBAL;
}
void Test_IdleModeHard(void)
{
	int i,j;
	Uart_Printf("[IDLE Mode Test with Timer0,1 10000times]\n");
	Uart_Printf("S3C44B0X will also wake up by EINT4/5.\n");
	Uart_TxEmpty(0); //Wait until UART0 Tx buffer empty.
	rPCONG=0xf00; //PG2=EINT2
	rEXTINT=rEXTINT&~(7<<8)|(2<<8); //falling
	pISR_TIMER0=(U32)Timer0Int;
	pISR_TIMER1=(U32)Timer1Int;
	pISR_EINT4567=(U32)Eint45Int;
	rTCFG0=0x00010110; //PRESC01,23,45= 1
	rTCFG1=0x00000000; //TIMER0,1,2,3,4,5= 1/2
	rTCNTB0=65535;
	rTCNTB1=2570;
	//rTCON=0xa0a; //T1=MU,ITV,T0=MU,ITV
	//rTCON=0x909; //Start T0,T1.
	rTCON=0x00a;
	rTCON=0x009;
	rINTMSK=~(BIT_GLOBAL|BIT_EINT4567|BIT_TIMER0|BIT_TIMER1);
	//rINTMSK=~(BIT_GLOBAL|BIT_EINT2);
	//The two timer will test the IDLE mode hard.
	for(i=0;i<10000;i++)
	{
		rCLKCON=0x7ff8|0x4; //enter IDLE mode.
		for(j=0;j<10;j++); //wait until KS32C41100 enters IDLE mode.
		//wake up from normal mode
		rCLKCON=0x7ff8;
		//turn-off IDLE bit on rCLKCON to synchronize rCLKCON with the real mode.
		Uart_Printf(".");
	}
	rTCON=0x0; //timer off
	rINTMSK=BIT_GLOBAL;
}
/*********************
* SL_IDLE mode test *
*********************/
#define MVAL_USED (0)
#define MVAL (13)
#define L248 (8)
#define CLKVAL_SL (38) // 60Mhz, fr=100Hz (CLKVAL=38.6)
#define M5D(n) ((n) & 0x1fffff)
unsigned int (*_frameBuffer4)[10];
void LcdInit_4Gray160x240(void);
void Display_4Gray160x240(void);
void Test_SLIdleMode20(void)
{
	int i;
	LcdInit_4Gray160x240();
	Display_4Gray160x240();
	Delay(1000); //wait more than 1 frame time.
	for(i=0;i<20;i++)
		SLIdleMode();
}
void Test_SLIdleMode(void)
{
	LcdInit_4Gray160x240();
	Display_4Gray160x240();
	Delay(1000); //wait more than 1 frame time.
	SLIdleMode();
}
void SLIdleMode(void) //160x240
{
	int i;
	int saveDramcon;
	debug=0;
	Uart_Printf("[SL_IDLE MODE TEST for 160x240]\n");
	Uart_Printf("After 10 seconds, S3C44B0X will wake up by RTC alarm interrupt.\n");
	Uart_Printf("S3C44B0X can wake up by EINT4/5.\n");
	Uart_TxEmpty(0);
	rPCONG=0xf00; //PG2=EINT2
	rEXTINT=0x22222222; //falling
	//pISR_EINT2=(U32)SlEint2Int;
	//pISR_RTC=(U32)SlAlarmInt;
	//rINTMSK=~(BIT_GLOBAL|BIT_EINT2|BIT_RTC);
	//If you want to use interrupt generation,the ISR should be on ROM/SRAM
	//(DRAM can't be allowed because of DRAM self-refresh)
	Rtc_Init();
	rRTCCON = 0x01; // R/W enable, 1/32768, Normal(merge), No reset
	rALMYEAR=TESTYEAR2 ;
	rALMMON =TESTMONTH2;
	rALMDAY =TESTDAY2 ;
	rALMHOUR=TESTHOUR2 ;
	rALMMIN =TESTMIN2 ;
	rALMSEC =TESTSEC2+9;
	//rALMSEC =TESTSEC2+1;
	rRTCALM=0x7f; //To test alarm wake-up.
	rADCCON|=0x20; //ADC power down mode
	//
	// The I/O ports have to be configured properly to reduce STOP mode current.
	//
	// LINECNT 4n+m th line
	// 1st line 239 4n+1th
	// 2nd line 238 4n+2th
	// 3rd line 237 4n+3th
	// 4th line 236 4n th
	// ....
	//236th line 4 4n th
	//237th line 3 4n+1th
	//238th line 2 4n+2th
	//239th line 1 4n+3th
	//240th line 0 4n th
	while((rLCDCON1>>22)!=9);
	while((rLCDCON1>>22)!=8);
	// To enter self-refresh mode, the VCLK has to be 'L' after 4n-th line is displayed	completely,
	// So,the self-refresh command has to be issued at 4n th line.
	// VCLK will be 'L' from 4n+1th line.
	//for(i=0;i<10;i++);
	rLCDCON3=0x1; //Enter self-refresh mode.
	while((rLCDCON1>>22)!=0);
	//Because the SLOW mode is used, the LCDCON1,2 should be changed.
	rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)|(0x0<<8)|(0x0<<10)|(1/*CLKVAL*/<<12);
	// disable,4B_SNGL_SCAN,WDLY=2clk,WLH=2clk
	rLCDCON2=(239+L248)|(15/*39*/<<10)|(1<<21); //LINEBLANK=1
	rCLKSLOW=2|(1<<4)|(1<<5); //SLOWVAL=2,Fout=Fin/(2x2),PLL off.
	//DRAM refresh may not be done because of slow MCLK. but,the abnormal period is very short.
	rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x0<<8)|(0x0<<10)|(1<<12);
	saveDramcon=rREFRESH;
	rREFRESH=(2017)|(0<<22)|(1<<23);
	//15,6us@2Mhz, tchr,trc,trp=min, refresh enable.
	// DRAM refresh may not be done every 15.6uS
	// because of slow MCLK(1Mhz) and long memory access cycle.
	EnterPWDN(0x46); //enters SL_IDLE mode. rCLKCON=0x46
	//DRAM/SDRAM self-refresh is executed in EnterPWDN()
	//NOTE:
	//Any special registers setting will not accepted because CPU is not normal mode.
	rCLKCON=0x7ff8;
	rCLKSLOW=2|(1<<4)|(0<<5); //SLOWVAL=2,Fout=Fin/(2x2),PLL on.
	for(i=0;i<2048;i++); //Wait PLL lock time.
	while((rLCDCON1>>22)!=1);
	while((rLCDCON1>>22)!=0);
	//Because the SLOW mode is exited, the LCDCON1,2 should be changed.
	rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_SL<<12);
	// disable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,
	rLCDCON2=(239+L248)|(39<<10)|(10<<21); //HOZVAL=39,LINEBLANK=1
	rCLKSLOW=2; //SLOWVAL=2,Fout=Fpllo,PLL on.
	rLCDCON3=0x0; //LCD self refresh mode off.
	rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_SL<<12);
	rREFRESH=saveDramcon;
	while((rLCDCON1>>22)!=1);
	while((rLCDCON1>>22)!=0); //Display 1 more frame before exiting SL_IDLE mode.
	//why? no reason. it may be better.
	//while((rLCDCON1>>22)!=9);
	//while((rLCDCON1>>22)!=8); //to catch the exit time for SL_IDLE mode.
	//rLCDCON3=0x0; //LCD self refresh mode off.
	//for(i=0;i<10;i++);
	rADCCON&=~(0x20);
	rEXTINPND=0xf; //Clear EXTINPND register
	Uart_Printf("debug=%d\n",debug);
	Uart_Printf("I have exited LCD SELFREF mode.\n");
}
void LcdInit_4Gray160x240(void)
{
	if((U32)_frameBuffer4==0)
	{
		_frameBuffer4=(unsigned int (*)[10])malloc(10*4*240);
	}
	rLCDCON1=(0)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_SL<<12);
	// disable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,CLKVAL=?
	rLCDCON2=(239+L248)|(39<<10)|(10<<21);
	//LINEBLANK=10 (without any calculation)
	rLCDSADDR1= (0x1<<27) | ( ((U32)_frameBuffer4>>22)<<21 ) | M5D((U32)_frameBuffer4>>1);
	// 4-gray, LCDBANK, LCDBASEU
	rLCDSADDR2= M5D((((U32)_frameBuffer4+((160/4)*(240+L248)))>>1)) | (MVAL<<21);
	rLCDSADDR3= (160/8) | ( 0<<9 );
	//No virtual screen.
	//The following value has to be changed for better display.
	//Select 4 levels among 16 gray levels.
	rBLUELUT=0xfa40;
	rDITHMODE=0x0;
	rDP1_2 =0xa5a5;
	rDP4_7 =0xba5da65;
	rDP3_5 =0xa5a5f;
	rDP2_3 =0xd6b;
	rDP5_7 =0xeb7b5ed;
	rDP3_4 =0x7dbe;
	rDP4_5 =0x7ebdf;
	rDP6_7 =0x7fdfbfe;
	rLCDCON1=(1)|(1<<5)|(MVAL_USED<<7)|(0x3<<8)|(0x3<<10)|(CLKVAL_SL<<12);
	// enable,4B_SNGL_SCAN,WDLY=8clk,WLH=8clk,CLKVAL=?
}
void Display_4Gray160x240(void)
{
	int i,j;
	for(j=0;j<100;j++)
	{
		for(i=2;i<10;i++)
		{
			_frameBuffer4[j][i]=0x55aa55aa;
		} 
	}
	for(j=0;j<100;j++)
	{
		_frameBuffer4[j][9]=0x5555ffff;
	}
	for(j=100;j<240;j++)
		for(i=2;i<10;i++)
			_frameBuffer4[j][i]=0x0;
	for(i=2;i<10;i++)
		_frameBuffer4[100][i]=0xffffffff;
	for(i=2;i<10;i++)
		_frameBuffer4[0][i]=0xffffffff;
}

⌨️ 快捷键说明

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