忘了贴代码
/* timer0.c
* Copyright (C) by Tymanium from china
* this is a device module file used for SBC2410
* it can drive timer0, and in interrupt routine it will inverse GPB0 to generate tooth wave. Surely, it's very easy
*/
/*Usage:
1. arm-linux-gcc -D__KERNEL__ -I/friendly-arm/kernel/include -DKBUILD_BADENAME=test -DMODULE -c -o timer0.o timer0.c
2. start your SBC2410 EVBOARD
3. copy timer0.o to /lib
4. in your board bash run # insmod /lib/timer0.o ,and now you can inspect GPB0 on your OSC
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/miscdevice.h>
#include <linux/sched.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <asm/hardware.h>
//#include "S3C2410SFR.h"
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <asm/arch/regs-rtc.h>
#include <asm/arch/regs-timer.h>
#include <asm/arch/regs-gpio.h>
#define DEVICE_NAME "timer0_test" //
#define IOPORT_MAJOR 200
//#define Ftclk 1000000
#define FCLK (202.80*1000000) // Output Frequency 202.80MHz.
#define HCLK (FCLK/2) // 101.40MHz
#define PCLK (FCLK/4) // 50.70MHz
#define LED_ON 0
#define LED_OFF 1
#define LED1_PIN S3C2410_GPF4
#define LED2_PIN S3C2410_GPF5
#define LED3_PIN S3C2410_GPF6
#define LED4_PIN S3C2410_GPF7
#define DEVICE_NAME "timer0_test" //
#define IOPORT_MAJOR 200
static unsigned int counter;
static unsigned char flag;
static DECLARE_WAIT_QUEUE_HEAD(timer0_wait);
/*timer0 interrupt routine*/
static irqreturn_t timer0_interrupt(int irq , void *dev_id, struct pt_regs *reg)
{
if(flag != 1)
{
s3c2410_gpio_setpin(LED1_PIN,LED_ON);
//s3c2410_gpio_setpin(LED2_PIN,LED_ON);
//s3c2410_gpio_setpin(LED3_PIN,LED_ON);
//s3c2410_gpio_setpin(LED4_PIN,LED_ON);
flag = 1;
}
else
{
s3c2410_gpio_setpin(LED1_PIN,LED_OFF);
//s3c2410_gpio_setpin(LED2_PIN,LED_OFF);
//s3c2410_gpio_setpin(LED3_PIN,LED_OFF);
//s3c2410_gpio_setpin(LED4_PIN,LED_OFF);
flag = 0;
}
return IRQ_HANDLED;
}
/*this function is called when you use insmod */
static int __init timer0_init(void)
{
int ret;
unsigned long Ftclk;
unsigned int tcfg0,tcfg1,tcon;
tcfg0 = inl(S3C2410_TCFG0);
tcfg1 = inl(S3C2410_TCFG1);
tcon = inl(S3C2410_TCON);
outl((tcfg0 &= ~0xff) | 49,S3C2410_TCFG0); //设置预分频
outl((tcfg1 &= ~0xf) | 0,S3C2410_TCFG1); //设置分频和模式
Ftclk=50000000/49/2/10000; //参考datasheet公式
outl(Ftclk,S3C2410_TCNTB(0)); //写入定时初值
outl(0,S3C2410_TCMPB(0)); //写入终点比较值
outl(tcon | S3C2410_TCON_T0MANUALUPD,S3C2410_TCON); //手动刷新一次,将数据装入TCNT和TCMP
tcon = inl(S3C2410_TCON) & ~S3C2410_TCON_T0MANUALUPD;
outl(tcon | (S3C2410_TCON_T0START|S3C2410_TCON_T0RELOAD),S3C2410_TCON);
ret=request_irq(IRQ_TIMER0,&timer0_interrupt,SA_INTERRUPT,DEVICE_NAME,NULL);
if(ret<0){
printk("Register IRQ_TIMER0 failed!\n");
return ret;
}
/*配置IO口*/
s3c2410_gpio_cfgpin(LED1_PIN,S3C2410_GPF4_OUTP);
s3c2410_gpio_cfgpin(LED2_PIN,S3C2410_GPF5_OUTP);
s3c2410_gpio_cfgpin(LED3_PIN,S3C2410_GPF6_OUTP);
s3c2410_gpio_cfgpin(LED4_PIN,S3C2410_GPF7_OUTP);
/*初始化IO电平*/
s3c2410_gpio_setpin(LED1_PIN,LED_OFF);
s3c2410_gpio_setpin(LED2_PIN,LED_OFF);
s3c2410_gpio_setpin(LED3_PIN,LED_OFF);
s3c2410_gpio_setpin(LED4_PIN,LED_OFF);
counter = 0;
return ret;
}
/*this function is called when you use rmmod*/
static void __exit timer0_cleanup(void)
{
free_irq(IRQ_TIMER0,NULL);
}
module_init(timer0_init);
module_exit(timer0_cleanup);
MODULE_LICENSE("GPL");