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

📄 timer.c

📁 os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm os arm
💻 C
字号:
/*
 *	ApOS (Another Project software for s3c2410)
 *	
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU General Public License version 2 as
 *	published by the Free Software Foundation.
 *			
 *						Copyright caiyuqing
 *
 */
#include "../include/kernel/irq.h"
#include "../include/s3c2410/timer.h"
#include "../include/s3c2410/s3c2410.h"
#include "../include/s3c2410/cpu.h"
#include "../include/kernel/task.h"
#include "../include/kernel/signal.h"
#include "../include/s3c2410/io.h"

/*
	Timer input clock Frequency = PCLK / {prescaler value+1} / {divider value}
	Sample:
		prescaler value = 119
		divider value = 1/16
		PCLK= 50700000
		Timer input clock Frequency =50700000/ (119+1)/(1/16)=26406
*/
extern irq_ptr irq_rotunie[32];

void do_timer0(struct cpu_registers *regs);//Timer0中断服务例程
void do_timer1(struct cpu_registers *regs);//Timer1中断服务例程
void do_timer2(struct cpu_registers *regs);//Timer2中断服务例程
void do_timer3(struct cpu_registers *regs);//Timer3中断服务例程
void do_timer4(struct cpu_registers *regs);//Timer4中断服务例程

struct timer_ctrl_object timer_ctrl_object;

extern struct task_struct* current;
extern int volatile jiffies;
unsigned int current_singal;

unsigned int *led=0x56000054;
/*
	初始化 timer_ctrl_object 对象
*/
void timer_ctrl_obj_init(struct timer_ctrl_object *tco)
{
	tco->tcfg0	=&rTCFG0;
	tco->tcfg1	=&rTCFG1;
	tco->tcon	=&rTCON;
	
	tco->tcntb0	=&rTCNTB0;
	tco->tcmpb0	=&rTCMPB0;
	tco->tcnto0	=&rTCNTO0;
	
	tco->tcntb1	=&rTCNTB1;
	tco->tcmpb1	=&rTCMPB1;
	tco->tcnto1	=&rTCNTO1;
	
	tco->tcntb2	=&rTCNTB2;
	tco->tcmpb2	=&rTCMPB2;
	tco->tcnto2	=&rTCNTO2;
	
	tco->tcntb3	=&rTCNTB3;
	tco->tcmpb3	=&rTCMPB3;
	tco->tcnto3	=&rTCNTO3;
	
	tco->tcntb4	=&rTCNTB4;
	tco->tcnto4	=&rTCNTO4;

	tco->timer_cnt0	=0;
	tco->timer_cnt1	=0;
	tco->timer_cnt2	=0;
	tco->timer_cnt3	=0;
}
/*
	设置 rTCFG0 寄存器中的 prescaler
*/
int timer_set_prescaler(unsigned char timerX,unsigned int pres_val)
{
	unsigned int tcfg0	=*timer_ctrl_object.tcfg0;
	if(timerX>4)
		return -1;
	else
	{
		switch(timerX)
		{
			/*
				TIMER_0,TIMER_1的 prescaler 占用 rTCFG0 的前0~7位
			*/
			case TIMER_0:
			case TIMER_1:
				tcfg0&=0xFF00;
				tcfg0|=pres_val<<PRESCALER0_OFFSET_TCFG0;
				break;
			
			/*
				TIMER_2,TIMER_3,TIMER_4的 prescaler 占用 rTCFG0 的第8~16位
			*/
			case TIMER_2:
			case TIMER_3:
			case TIMER_4:
				tcfg0&=0x00FF;
				tcfg0|=(pres_val<<PRESCALER1_OFFSET_TCFG0);
				break;
		}
		*timer_ctrl_object.tcfg0	=tcfg0;
		return 1;
	}
	
}
/*
	设置 rTCFG1 寄存器中的 MUX,MUX的取值由time.h中的宏 MUX_X1_X2 定义,
	X1_X2表示X1/X2,例如MUX_1_2,表示MUX为 1/2
*/
int timer_set_mux(unsigned char timerX,unsigned int mux_val)
{
	unsigned int tcfg1	=*timer_ctrl_object.tcfg1;
	unsigned int tmp_mux_val=0x0000000F;
	
	if(timerX>4)
		return -1;
	else
	{
		tcfg1&=~(tmp_mux_val<<timerX*MUX_BITS_TCFG1);
		tcfg1|=mux_val<<timerX*4;
		*timer_ctrl_object.tcfg1=tcfg1;
		return 1;
	}
}
/*
	DMA模式/中断模式选择,dma_sel_val的值由time.h中的宏TIMERX_DMA_MODE
	和INTERRUPT_MODE定义
*/
void timer_dma_sel(unsigned int dma_sel_val)
{
	unsigned int tcfg1	=*timer_ctrl_object.tcfg1;
	unsigned int tmp_dma_sel_val=0x0000000F;
	
	tcfg1&=~(tmp_dma_sel_val<<DMA_MODE_OFFSET_TCFG1);
	tcfg1|=dma_sel_val<<DMA_MODE_OFFSET_TCFG1;
	*timer_ctrl_object.tcfg1=tcfg1;
		
}
/*
	设置rTCNTBX寄存器(计数寄存器)的值
*/
int timer_set_cnt_buffer(unsigned char timerX,unsigned int cnt_val)
{
	if(timerX>4)
		return -1;
	else
	{
		switch(timerX)
		{
			case TIMER_0:
				*timer_ctrl_object.tcntb0=cnt_val;
				break;
			
			case TIMER_1:
				*timer_ctrl_object.tcntb1=cnt_val;
				break;
			
			case TIMER_2:
				*timer_ctrl_object.tcntb2=cnt_val;
				break;
			
			case TIMER_3:
				*timer_ctrl_object.tcntb3=cnt_val;
				break;
			
			case TIMER_4:
				*timer_ctrl_object.tcntb4=cnt_val;
				break;
		}
		return 1;
	}
}
/*
	设置rTCMPBX寄存器(比较寄存器)的值
*/
int timer_set_cmp_buffer(unsigned char timerX,unsigned int cmp_val)
{
	if(timerX>3)
		return -1;
	else
	{
		switch(timerX)
		{
			case TIMER_0:
				*timer_ctrl_object.tcmpb0=cmp_val;
				break;
				
			case TIMER_1:
				*timer_ctrl_object.tcmpb1=cmp_val;
				break;
				
			case TIMER_2:
				*timer_ctrl_object.tcmpb2=cmp_val;
				break;
				
			case TIMER_3:
				*timer_ctrl_object.tcmpb3=cmp_val;
				break;
		}
		return 1;
	}
}

