免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: vincent_zs
打印 上一主题 下一主题

写PWM驱动玩,居然发现一个奇怪的问题!(附代码) [复制链接]

论坛徽章:
0
11 [报告]
发表于 2009-03-30 08:29 |只看该作者

代码来了!再问个问题

代码是按照我写的裸机程序改过来的,写的比较简单。有什么不好的地方,还请过路的高手们指出来!  还有就是看看为什么会引起死机啊?(考虑了一下,会不会是代码影响了串口啊?或者使跑的系统出了点问题?) 最后一个问题就是在代码中,我起初在犹豫要不要用clk_get(NULL, "pwmt";等函数来获取时钟,但我又不知道第二个参数可以写什么。(以前写触摸屏驱动,可以用“ADC”的),结果是在这个驱动中不需要这个函数。到底怎么用呢?

#include<linux/module.h>
#include<linux/ioctl.h>
#include<linux/types.h>
#include<linux/init.h>
#include<linux/fs.h>
#include <asm/arch/regs-timer.h>
#include<linux/cdev.h>
#include<asm/semaphore.h>
#include <linux/delay.h>
#include<linux/slab.h>
#include<linux/mm.h>
#include <asm/arch/regs-gpio.h>
#include <asm/hardware.h>
#include <asm/arch/regs-irq.h>
#include <asm/mach/time.h>
#include <asm/hardware/clock.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#define STOP_PWM 1
#define SET_PWM  2
#define DEVICE_NAME "WM"
#define PWM_MAJOR 233
//static struct clk       *pwm_clock;

struct pwm_device
{
        struct cdev cdev;
        struct semaphore sem;
       
};

struct pwm_device *pwm_dev;

void PWM_Freq_Init(void)
{
        unsigned long tcon=0;
        //unsigned long tcnt;
        unsigned long tcfg1;
        unsigned long tcfg0;
        tcfg0=__raw_readl(S3C2410_TCFG0);
        tcfg1=__raw_readl(S3C2410_TCFG1);
        tcfg0&=0;
        tcfg0|=1;
        tcfg1&=0;
         __raw_writel(tcfg0, S3C2410_TCFG0);
         __raw_writel(tcfg1, S3C2410_TCFG1);
        // tcfg1 = __raw_readl(S3C2410_TCFG1);

        __raw_writel(100, S3C2410_TCNTB(1));
        __raw_writel(20, S3C2410_TCMPB(1));
        tcon|=((0<<11)|(1<<10)|(1<<9)|(0<<);//manual updata
        __raw_writel(tcon,S3C2410_TCON);
        mdelay(10);
        tcon&=0;
        tcon|=((1<<11)|(1<<10)|(0<<9)|(1<<);//auto load
        __raw_writel(tcon,S3C2410_TCON);
      // printk(KERN_INFO"init ok!\n";

}
void PWM_Stop( void )
{
        //set GPB0 as output
        s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB0_OUTP);
        s3c2410_gpio_setpin(S3C2410_GPB1, 0);
        //printk(KERN_INFO"stop Pwm ok!\n";
}
static int pwm_dev_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
//  volatile unsigned int dd;
//        down((&pwm_dev->sem));
        //        dd=cmd;
//                dd=dd+1;
//                printk(KERN_INFO"%d\n",dd);
            arg=100-arg;
           switch (cmd)
       {
                case SET_PWM:
                        if (arg == 0)
                                return -EINVAL;
                         __raw_writel(arg, S3C2410_TCMPB(1));       
                         printk(KERN_INFO"set pwm ok!\n";
                        //PWM_Set_Freq(arg);
                        break;
                                                                                
               case STOP_PWM:
                      PWM_Stop();
                      printk(KERN_INFO"stop Pwm ok!\n";
                      break;
                default:
                   //   printk(KERN_INFO"default>????!\n";
                         
                break;

        
        }
//        printk(KERN_INFO"set pwm ok!\n";
     // up(&(pwm_dev->sem));
     return 0;

       
}
static int pwm_dev_open(struct inode *inode, struct file *file)
{   
         // pwm_clock = clk_get(NULL, "pwmt";
        //if (!pwm_clock)
//        {
             //   printk(KERN_ERR "failed to get adc clock source\n";
             //   return -ENOENT;
      //  }
      //  clk_use(pwm_clock);
      //  clk_enable(pwm_clock);
        //down(&(pwm_dev->sem));

        init_MUTEX(&(pwm_dev->sem));
        down(&(pwm_dev->sem));
        s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);
        s3c2410_gpio_setpin(S3C2410_GPB0,0);
        s3c2410_gpio_cfgpin(S3C2410_GPB1, S3C2410_GPB1_TOUT1);
        PWM_Freq_Init();
        printk(KERN_INFO"open ok!\n";
        return 0;
}
static int pwm_dev_close(struct inode *inode, struct file *file)
{
       
    printk(KERN_INFO"close file  ok!\n");
    up(&(pwm_dev->sem));
    return 0;

}
                                                                                

static const struct file_operations pwm_fops=
{
        .owner=THIS_MODULE,
        .open=pwm_dev_open,
        .release=pwm_dev_close,
        .ioctl=pwm_dev_ioctl,
};




static int __init pwm_dev_init(void)
{
        int ret,err;
        dev_t devno;
        devno=MKDEV(PWM_MAJOR,0);
        ret=register_chrdev_region(devno,1,DEVICE_NAME);
        if(ret<0)
        {
        unregister_chrdev_region(devno,1);
        return ret;
        }
        pwm_dev=kmalloc(sizeof(struct pwm_device),GFP_KERNEL);//GHP_KERNEL can cause blocking when erro occurs
        if(!pwm_dev)
        {
           ret = -ENOMEM;
          goto fail_kmalloc;
        }

         memset(pwm_dev,0,sizeof(struct pwm_device));
        cdev_init(&pwm_dev->cdev,&pwm_fops);
        pwm_dev->cdev.owner=THIS_MODULE;
        err=cdev_add(&pwm_dev->cdev,devno,1);
        //if success, return 0;
        if(err)
        {
        printk(KERN_INFO"add cdev failing!\n");
        }
        printk(KERN_INFO"success add  modules\n");
        return 0;
        fail_kmalloc:unregister_chrdev_region(devno,1);
                    printk(KERN_ERR"fail to register the device\n");
                   return 1;
}

static void __exit pwm_dev_exit(void)
{
  cdev_del(&pwm_dev->cdev);
  unregister_chrdev_region(MKDEV(PWM_MAJOR,0),1);
  kfree(pwm_dev);
  printk(KERN_INFO"module exit!\n");
}


module_init(pwm_dev_init);
module_exit(pwm_dev_exit);
                                                                                
                                                                                
MODULE_AUTHOR("vincent_zou");
MODULE_DESCRIPTION("wm driver");
MODULE_LICENSE("GPL");
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP