mtk pwmlinux timer

pwm控制还是有很多要注意的地方
附上驱动的代码

/** drivers/leds/leds-mt65xx.c** This file is subject to the terms and conditions of the GNU General Public* License.  See the file COPYING in the main directory of this archive for* more details.** Hydrodent weiqifa modify add**/#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/workqueue.h>
#include <linux/wakelock.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <mach/mt_pwm.h>
#include <mach/pmic_mt6329_hw_bank1.h> 
#include <mach/pmic_mt6329_sw_bank1.h> 
#include <mach/pmic_mt6329_hw.h>
#include <mach/pmic_mt6329_sw.h>
#include <mach/upmu_common_sw.h>
#include <mach/upmu_hw.h>
#include <linux/hrtimer.h>
/***************************************************************************** 现在我们的时钟源是32k ** 频率 理论上 1<f<32  但是 10<frequency<8191  所以最大的频率是3kHZ* f=32/div/frequency  div=1 frequency=pwm_setting.duration* 比如我们设置 f=1 那么我们frequency的值就应该是30 ** 占空比* 0<duty<=100* 实际测试发现 duty 值越大 测量值就越接近测试值* 并在adb 下面显示出来** 设备文件目录:/sys/class/hdyrodent* frequency:设置频率 echo 10 > frequency* duty:设置占空比 echo 50 > duty* switch:打开关闭 echo 1 >switch 大于0是打开 小于等于0是关闭**提示:如果不设置值,直接打开默认有波形***************************************************************************/static struct class *hdyrodent_pwm_class=NULL;
static int show_frequency=123;//默认分辨率变量
static int show_duty=50;//默认占空比变量
static bool show_switch=false;
static int show_stopbit=63;//这个变量可以用来控制分辨率,默认最大值是63 最小值是0#define PWM_NO PWM4
//声明定时器
static struct hrtimer timer_ptt;
static struct pwm_easy_config pwm_setting;//pwm设置的结构体/***************************************************************************** scnprintf是linux下面一个函数,这个函数把后面 的值格式话转化成字符串* 并在adb 下面显示出来***************************************************************************/
static ssize_t hdyrodent_frequency_show(struct device *dev,struct device_attribute *attr, char *buf)
{
      printk("%s\n", __FUNCTION__);      return scnprintf(buf, PAGE_SIZE, "%d\n", show_frequency);
}
/***************************************************************************** echo pwm这个节点的时候就会调用下面这个函数,echo "12" > pwm * 那么value的值就是12 可以通过这样设置pwm的数值***************************************************************************/
static ssize_t hdyrodent_frequency_store(struct class *cls, struct class_attribute *attr, const  char *_buf, size_t _count)
{
    int value=0;
    sscanf(_buf, "%d", &value);
    sscanf(_buf, "%d", &show_frequency);//把值传给show_frequency这样 cat的值就是echo 进去的值了
    printk("%s: value: %d _count:%d\n", __FUNCTION__, value,_count);
    if(value<=0)
    {
        printk("Error %s input value wrong!!!!\n",__FUNCTION__);
    }
    else
    {   
        pwm_setting.duration=value;
        pwm_set_easy_config(&pwm_setting);
        printk("Success %s \n",__FUNCTION__);
    }      return _count;
}
/***************************************************************************** scnprintf是linux下面一个函数,这个函数把后面 的值格式话转化成字符串* 并在adb 下面显示出来***************************************************************************/
static ssize_t hdyrodent_brightness_show(struct device *dev,struct device_attribute *attr, char *buf)
{
      printk("%s\n", __FUNCTION__);      return scnprintf(buf, PAGE_SIZE, "%d\n", show_duty);
}
/***************************************************************************** echo pwm这个节点的时候就会调用下面这个函数,echo "12" > pwm * 那么value的值就是12 可以通过这样设置pwm的数值***************************************************************************/
static ssize_t hdyrodent_brightness_store(struct class *cls, struct class_attribute *attr, const  char *_buf, size_t _count)
{
    int value=0;
    sscanf(_buf, "%d", &value);
    sscanf(_buf, "%d", &show_duty);//把值传给show_duty这样 cat的值就是echo 进去的值了
    printk("%s: value: %d _count:%d\n", __FUNCTION__, value,_count);
    if(value<=0)
    {
        mt_pwm_disable(PWM_NO, true);//关闭pwm波       
        printk("Error: %s disable the pwm 2\n",__FUNCTION__);
    }
    else
    {   
        pwm_setting.duty = value;
        pwm_set_easy_config(&pwm_setting);
        printk("Success: %s disable the pwm 2\n",__FUNCTION__);
    }
        return _count;
}
/***************************************************************************** scnprintf是linux下面一个函数,这个函数把后面 的值格式话转化成字符串* 并在adb 下面显示出来***************************************************************************/
static ssize_t hdyrodent_on_show(struct device *dev,struct device_attribute *attr, char *buf)
{
      printk("%s\n", __FUNCTION__);      return scnprintf(buf, PAGE_SIZE, "%d\n", show_switch);
}
/***************************************************************************** echo pwm这个节点的时候就会调用下面这个函数,echo "12" > pwm * 那么value的值就是12 可以通过这样设置pwm的数值***************************************************************************/
static ssize_t hdyrodent_on_store(struct class *cls, struct class_attribute *attr, const  char *_buf, size_t _count)
{
    int value=0;
    sscanf(_buf, "%d", &value);
    sscanf(_buf, "%d", &show_switch);//把值传给show_switch这样 cat的值就是echo 进去的值了
    printk("%s: value: %d _count:%d\n", __FUNCTION__, value,_count);
    if(value>0)
    {
        pwm_set_easy_config(&pwm_setting);
        printk("Success: %s enable the pwm 2\n",__FUNCTION__);      
    }
    else
    {
        mt_pwm_disable(PWM_NO, true);//关闭pwm波
        printk("Success: %s disable the pwm 2\n",__FUNCTION__);
    }
        return _count;
}
/***************************************************************************** __ATTR的第一个参数是在sys文件系统里面显示的名字* 0666是这个节点的属性,0666表示是可读可写* hdyrodent_frequency_show 是cat 这个文件的时候调用的函数* hdyrodent_frequency_store 是echo的时候调用的函数***************************************************************************/
static struct class_attribute hdyrodent_attr[] = {
__ATTR(frequency,0666, hdyrodent_frequency_show, hdyrodent_frequency_store),
__ATTR(brightness,0666, hdyrodent_brightness_show, hdyrodent_brightness_store),
__ATTR(on,0666, hdyrodent_on_show, hdyrodent_on_store),
__ATTR_NULL,};
/***************************************************************************** 定时中断函数***************************************************************************/
static enum hrtimer_restart timer_ptt_interrupt(struct hrtimer *timer)
{
    static unsigned int c=0;
    c++;
    printk("%s,%d,c=%d\n",__func__,__LINE__,c);
    hrtimer_start(&timer_ptt, ktime_set(1, 0), HRTIMER_MODE_REL);
    return HRTIMER_NORESTART;
}static int __init hdyrodent_pwm_init(void)
{
    int ret;
    int i = 0;    printk("%s start\n", __FUNCTION__);
    //用class_create在sys/class/下面生成sys文件系统
    hdyrodent_pwm_class=class_create(THIS_MODULE,"hdyrodent_charger_led");
    if(IS_ERR(hdyrodent_pwm_class))
    {
        printk("create hdyrodent module fail \n");
        return PTR_ERR(hdyrodent_pwm_class);;
    }    for (i = 0 ; NULL != attr_name(hdyrodent_attr[i]);i++)
    {
        ret = class_create_file(hdyrodent_pwm_class, &hdyrodent_attr[i]);
        if (0 != ret)
        {
            printk("creat %s class file fail\n",attr_name(hdyrodent_attr[i]));
            break;
        }
    }
    mt_pwm_disable(PWM_NO, true);//把pwm 功能关闭掉
    mt_set_gpio_mode(90,GPIO_MODE_06);
    pwm_setting.pwm_no = PWM_NO;//通过函数把这个gpio口设置成pwm1模式,对应pwm_no就是PWM2
    pwm_setting.pmic_pad = false;
    pwm_setting.duty=20;
    pwm_setting.duration=100; 
    pwm_setting.clk_div = CLK_DIV1;
    pwm_setting.clk_src = PWM_CLK_OLD_MODE_32K;//PWM_CLK_OLD_MODE_BLOCK;//26M
    //pwm_set_easy_config(&pwm_setting);    //定时器
    hrtimer_init(&timer_ptt, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
    timer_ptt.function = timer_ptt_interrupt;
    hrtimer_start(&timer_ptt, ktime_set(1, 0), HRTIMER_MODE_REL);
    printk("%s end\n", __FUNCTION__);    return 0;}static void __exit hdyrodent_pwm_exit(void)
{
    int i = 0;    printk("hdyrodent module cleanup start.\n");
    mt_pwm_disable(PWM_NO, true);//把pwm 功能关闭掉
    if(hrtimer_cancel(&timer_ptt))
    {
        printk("try to cancel hrtimer \n"); 
    }
    for (i = 0 ; NULL != attr_name(hdyrodent_attr[i]);i++)
    {
            class_remove_file(hdyrodent_pwm_class, &hdyrodent_attr[i]);
        }
    class_destroy(hdyrodent_pwm_class);
    printk("hdyrodent module cleanup OK!\n");
}MODULE_AUTHOR("329410527@qq.com");
MODULE_DESCRIPTION("HDYRODENT PWM MODULE");
MODULE_LICENSE("GPL");
MODULE_VERSION("ver0.1");module_init(hdyrodent_pwm_init);
module_exit(hdyrodent_pwm_exit);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/469277.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Pytorch神经网络理论篇】 31 图片分类模型:ResNet模型+DenseNet模型+EffcientNet模型

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

CentOS7 编译安装golang和rpm安装golang

编译安装 1、下载golang二进制安装包&#xff1a; https://storage.googleapis.com/golang/go1.9.linux-amd64.tar.gz 2、解压安装包到指定目录&#xff0c;此处以解压到/usr/local目录下为例&#xff1a; 1 tar -C /usr/local -xzf ../packages/go1.8.linux-amd64.tar.gz 3、在…

Class_fileAndroid应用调用方法

java代码调用 fos.write这里面是byte类型的 + private static final String LEDBLPATH="/sys/class/hdyrodent_charger_led/brightness"; + private final void SetChargerLedBrightness(String path,int brightness) + { + try{ + …

【Pytorch神经网络理论篇】 32 PNASNet模型:深层可分离卷积+组卷积+空洞卷积

1 PNASNet模型简介 PNASNet模型是Google公司的AutoML架构自动搜索所产生的模型&#xff0c;它使用渐进式网络架构搜索技术&#xff0c;并通过迭代自学习的方式&#xff0c;来寻找最优网络结构。即用机器来设计机器学习算法&#xff0c;使得它能够更好地服务于用户提供的数据。该…

s5k5e2ya MIPI 摄像头调试

1、驱动移植的话按照我之前的文章来做 驱动里面注意是几路的lane,一般mipi的话是差分信号&#xff0c;2路和4路是比较常见的。2、mipi波形 很明显上面的波形是不正确的。dp dn有一个都成了正弦波了。 首先&#xff0c;我们要找一下正确的波形 正确的波形应该是DP和DN不会同时…

css那些事儿4 背景图像

background:背景颜色&#xff0c;图像&#xff0c;平铺方式&#xff0c;大小&#xff0c;位置 能够显示背景区域即为盒子模型的填充和内容部分&#xff0c;其中背景图像将会覆盖背景颜色。常见的水平或垂直渐变颜色背景通常使用水平或垂直渐变的背景图像在水平或垂直方向平铺&a…

用Android UEventObserver监听内核event

很多时候我们在框架上层需要知道内核中某些事件的状态&#xff0c;用设备的show属性是可以供上层来查询&#xff0c;但是这需要上层设定一个较耗资源的循环。如果用UEventObserver就可以监听内核event&#xff0c;它是android Java层利用uevent与获取Kernel层状态变化的机制。 …

【Pytorch神经网络实战案例】23 使用ImagNet的预训练模型识别图片内容

1 案例基本工具概述 1.1 数据集简介 Imagenet数据集共有1000个类别&#xff0c;表明该数据集上的预训练模型最多可以输出1000种不同的分类结果。 Imagenet数据集是目前深度学习图像领域应用得非常多的一个领域&#xff0c;关于图像分类、定位、检测等研究工作大多基于此数据…

杂谈转载

一、什么是运行时&#xff08;Runtime&#xff09;? 运行时是苹果提供的纯C语言的开发库&#xff08;运行时是一种非常牛逼、开发中经常用到的底层技术&#xff09;二、运行时的作用&#xff1f; 能获得某个类的所有成员变量能获得某个类的所有属性能获得某个类的所有方法交换…

Linux中的工作队列

工作队列(work queue)是Linux kernel中将工作推后执行的一种机制。这种机制和BH或Tasklets不同之处在于工作队列是把推后的工作交由一个内核线程去执行&#xff0c;因此工作队列的优势就在于它允许重新调度甚至睡眠。 工作队列是2.6内核开始引入的机制&#xff0c;在2.6.20之后…

【Pytorch神经网络实战案例】24 基于迁移学习识别多种鸟类(CUB-200数据集)

1 迁移学习 在实际开发中&#xff0c;常会使用迁移学习将预训练模型中的特征提取能力转移到自己的模型中。 1.1 迁移学习定义 迁移学习指将在一个任务上训练完成的模型进行简单的修改&#xff0c;再用另一个任务的数据继续训练&#xff0c;使之能够完成新的任务。 1.1.1 迁…

linux工作队列

这里对Linux的工作队列(work_queue)不做深层次的挖掘&#xff0c;只对如何使用它以及一些简单的结构做简单地介绍。 Linux源代码(3.0.8)中和工作队列(work_queue)相关的结构主要在 include/linux/workqueue.h这个头文件中&#xff0c;这里就不摘抄了。这里就直接给出例子代码…

【Pytorch神经网络理论篇】 33 基于图片内容处理的机器视觉:目标检测+图片分割+非极大值抑制+Mask R-CNN模型

同学你好&#xff01;本文章于2021年末编写&#xff0c;获得广泛的好评&#xff01; 故在2022年末对本系列进行填充与更新&#xff0c;欢迎大家订阅最新的专栏&#xff0c;获取基于Pytorch1.10版本的理论代码(2023版)实现&#xff0c; Pytorch深度学习理论篇(2023版)目录地址…

linux inputuevent使用

input 输入子系统 在应用层使用的时候&#xff0c;容易出现找不到UEventObserver.java 这时候就要导入jar包 导入classes.jar这个jar包 weiqifaweiqifa-Inspiron-3847:~/weiqifa/tm100$ ls out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/ classes classes…

linq中给字段添加别名

linq 是我们在查询中经常回用到的一种形式,比如我们创建一个类,然后List<添加> 并绑定到表格中public class Modeltest{string id;public string Id{get { return id; }set { id value; }}string pwd;public string Pwd{get { return pwd; }set { pwd value; }}string…

报错 ValueError: too many values to unpack (expected 2)

enc_output,enc_slf_attn self.slf_attn(user_embedding,item_input,item_input,mask slf_attn_mask) 实际上只有一个返回值&#xff0c;但是却写了两个返回值&#xff0c;所以报错。 改正为 enc_output self.slf_attn(user_embedding,item_input,item_input,mask sl…

Python带*参数和带**参数

一、带*形参 1、格式&#xff1a;*形参名&#xff0c;如*args 2、数据类型&#xff1a;元组 3、传参方式&#xff1a;接收任意个位置参数&#xff08;可以不传参&#xff09;。 4、位置&#xff1a;在一个函数里只能有一个&#xff0c;且放在末尾&#xff08;没有带**形参的…

IE浏览器解决无法识别js中getElementsByClassName问题

关于ie浏览器无法识别js中getElementsByClassName问题&#xff0c;现通过以下方法&#xff0c;引用如下js /***打印js对象详细信息*/ function alertObj(obj) {var description "";for ( var i in obj){var property obj[i];description i " " prope…

arduino i2c 如何写16位寄存器_树莓派3B开发Go语言(二)寄存器版本GPIO

作者&#xff1a;爪爪熊链接&#xff1a;https://www.jianshu.com/p/0495c0554a63來源&#xff1a;简书之前将go语言的运行环境给搭建起来了&#xff0c;但是没有开始真正的试试Go 语言操作树莓派硬件的效果。一、树莓派3B硬件介绍树莓派3B采用了博通的BCM2837方案&#xff0c;…

Android aidl在Framework的使用

为何要做这个 我要在framework的PhoneWindowManager.java里面调用LightService.java里面的函数&#xff0c;用来做灯光的提示之类的&#xff0c;为何我要在PhoneWindowManager.java里面加这个呢&#xff0c;这里就不做讨论了&#xff0c;但是直接调用哪些接口是不行的&#xf…