int timer_set_cnto_buffer(unsigned char timerX,unsigned int cnto_val)
{
	if(timerX>4)
		return -1;
	else
	{
		switch(timerX)
		{
			case TIMER_0:
				*timer_ctrl_object.tcnto0=cnto_val;
				break;
				
			case TIMER_1:
				*timer_ctrl_object.tcnto1=cnto_val;
				break;
				
			case TIMER_2:
				*timer_ctrl_object.tcnto2=cnto_val;
				break;
				
			case TIMER_3:
				*timer_ctrl_object.tcnto3=cnto_val;
				break;
			case TIMER_4:
				*timer_ctrl_object.tcnto4=cnto_val;
				break;
		}
		return 1;
	}
}
/*
	开始刷新CTCNTBX和CTCMPBX寄存器,当开启TIMERX时,该TIMER必须停止
	对CTCNTBX和CTCMPBX的刷新,否则TIMER不会进行计数(CTCNTBX不会递减)
*/
int timer_update_cntb_and_cmpb(unsigned char timerX)
{
	unsigned int tcon	=*timer_ctrl_object.tcon;
	unsigned int tmp_update=0x00000001;
	
	if(timerX>4)
		return -1;
	else
	{
		switch(timerX)
		{
			//CTCNTB0,CTCMPB0
			case TIMER_0:
				tcon&=~(tmp_update<<TIMER0_UPDATE_BIT_TCON);
				tcon|=(tmp_update<<TIMER0_UPDATE_BIT_TCON);
				break;
			//CTCNTB1,CTCMPB1
			case TIMER_1:
				tcon&=~(tmp_update<<TIMER1_UPDATE_BIT_TCON);
				tcon|=(tmp_update<<TIMER1_UPDATE_BIT_TCON);
				break;
			//CTCNTB2,CTCMPB2	
			case TIMER_2:
				tcon&=~(tmp_update<<TIMER2_UPDATE_BIT_TCON);
				tcon|=(tmp_update<<TIMER2_UPDATE_BIT_TCON);
				break;
			//CTCNTB3,CTCMPB3	
			case TIMER_3:
				tcon&=~(tmp_update<<TIMER3_UPDATE_BIT_TCON);
				tcon|=(tmp_update<<TIMER3_UPDATE_BIT_TCON);
				break;
			//CTCNTB4,CTCMPB4	
			case TIMER_4:
				tcon&=~(tmp_update<<TIMER4_UPDATE_BIT_TCON);
				tcon|=(tmp_update<<TIMER4_UPDATE_BIT_TCON);
				break;
		}
		
		*timer_ctrl_object.tcon	=tcon;
		return 1;
	}
}
/*
	停止刷新CTCNTBX和CTCMPBX寄存器,当开启TIMERX时,该TIMER对应的
	update位必须为0(停止刷新),否则TIMER不会进行计数(CTCNTBX不会递减)
*/
int timer_unupdate_cntb_and_cmpb(unsigned char timerX)
{
	unsigned int tcon	=*timer_ctrl_object.tcon;
	
	unsigned int tmp_update=0x00000001;
	
	if(timerX>4)
		return -1;
	else
	{
		switch(timerX)
		{
			//CTCNTB0,CTCMPB0
			case TIMER_0:
				tcon&=~(tmp_update<<TIMER0_UPDATE_BIT_TCON);
				break;
				
			//CTCNTB1,CTCMPB1	
			case TIMER_1:
				tcon&=~(tmp_update<<TIMER1_UPDATE_BIT_TCON);
				break;
				
			//CTCNTB2,CTCMPB2	
			case TIMER_2:
				tcon&=~(tmp_update<<TIMER2_UPDATE_BIT_TCON);
				break;
				
			//CTCNTB3,CTCMPB3	
			case TIMER_3:
				tcon&=~(tmp_update<<TIMER3_UPDATE_BIT_TCON);
				break;
				
			//CTCNTB4,CTCMPB4	
			case TIMER_4:
				tcon&=~(tmp_update<<TIMER4_UPDATE_BIT_TCON);
				break;
				
		}
		*timer_ctrl_object.tcon	=tcon;
		return 1;
	}
}
/*
	选择CTCNTBX加载模式,load_mode由 time.h中的宏AUTO_RELOAD	1
	和 ONE_SHORT 定义
*/
int timer_load_mode(unsigned char timerX,unsigned load_mode)
{
	unsigned int tcon	=*timer_ctrl_object.tcon;
	unsigned int tmp_reload_mode=0x00000001;
	
	if(timerX>4)
		return -1;
	else
	{
		switch(timerX)
		{
			case TIMER_0:
				tcon&=~(tmp_reload_mode<<TIMER0_LOADMODE_BIT_TCON);
				tcon|=load_mode<<TIMER0_LOADMODE_BIT_TCON;
				break;
				
			case TIMER_1:
				tcon&=~(tmp_reload_mode<<TIMER1_LOADMODE_BIT_TCON);
				tcon|=load_mode<<TIMER1_LOADMODE_BIT_TCON;
				break;
				
			case TIMER_2:
				tcon&=~(tmp_reload_mode<<TIMER2_LOADMODE_BIT_TCON);
				tcon|=load_mode<<TIMER2_LOADMODE_BIT_TCON;
				break;
				
			case TIMER_3:
				tcon&=~(tmp_reload_mode<<TIMER3_LOADMODE_BIT_TCON);
				tcon|=load_mode<<TIMER3_LOADMODE_BIT_TCON;
				break;
				
			case TIMER_4:
				tcon&=~(tmp_reload_mode<<TIMER4_LOADMODE_BIT_TCON);
				tcon|=load_mode<<TIMER4_LOADMODE_BIT_TCON;
				break;

		}
		*timer_ctrl_object.tcon	=tcon;
		return 1;
	}
}


int timer_start(unsigned char timerX)
{
	//停止TIMER的CTCNTB和CTCMPB进行update
	timer_unupdate_cntb_and_cmpb(timerX);
	unsigned int tcon	=*timer_ctrl_object.tcon;

	if(timerX>4)
		return -1;
	else
	{	
		
		switch(timerX)
		{
			case TIMER_0:
				//启动TIMER0
				tcon|=(1<<TIMER0_START_BIT_TCON);
				break;
				
			case TIMER_1:
				//启动TIMER1
				tcon|=(1<<TIMER1_START_BIT_TCON);
				break;
				
			case TIMER_2:
				//启动TIMER2
				tcon|=(1<<TIMER2_START_BIT_TCON);
				break;

			case TIMER_3:
				//启动TIMER3
				tcon|=(1<<TIMER3_START_BIT_TCON);
				break;
				
			case TIMER_4:
				//启动TIMER4
				tcon|=(1<<TIMER4_START_BIT_TCON);
				break;
		}
		*timer_ctrl_object.tcon	=tcon;
		return 1;
	}
}


void timer_config(unsigned char timerX,
		unsigned int cntb,unsigned int cmpb)
{
	timer_set_prescaler(timerX,119);
	timer_set_mux(timerX,MUX_1_16);
	timer_set_cnt_buffer(timerX,cntb);
	timer_set_cmp_buffer(timerX,cmpb);
	timer_update_cntb_and_cmpb(timerX);
	timer_load_mode(timerX,AUTO_RELOAD);
}

