主题 : tiny6410还有5个定时器中还有哪个可用的 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 57071
精华: 0
发帖: 7
金钱: 35 两
威望: 7 点
综合积分: 14 分
注册时间: 2011-10-18
最后登录: 2011-11-11
楼主  发表于: 2011-11-04 17:41

 tiny6410还有5个定时器中还有哪个可用的

在超级终端中输入cat proc/interrupts后:
98:          2   s3c-timer  pwm_timer2
99:     453627   s3c-timer  1-wire Timer Tick
100:      14003   s3c-timer  pwm_timer4
好像timer2~timer4都已被占用了。我想用3个定时器,有什么解决办法?
自由,自强,共享,共创。
级别: 论坛版主
UID: 12573
精华: 27
发帖: 8838
金钱: 46490 两
威望: 9298 点
综合积分: 18216 分
注册时间: 2010-01-09
最后登录: 2019-07-16
1楼  发表于: 2011-11-04 17:43
可以试试98, 100对应的timer
新手如何向我们反馈有效的信息,以便解决问题,见此贴:
http://www.arm9home.net/read.php?tid-14431.html

[注]: 此处签名链接仅为指引方向,而非解答问题本身.
级别: 新手上路
UID: 57071
精华: 0
发帖: 7
金钱: 35 两
威望: 7 点
综合积分: 14 分
注册时间: 2011-10-18
最后登录: 2011-11-11
2楼  发表于: 2011-11-07 08:35

 回 1楼(mindee) 的帖子

试了, 驱动加载失败,提示“Device or resources busy” 是不是已经被别的设备使用了?
级别: 新手上路
UID: 57071
精华: 0
发帖: 7
金钱: 35 两
威望: 7 点
综合积分: 14 分
注册时间: 2011-10-18
最后登录: 2011-11-11
3楼  发表于: 2011-11-07 10:42

 回 1楼(mindee) 的帖子

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/poll.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <plat/regs-timer.h>
#include <mach/regs-irq.h>
#include <asm/mach/time.h>
#include <linux/clk.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/miscdevice.h>

#include <mach/map.h>
#include <plat/gpio-cfg.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#include <mach/gpio-bank-e.h>
#include <mach/gpio-bank-k.h>

#include <linux/timer.h>
#include <linux/irq.h>

#define DEVICE_NAME "iopwm"
#define iopwm_irq IRQ_TIMER2

struct cdev *iopwm_cdev;
unsigned int counter=0;
unsigned int pwm[]={3,55};
unsigned long tmp;

static irqreturn_t iopwm_interrupt(int irq , void *dev_id){
    if(irq != IRQ_TIMER2){
    printk("bad irq % d in timer0 \n", irq);
    return -1;
    }

    /*counter++;
    if(counter == pwm[0]){
        tmp = readl(S3C64XX_GPEDAT);
        tmp |= (0x4);
        writel(tmp, S3C64XX_GPEDAT);
    }

    if(counter == pwm[1]){
        tmp = readl(S3C64XX_GPEDAT);
        tmp |= (0x10);
        writel(tmp, S3C64XX_GPEDAT);
    }

    if(counter == 600){
        tmp = readl(S3C64XX_GPEDAT);
        tmp &= ~(0x14);
        writel(tmp, S3C64XX_GPEDAT);
        counter = 0;
    }*/

    tmp = readl(S3C64XX_GPKDAT);
    if(tmp & 0x10){
        tmp &= ~(0x10);
        writel(tmp, S3C64XX_GPKDAT);
    }else{
        tmp |= (0x10);
        writel(tmp, S3C64XX_GPKDAT);
    }

    /*counter++;
    if(counter == 1){
        tmp = readl(S3C64XX_GPKDAT);
        tmp &= ~(0x10);
        writel(tmp, S3C64XX_GPKDAT);
    }else if(counter == pwm[0]){
        tmp = readl(S3C64XX_GPKDAT);
        tmp |= (0x10);
        writel(tmp, S3C64XX_GPKDAT);
        counter = 0;
    }*/

    return IRQ_RETVAL(IRQ_HANDLED);
}

