This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

定时器 实现 1S 定时

刚刚入职的新人,CPU 是 3358,想通过 timer3 定时器,实现1S的定时(其实是 200us 和 600 us,为了验证方便,就用 1s),自己去配置寄存器,定时器就是不工作,实现找不到解决的办法了,求前辈们或者 TI 的前辈,指导一下。
求知识,求指导
#define TIMER3_IRQ_3358 69


#define TIMER3_BASE 0x48042000 // 定时器基地址
#define CM_PER 0x44E00000 // clock management
#define CM_DPLL 0x44E00500 // 锁相环,用于倍频
#define CM_WKUP 0x44E0_0400 // Clock Module Wakeup Registers





volatile unsigned long * IRQWAKEEN = NULL;

volatile unsigned long * IRQENABLE_SET = NULL;
volatile unsigned long * IRQENABLE_CLR = NULL;
volatile unsigned long * IRQSTATUS = NULL;

volatile unsigned long * CM_PER_TIMER3_CLKCTRL = NULL;

volatile unsigned long * CLKSEL_TIMER3_CLK = NULL;
volatile unsigned long * TIMET3_TLDR = NULL;

volatile unsigned long * TIMER3_TCLR = NULL;


#define GPIO_TO_PIN(bank, gpio) (32 * (bank) + (gpio))

static int timer_init(void);

long motor_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{


switch (cmd){
case 0:
break;
case 1:
break;
}

return 0;
}


/*
 * motor open routine. 
 * 
 */
int motor_open(struct inode * inode, struct file * file)
{
int ret;

// 1、检测 GPIO 的合法性
ret = gpio_is_valid(GPIO_TO_PIN(1,16));
if(ret < 0) {
printk("failed gpio_is_valid GPIO_TO_PIN(1,16) \n");
return ret;
}
else
printk("valid OK\n");

// 2、注册/申请 GPIO 
ret = gpio_request(GPIO_TO_PIN(1, 16),"GPIO_OUT");
if(ret < 0) {
printk("failed gpio_request GPIO_TO_PIN(1,16)\n");
return ret;
}
else
printk("request gpio GPIO_TO_PIN(1,16) OK \n");

// 3、设置为输出,且设置为低电平
gpio_direction_output(GPIO_TO_PIN(1, 16), 0);
if(ret < 0) {
printk("failed gpio_direction_output GPIO_TO_PIN(1,16)\n");
return ret;
}
else
printk("gpio_direction_output(GPIO_TO_PIN(1, 16), 0) OK\n");

// 4、设置 GPIO 为高电平
gpio_set_value(GPIO_TO_PIN(1, 16), 1);


// 定时器 初始化
timer_init();


    return 0;
}

/*
 * motor close routine. 
 * do nothing.
 */
 
int motor_close(struct inode * inode, struct file * file)
{
    return 0;
}

int motor_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{

return 0;  
}


/*
 *  The various file operations we support.
 */
 
static struct file_operations motor_fops = {
.owner     = THIS_MODULE,
.unlocked_ioctl = motor_ioctl,
.open    = motor_open,
.write = motor_write,
.release   = motor_close
};

static struct miscdevice motor_dev = {
MISC_DYNAMIC_MINOR,
"gpio_motor",
&motor_fops,
};



static irqreturn_t timer_interrupt(int irq,void * dev_id)
{
int step = 0;

printk("%s,%d\n",__FUNCTION__,__LINE__);

// 4097
// 当中断发生的时候,就清除中断,
if ( (readl(IRQSTATUS)) & 0x2 ){   
// 200 us 到了
writel(~0, IRQENABLE_CLR);   // 4099

count++;
step++;
}
gpio_set_value(GPIO_TO_PIN(1, 16), 1);
if( count ==  2){
gpio_set_value(GPIO_TO_PIN(1, 16), 0);
count = 0;
}
// 中断函数处理完毕
return IRQ_HANDLED;
}


// 硬件定时器的初始化
// 定时器选用 timer0,timer0 指定了时钟只能是 32KHz

static int timer_init(void)
{
unsigned int val;
int ret;

printk("%s,%d\n",__FUNCTION__,__LINE__);

// timer3 936 开启时钟模式
// 1、允许我们去访问寄存器 ,// CM_PER_TIMER3_CLKCTRL
val = 0x02;
writel(val, CM_PER_TIMER3_CLKCTRL);
printk("%s,%d\n",__FUNCTION__,__LINE__);

// 2、关闭定时器
val = 0x00;
writel(val, TIMER3_TCLR);
printk("%s,%d\n",__FUNCTION__,__LINE__);


// 3、选择、设置、时钟,选择为 32 KHz, // 1035,
val = 0x02;
writel(val, CLKSEL_TIMER3_CLK);
printk("%s,%d\n",__FUNCTION__,__LINE__);


// 4、装载初值 4104,也就是说,周期是 31.25 微秒
// 32 KHz == 0.03125 * 10(-3) 毫秒, 那么 200 us -->> 200 / 31.25= 6.4
// 4104 ,故意设置为 1 S,6.4 X = 1 000 000 ,X->> 32 000
// 这个步骤要不要,貌似应该不用装载了吧,
writel(32000, TIMET3_TLDR); // timer load register,完成数值的加载,
printk("%s,%d\n",__FUNCTION__,__LINE__);

// 4100,中断唤醒使能,
val = 0;
val |= ((1<<2) | (1<<1) | (1<<0));
writel(val, IRQWAKEEN);
printk("%s,%d\n",__FUNCTION__,__LINE__);

// 中断使能 4098
val = 0;
val |= (1<<1); //((1<<2) | (1<<1) | (1<<0));
writel(val, IRQENABLE_SET);
printk("%s,%d\n",__FUNCTION__,__LINE__);


// 5、定时器开始, 4101
val = 0x03;
writel(val, TIMER3_TCLR);
printk("%s,%d\n",__FUNCTION__,__LINE__);

// 注册中断,213
ret=request_irq(TIMER3_IRQ_3358,timer_interrupt,IRQF_SHARED,TIMER_NAME,(void*)&key_event);
if(ret<0)
{
printk("IRQ %d can not request,ret = %d \n",TIMER3_IRQ_3358,ret);
return ret;
}
printk("%s,%d\n",__FUNCTION__,__LINE__);
return 0;

}
printk("%s,%d\n",__FUNCTION__,__LINE__);
return 0;
}
static int __init motor_init(void)
{  
    int ret = 0;
//WKUP_TIMER0_CLKCTR = (volatile unsigned long *)ioremap(TIMER2_BASE + 0x10, 4);

TIMER3_CLKCTRL = (volatile unsigned long *)ioremap(TIMER3_BASE + 0x84, 4);
CLKSEL_TIMER3_CLK =(volatile unsigned long *)ioremap(TIMER3_BASE + 0x0c, 4);
TIMET3_TLDR = (volatile unsigned long *)ioremap(TIMER3_BASE + 0x40, 4);
IRQWAKEEN = (volatile unsigned long *)ioremap(TIMER3_BASE + 0x34, 4);
IRQENABLE_SET = (volatile unsigned long *)ioremap(TIMER3_BASE + 0x2c, 4);
IRQSTATUS = (volatile unsigned long *)ioremap(TIMER3_BASE + 0x28, 4);
IRQENABLE_CLR = (volatile unsigned long *)ioremap(TIMER3_BASE + 0x30, 4);



key_event.state = KEY_NONE;


ret = misc_register(&motor_dev);
    if(ret)
    {
        DBG("could not register gpio devices. \n");
        return ret;
    }
    printk("gpio motor  driver insmod successful!\n");


    return ret;
}

static void __exit motor_exit(void)
{
    misc_deregister(&motor_dev);
    free_irq(TIMER3_IRQ_3358,(void*)&key_event);
gpio_free(GPIO_TO_PIN(1, 16));
    printk("gpio driver exit successful!\n");
}

module_init(motor_init);
module_exit(motor_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("carlos");