/*
 *	有了 timer_enable(),我们就可以方便的调整任何一个timer的频率并开启它
 */
void timer_enable(unsigned char timerX,unsigned int freq)
{
	switch(timerX)
	{
		case TIMER_0:
			irq_mask(INT_TIMER0,IRQ_MASK);
			timer_config(TIMER_0,26406/freq,0);
			timer_start(TIMER_0);
			irq_rotunie[INT_TIMER0]=&do_timer0;
			irq_mask(INT_TIMER0,IRQ_UNMASK);
			break;
			
		case TIMER_1:
			irq_mask(INT_TIMER1,IRQ_MASK);
			timer_config(TIMER_1,26406/freq,0);
			timer_start(TIMER_1);
			irq_rotunie[INT_TIMER1]=&do_timer1;
			irq_mask(INT_TIMER1,IRQ_UNMASK);
			break;
			
		case TIMER_2:
			irq_mask(INT_TIMER2,IRQ_MASK);
			timer_config(TIMER_2,26406/freq,0);
			timer_start(TIMER_2);
			irq_rotunie[INT_TIMER2]=&do_timer2;
			irq_mask(INT_TIMER2,IRQ_UNMASK);
			break;
			
		case TIMER_3:
			irq_mask(INT_TIMER3,IRQ_MASK);
			timer_config(TIMER_3,26406/freq,0);
			timer_start(TIMER_3);
			irq_rotunie[INT_TIMER3]=&do_timer3;
			irq_mask(INT_TIMER3,IRQ_UNMASK);
			break;
			
		case TIMER_4:
			irq_mask(INT_TIMER4,IRQ_MASK);
			timer_config(TIMER_4,26406/freq,0);
			timer_start(TIMER_4);
			irq_rotunie[INT_TIMER4]=&do_timer4;
			irq_mask(INT_TIMER4,IRQ_UNMASK);
			break;
	}

}


/*
 *	timer_disable()用于停止指定的timer并关闭与该timer相关的中断
 */
int timer_disable(unsigned char timerX)
{
	unsigned int tcon	=*timer_ctrl_object.tcon;
	if(timerX>4)
		return -1;
	else
	{	
		
		switch(timerX)
		{
			case TIMER_0:
				//停止TIMER0
				tcon&=~(1<<TIMER0_START_BIT_TCON);
				irq_mask(INT_TIMER0,IRQ_MASK);
				break;
				
			case TIMER_1:
				//停止TIMER1
				tcon&=~(1<<TIMER1_START_BIT_TCON);
				irq_mask(INT_TIMER1,IRQ_MASK);
				break;

			case TIMER_2:
				//停止TIMER2
				tcon&=~(1<<TIMER2_START_BIT_TCON);
				irq_mask(INT_TIMER2,IRQ_MASK);
				break;

			case TIMER_3:
				//停止TIMER3
				tcon&=~(1<<TIMER3_START_BIT_TCON);
				irq_mask(INT_TIMER3,IRQ_MASK);
				break;
				
			case TIMER_4:
				//停止TIMER4
				tcon&=~(1<<TIMER4_START_BIT_TCON);
				irq_mask(INT_TIMER4,IRQ_MASK);
				break;
		}
		*timer_ctrl_object.tcon	=tcon;
		return 1;
	}	
}

//设置系统的时钟滴答
void set_sched_freq(unsigned int freq)
{
	timer_enable(TIMER_0,freq);

}

extern struct task_struct* task[128];

//Timer0 中断服务例程
void do_timer0(struct cpu_registers *regs)
{
	int sp;
	irq_mask(INT_TIMER0,IRQ_MASK);
	timer_ctrl_object.timer_cnt0++;
	
	//若当前任务运行在内核态,则stime增一
	if(current->cpu_registers.cpsr&SystemMode)
		current->stime++;
	else//若当前任务运行在用户态,则utime增一
		current->utime++;

	//当前进程时间片递减
	current->counter--;
		
	/*对当前任务的信号位图进行识别处理*/
	for(current_singal=0;current_singal<NSIG;current_singal++)
	{
		if((current->signal)&(1<<current_singal))
		{
			current->signal&=~(1<<current_singal);
			do_signal_irq(current_singal,regs);
			break;
		}
	}
	jiffies++;		//时钟滴嗒增1
	
	if(jiffies%10==0)
	{
		*led=0;
	}
	else
	{
		*led=1<<4;
	}
	
	switch_to_next(regs,schedule());		// 进行任务调度
	
	clean_src_pnd(INT_TIMER0);
	clean_int_pnd(INT_TIMER0);
	irq_mask(INT_TIMER0,IRQ_UNMASK);
}

//Timer1 中断服务例程
void do_timer1(struct cpu_registers *regs)
{
	irq_mask(INT_TIMER1,IRQ_MASK);
	timer_ctrl_object.timer_cnt1++;
	
	//在这里添加timer1的中断功能代码
	//
		printk("timer1 \n");
	clean_src_pnd(INT_TIMER1);
	clean_int_pnd(INT_TIMER1);
	irq_mask(INT_TIMER1,IRQ_UNMASK);
}

//Timer2 中断服务例程
void do_timer2(struct cpu_registers *regs)
{
	irq_mask(INT_TIMER2,IRQ_MASK);
	timer_ctrl_object.timer_cnt2++;
	
	//在这里添加timer2的中断功能代码
	//
		printk("timer2 \n");
	clean_src_pnd(INT_TIMER2);
	clean_int_pnd(INT_TIMER2);
	irq_mask(INT_TIMER2,IRQ_UNMASK);
}

//Timer3 中断服务例程
void do_timer3(struct cpu_registers *regs)
{
	irq_mask(INT_TIMER3,IRQ_MASK);
	timer_ctrl_object.timer_cnt3++;
	
	//在这里添加timer3的中断功能代码
	//
		printk("timer3 \n");
	clean_src_pnd(INT_TIMER3);
	clean_int_pnd(INT_TIMER3);
	irq_mask(INT_TIMER3,IRQ_UNMASK);	
}

//Timer4 中断服务例程
void do_timer4(struct cpu_registers *regs)
{
	irq_mask(INT_TIMER4,IRQ_MASK);
	timer_ctrl_object.timer_cnt4++;
	
	//在这里添加timer3的中断功能代码
	//
		printk("timer4 \n");
	clean_src_pnd(INT_TIMER4);
	clean_int_pnd(INT_TIMER4);
	irq_mask(INT_TIMER4,IRQ_UNMASK);	
}

⌨️ 快捷键说明

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