void iopwm_timerinit(void){
    unsigned long tcfg0,tcfg1,tcon,cstat;
    struct clk *clk_p;
    unsigned long pclk,tcnt,tcmp;
    unsigned long freq=2;

    {
        unsigned temp;
        temp = readl(S3C64XX_GPEPUD);
        temp = (temp & ~(0x33U<<4))|(0x22U<<4); //设置GPE2 和GPE4口上拉
        writel(temp, S3C64XX_GPEPUD);

        temp = readl(S3C64XX_GPECON);
        temp = (temp & ~(0x0f0fU<<8))|(0x0101U<<8); //设置GPE2 和GPE4口为输出
        writel(temp, S3C64XX_GPECON);

        temp = readl(S3C64XX_GPEDAT);
        temp |= (0x14);
        writel(temp, S3C64XX_GPEDAT);

        tmp = readl(S3C64XX_GPKCON);    //设置GPK口
        tmp = (tmp & ~(0xffffU<<16))|(0x1111U<<16);
        writel(tmp, S3C64XX_GPKCON);
        
        tmp = readl(S3C64XX_GPKDAT);
        tmp |= (0xF << 4);
        writel(tmp, S3C64XX_GPKDAT);
    }

    tcon = __raw_readl(S3C_TCON);
    tcfg1 = __raw_readl(S3C_TCFG1);
    tcfg0 = __raw_readl(S3C_TCFG0);

    //prescaler = 50
    tcfg0 &= ~S3C_TCFG_PRESCALER1_MASK;
    tcfg0 |= (50 - 1);

    //mux = 1/16
    tcfg1 &= ~S3C_TCFG1_MUX2_MASK;
    tcfg1 |= S3C_TCFG1_MUX2_DIV16;

    __raw_writel(tcfg1, S3C_TCFG1);
    __raw_writel(tcfg0, S3C_TCFG0);


    clk_p = clk_get(NULL, "pclk");
    pclk = clk_get_rate(clk_p);
    tcnt = (pclk/50/16)/freq;
    printk("TCNT is %ld\n",tcnt);
    __raw_writel(tcnt, S3C_TCNTB(2));
    __raw_writel(0, S3C_TCMPB(2));

    //定时器1中断使能
    cstat = __raw_readl(S3C_TINT_CSTAT);
    //cstat &=~S3C_TINT_CSTAT_T0INTEN;
    cstat |=0x4;
    __raw_writel(cstat,S3C_TINT_CSTAT);

    tcon &= ~0xf01<<4;
     tcon |= 0xb<<12; //disable deadzone, auto-reload, inv-off, update TCNTB0&TCMPB0, start timer 1
    __raw_writel(tcon, S3C_TCON);

    tcon &= ~0x2<<12; //clear manual update bit
    __raw_writel(tcon, S3C_TCON);
    printk("init iopwm success!\n");
    tcmp = __raw_readl(S3C_TCMPB(2));
    printk("tcmp is %ld\n",tcmp);
}

static int iopwm_open(struct inode *inode,struct file *filp){  
    printk("Register iopwm success!\n");
    return 0;
}

static long iopwm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){
    //unsigned long tcmp=0;

    switch (cmd){
        case 0:

            //pwm[0]=arg;
            break;
        case 1:
            //pwm[1]=arg;
            break;
        default:
            return -EINVAL;
    }
    return 0;
}

static int iopwm_close(struct inode *inode,struct file *filp){
    // free_irq(iopwm_irq,NULL);
    return 0;
}

static struct file_operations iopwm_fops={
    .owner=THIS_MODULE,
    .open=iopwm_open,
    .unlocked_ioctl=iopwm_ioctl,
    .release=iopwm_close,
};

static struct miscdevice misc = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DEVICE_NAME,
    .fops = &iopwm_fops,
};

static int __init iopwm_init(void){
    int ret;
    ret = misc_register(&misc);
    printk (DEVICE_NAME"\tinitialized\n");

    iopwm_timerinit();
    ret=request_irq(iopwm_irq,iopwm_interrupt, IRQF_SHARED, DEVICE_NAME, NULL);
    printk("IRQ num is:%d\n", iopwm_irq);
    if(ret<0){
    printk("Register IOPWM failed!\n");
    return ret;
    }

    printk("Register iopwm success!\n");
    return ret;
}

static void __exit iopwm_exit(void){
    tmp = readl(S3C64XX_GPKDAT);
    tmp |= (0x10);
    writel(tmp, S3C64XX_GPKDAT);

    printk("remove device\n");

    free_irq(iopwm_irq,NULL);
    misc_deregister(&misc);
}

module_init(iopwm_init);
module_exit(iopwm_exit);

我的代码,有什么问题吗?IRQF_SHARED是不是没有这个参数啊,我想共享中断,但这个参数好像会导致invalid argument的错误
^很多问题的背后都是简单的原因......
级别: 荣誉会员
UID: 34780
精华: 0
发帖: 1219
金钱: 6230 两
威望: 1246 点
综合积分: 2438 分
注册时间: 2010-12-21
最后登录: 2017-09-18
4楼  发表于: 2011-11-07 12:03
如果中断已经被使用且没有注册为shared,那么你再申请肯定会失败的