明远智睿技术论坛

 找回密码
 立即注册
搜索
查看: 2862|回复: 0
打印 上一主题 下一主题

linux3.14.52 imx6s epit1比较不能输出波形问题,请教相关技术...

[复制链接]

1

主题

1

帖子

19

积分

新手上路

Rank: 1

积分
19
跳转到指定楼层
楼主
发表于 2017-2-15 17:50:35 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
已编写驱动,在init时已经配置epit为比较输出翻转方式,但加载驱动时没有波形输出。
配置方式及驱动代码如下:

在dtsi中增加配置                        epit1: epit@020d0000 { /* EPIT1 */
                                compatible = "fsl,imx6q-epit1";
                                reg = <0x020d0000 0x4000>;
                                interrupts = <0 56 IRQ_TYPE_LEVEL_HIGH>;
                        };

                pinctrl_epit1pwm1: epit1pwmgroup {
                        fsl,pins = <
                                MX6QDL_PAD_GPIO_7__EPIT1_OUT                0x1b0b1
                        >;
                };


&epit1 {
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_epit1pwm1>;
        status = "okay";
};


clk-imx6q.c中imx6q_clocks_init函数中添加如下代码
clk[IMX6QDL_CLK_EPIT1]        = imx_clk_gate2("epit1",        "ipg_per",            base + 0x6c, 12);
clk_register_clkdev(clk[IMX6QDL_CLK_EPIT1], "per", "imx-epit.1");

编译内核并烧录,再动态加载imx6epit的驱动,驱动代码如下
struct semaphore lock;
static void __iomem *epitbase;
float fFeq = 50.0f; // 频率
int myirq;

#define DEV_NAME "mypwm"

static int mypwm_open(struct inode *inode, struct file *file);
static int mypwm_close(struct inode *inode, struct file *file);
static long mypwm_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
static irqreturn_t epit_timer_interrupt(int irq, void *dev_id);

static struct file_operations pwm_fops =
{
    .owner = THIS_MODULE,
        .open = mypwm_open,
        .release = mypwm_close,
    .unlocked_ioctl = mypwm_ioctl
};

static struct miscdevice pwm_misc =
{
    .minor = MISC_DYNAMIC_MINOR,
    .name = "mypwm",             //dev/mypwm
    .fops = &pwm_fops
};

static int myPWM_Init(void)
{
        struct device_node *node;
        struct clk *timer_clk;
        uint32_t nCycle;
        uint32_t epitcr;
        int ret;
       
        node = of_find_compatible_node(NULL, NULL,"fsl,imx6q-epit1");
        if(node)
        {
                epitbase = of_iomap(node, 0);
                myirq = irq_of_parse_and_map(node, 0);
        }
        else
        {
                printk("find compatible err\r\n");
                return -1;
        }

        timer_clk = clk_get_sys("imx-epit.1", "per");
        if (IS_ERR(timer_clk))
        {
                printk("clk get sys err\r\n");
                return -1;
        }
        clk_prepare_enable(timer_clk);

        printk("base=%X epit clock=%ld\r\n", (uint32_t)epitbase, clk_get_rate(timer_clk));

        __raw_writel(0, epitbase+EPITCR);
        __raw_writel(0xffffffff, epitbase + EPITLR);
        epitcr = EPITCR_CLKSRC_REF_HIGH | EPITCR_OM_TOGGLE | EPITCR_WAITEN | EPITCR_STOPEN | EPITCR_IOVW
                                | (EPITCR_CLKDIV(66))| EPITCR_RLD | EPITCR_ENMOD;
        __raw_writel(epitcr, epitbase + EPITCR);

        // LR
        nCycle = 20000-1;
        __raw_writel(nCycle, epitbase+EPITLR);
       
        // compare nCycle+10
        __raw_writel(10000+1, epitbase+EPITCMPR);

        // pin altfunction 引脚复用中配置
       
        // enable epit
        __raw_writel(epitcr|EPITCR_EN , epitbase+EPITCR);

        ret = request_irq(myirq, &epit_timer_interrupt, 0, DEV_NAME, epitbase);

        return ret;
}

static int myPWM_UnInit(void)
{
        free_irq(myirq, epitbase);
        return 0;
}

static inline void epit_irq_disable(void)
{
        u32 val;

        val = __raw_readl(epitbase + EPITCR);
        val &= ~EPITCR_OCIEN;
        __raw_writel(val, epitbase + EPITCR);
}

static inline void epit_irq_enable(void)
{
        u32 val;

        val = __raw_readl(epitbase + EPITCR);
        val |= EPITCR_OCIEN;
        __raw_writel(val, epitbase + EPITCR);
}

static void epit_irq_acknowledge(void)
{
        __raw_writel(EPITSR_OCIF, epitbase + EPITSR);
}

static void myPWM_Stop(void)
{
        uint32_t epitcr;

        // disable irq
        epitcr = __raw_readl(epitbase + EPITCR);
        __raw_writel(epitcr&(~ EPITCR_EN) , epitbase + EPITCR);
}

static void myPWM_SetFreq(uint32_t nFreq)
{
        // disable irq

       
        // enable irq
}

static void myPWM_SetDuty(float nDutyPercent)
{
}



static irqreturn_t epit_timer_interrupt(int irq, void *dev_id)
{
        epit_irq_acknowledge();
        // first clear, second set
       
        return IRQ_HANDLED;
}


static int mypwm_open(struct inode *inode, struct file *file)
{
    if (!down_trylock(&lock)) //是否获得信号量,是 down_trylock(&lock)=0,否则非 0
        return 0;
    else
        return -EBUSY; //返回错误信息:请求的资源不可用
}

static int mypwm_close(struct inode *inode, struct file *file)
{
    myPWM_Stop();
    up(&lock); //释放信号量 lock
    return 0;
}


static long mypwm_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
    switch (cmd)
        {
                case PWM_DUTY:
                        break;
        case PWM_PERIOD: //if cmd=1 即进入 case PWM_IOCTL_SET_FREQ
            if (arg == 0) //如果设置的频率参数是 0
                return -EINVAL; //返回错误信息,表示向参数传递了无效的参数
            //PWM_Set_Freq(arg); //否则设置频率
            break;
        case PWM_OFF: // if cmd=2 即进入 case PWM_IOCTL_STOP
            myPWM_Stop();
            break;
                default:
                        break;
    }

        return 0;
}

static int pwm_init(void)
{
    int ret;
        sema_init(&lock, 1);
    printk ("\tmypwm initializ...\r\n");
        ret = myPWM_Init();
    if (ret < 0)
        {
                return ret;
        }       
    printk ("\tmypwm initialized\r\n");
       
    ret = misc_register(&pwm_misc); //注册一个 misc 设备       
    return ret;
}

static void pwm_exit(void)
{
        myPWM_UnInit();
        misc_deregister(&pwm_misc); //注销设备
}

module_init(pwm_init);
module_exit(pwm_exit);



回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|明远智睿  

GMT+8, 2024-5-4 10:03 , Processed in 0.054103 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表