在现有的项目上通过SoC的EHRPWM3B管脚产生PWM脉冲做为摄像头的framsync信号.

datasheet描述:

PWMSS:PWM Subsystem Resources
eHRPWM: Enhanced High Resolution Pulse Width Modulator 脉冲宽度调制器,产生pwm
eCAP: Enhanced Capture 增强型输入捕捉
eQEP: Enhanced Quadratured Pulse 增强的正弦波,只支持输入
 
eHRPWM:
  • 专用的带有频率/周期控制的16位时基发生器
  • 支持产生2组独立的PWM输出with Single edge operation
  • 支持产生2组独立的PWM输出with Dual edge symmetric operation
  • 支持产生1组独立的PWM输出with Dual edge symmetric operation
  • Supports Dead-band generation with independent Rising and Falling edge delay control
  • 在故障状态下, 提供PWM信号的异步越权控制
  • Supports “trip zone” allocation of both latched and un-latched fault conditions
  • CPU中断和ADC转换开始都允许触发事件
  • Support PWM chopping by high frequency carrier signal, used for pulse transformer gate drives.
  • 带有可编程延迟线的高分辨率模块
    • 每个PWM周期可编程?Programmable on a per PWM period basis
    • 可以在PWM脉冲的上升沿或者下降沿插入或者在两种边沿同时插入,亦或者两者都不插入Can be inserted either on the rising edge or falling edge of the PWM pulse or both or not at all
eCAP:
  • 专用的输入捕捉管脚
  • 32位时基发生器(counter)
  • 4x32bit时间戳捕捉寄存器(PWMSS_ECAP_CAP1 - PWMSS_ECAP_CAP4)
  • 4 stage sequencer (Mod4 counter) which is synchronized to external events (ECAPx pin edges)
  • Independent Edge polarity (Rising/Falling edge) selection for all 4 events
  • One-shot compare register (2 bits) to freeze captures after 1 to 4 Time-stamp events
  • Control for continuous Time-stamp captures using a 4 deep circular buffer (PWMSS_ECAP_CAP1 -PWMSS_ECAP_CAP4) scheme
  • Interrupt capabilities on any of the 4 capture events
 
eQEP:
  • 输入同步
  • Three Stage/Six Stage Digital Noise Filter
  • 正弦波解码单元
  • Position Counter and Control unit for position measurement
  • Quadrature Edge Capture unit for low speed measurement
  • Unit Time base for speed/frequency measurement
  • Watchdog Timer for detecting stalls

对应的寄存器

设备树描述
epwmss2: epwmss@48442000 {
compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss";
reg = <0x48442000 0x30>;
ti,hwmods = "epwmss2";
#address-cells = <1>;
#size-cells = <1>;
status = "okay";
ranges; ehrpwm2: pwm@48442200 {
compatible = "ti,dra746-ehrpwm",
"ti,am3352-ehrpwm",
"ti,am33xx-ehrpwm";
#pwm-cells = <3>;
reg = <0x48442200 0x80>;
clocks = <&ehrpwm2_tbclk>, <&l4_root_clk_div>;
clock-names = "tbclk", "fck";
status = "okay";
};
...
};

通过调用以下脚本可以产生25Hz, duty=25%的pwm脉冲

#!/bin/sh
echo 1 > /sys/class/pwm/pwmchip0/export
# setup frequency to 25Hz duty cycle 25%
echo 40000000 > /sys/class/pwm/pwmchip0/pwm1/period
echo 10000000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
echo normal > /sys/class/pwm/pwmchip0/pwm1/polarity
echo 1 > /sys/class/pwm/pwmchip0/pwm1/enable
echo "setting pwm for camera isp frame sync

代码流程:

系统上电初始化之后, 根据设备树注册一个名字为48442200.pwm的总线设备, 总线设备跟总线驱动匹配成功之后执行/driver/pwm/pwm-tiehrpwm.c的probe函数,
static int ehrpwm_pwm_probe(struct platform_device *pdev)
{
...
ret = pwmchip_add(&pc->chip);
if (ret < 0) {
dev_err(&pdev->dev, "pwmchip_add() failed: %d\n", ret);
return ret;
}
...
}

pwmchip_add函数定义在/driver/pwm/core.c里面

int pwmchip_add(struct pwm_chip *chip)
{
return pwmchip_add_with_polarity(chip, PWM_POLARITY_NORMAL);
}

同样pwmchip_add_with_polarity函数也定义在core.c下

int pwmchip_add_with_polarity(struct pwm_chip *chip,
enum pwm_polarity polarity)
{
...
pwmchip_sysfs_export(chip);
...
}

可在driver/pwm/sysfs.c下面找到pwmchip_sysfs_export的定义,这里调用了device_create在/sys/下面创建一个名字为pwmchip%d的目录.

void pwmchip_sysfs_export(struct pwm_chip *chip)
{
...
parent = device_create(&pwm_class, chip->dev, MKDEV(0, 0), chip,
"pwmchip%d", chip->base);
...
}

并调用根据pwm_class定义的内核属性新建文件夹pwm

static struct class pwm_class = {
.name = "pwm",
.owner = THIS_MODULE,
.dev_groups = pwm_chip_groups,
};

在pwm下面新建npwm, unexport, export三个文件

static ssize_t export_store(struct device *parent,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct pwm_chip *chip = dev_get_drvdata(parent);
struct pwm_device *pwm;
unsigned int hwpwm;
int ret; ret = kstrtouint(buf, 0, &hwpwm);
if (ret < 0)
return ret; if (hwpwm >= chip->npwm)
return -ENODEV; pwm = pwm_request_from_chip(chip, hwpwm, "sysfs");
if (IS_ERR(pwm))
return PTR_ERR(pwm); ret = pwm_export_child(parent, pwm);
if (ret < 0)
pwm_put(pwm); return ret ? : len;
}
static DEVICE_ATTR_WO(export); static ssize_t unexport_store(struct device *parent,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct pwm_chip *chip = dev_get_drvdata(parent);
unsigned int hwpwm;
int ret; ret = kstrtouint(buf, 0, &hwpwm);
if (ret < 0)
return ret; if (hwpwm >= chip->npwm)
return -ENODEV; ret = pwm_unexport_child(parent, &chip->pwms[hwpwm]); return ret ? : len;
}
static DEVICE_ATTR_WO(unexport); static ssize_t npwm_show(struct device *parent, struct device_attribute *attr,
char *buf)
{
const struct pwm_chip *chip = dev_get_drvdata(parent); return sprintf(buf, "%u\n", chip->npwm);
}
static DEVICE_ATTR_RO(npwm); static struct attribute *pwm_chip_attrs[] = {
&dev_attr_export.attr,
&dev_attr_unexport.attr,
&dev_attr_npwm.attr,
NULL,
};
ATTRIBUTE_GROUPS(pwm_chip);

往生成的export里面写数据才会生成新的目录

static ssize_t export_store(struct device *parent,
struct device_attribute *attr,
const char *buf, size_t len)
{
...
ret = pwm_export_child(parent, pwm);
...
}

如下在调用export之后先生成一个pwm%d的目录

static int pwm_export_child(struct device *parent, struct pwm_device *pwm)
{
...
export->child.release = pwm_export_release;
export->child.parent = parent;
export->child.devt = MKDEV(0, 0);
export->child.groups = pwm_groups;
dev_set_name(&export->child, "pwm%u", pwm->hwpwm);
...
}

上面函数调用了pwm_groups,而pwm_groups定义如下

static DEVICE_ATTR_RW(period);
static DEVICE_ATTR_RW(duty_cycle);
static DEVICE_ATTR_RW(enable);
static DEVICE_ATTR_RW(polarity); static struct attribute *pwm_attrs[] = {
&dev_attr_period.attr,
&dev_attr_duty_cycle.attr,
&dev_attr_enable.attr,
&dev_attr_polarity.attr,
NULL
};

脚本里先往export里面写1,然后才能在生成新的文件之后做其他操作.

阅读脚本控制pwm代码的更多相关文章

  1. .NET应用架构设计—表模块模式与事务脚本模式的代码编写

    阅读目录: 1.背景介绍 2.简单介绍表模块模式.事务脚本模式 3.正确的编写表模块模式.事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架构就必须能正确的搞懂每个架构模式的用意,而不是 ...

  2. TIMER门控模式控制PWM输出长度

    TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TI ...

  3. Shell脚本控制docker容器启动顺序

    1.遇到的问题 在分布式项目部署的过程中,经常要求服务器重启之后,应用(包括数据库)能够自动恢复使用.虽然使用docker update --restart=always containerid能够让 ...

  4. 一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp)

    一键自动发布ipa(更新svn,拷贝资源,压缩资源,加密图片资源,加密数据文件,加密lua脚本,编译代码,ipa签名,上传ftp) 程序员的生活要一切自动化,更要幸福^_^. 转载请注明出处http: ...

  5. Python脚本控制的WebDriver 常用操作 <十二> send_keys模拟按键输入

    下面将使用WebDriver中的send_keys来模拟键盘按键输入 测试用例场景 send_keys方法可以模拟一些组合键操作: ctrl+a ctrl+c ctrl+v 等. 另外有时候我们需要在 ...

  6. 实现图片大小的自动控制( 图片大小控制CSS代码)

    图片大小控制CSS代码 将以下代码放到你的样式表文件中即可实现图片大小的自动控制. /*图片大小控制CSS By Tekin */img,a img{border:0;margin:0;padding ...

  7. AudioMixer的脚本控制

    AudioMixer是Unity5新特性之一,能很好的实现立体声效果. 这儿先记录一下脚本控制的方法: 1.添加一个Group,然后点击它 2.右侧面板上出现2个参数:pitch(速度)和volume ...

  8. WordPress wp-includes/functions.php脚本远程任意代码执行漏洞

    漏洞名称: WordPress wp-includes/functions.php脚本远程任意代码执行漏洞 CNNVD编号: CNNVD-201309-166 发布时间: 2013-09-13 更新时 ...

  9. NGUI---使用脚本控制聊天系统的内容显示,输入事件交互

    在我的笔记Unity3D里面之 简单聊天系统一 里面已经介绍怎么创建聊天系统的背景.给聊天系统添加滚动条,设置Anchor锚点.以及设计聊天系统的输入框. 效果图如下所示: 现在我们要做的就是使用脚本 ...

随机推荐

  1. html实现高亮检索

    实现效果如下: demo.html <!DOCTYPE html> <html> <head> <meta charset="utf-8" ...

  2. Mysql 基础操作命令

    1,查看mysql的建表语句 show create table tableName; #tableName 库中已存在的表名

  3. RESTE MASTER和reset slave

    RESET MASTER 删除所有index file 中记录的所有binlog 文件,将日志索引文件清空,创建一个新的日志文件,这个命令通常仅仅用于第一次用于搭建主从关系的时的主库, 注意   re ...

  4. nodejs之express静态路由、ejs

    1.静态路由与ejs使用 /** *1.安装ejs npm install ejs --save-dev * *2.express 里面使用ejs ,安装以后就可以用,不需要引入 * *3.配置exp ...

  5. nodejs 之简单web服务器

    1.service.js var http=require('http');//引入http模块 var fs=require('fs');//fs模块 var path=require('path' ...

  6. 阶段3 3.SpringMVC·_02.参数绑定及自定义类型转换_1 请求参数绑定入门

    请求参数的绑定 参数绑定 创建新的页面 给方法加上注解 前面没有斜线 重新部署项目 传递一个username的值 后台方法接收 重新部署项目 再传一个password的值 再输出password ja ...

  7. 如何修改eclipse中的maven的仓库地址

    最近的有一个朋友问我如何修改eclipse的maven的本地仓库,我想了一下,这个玩意一般是不用修改的,主要是你本地安装的maven在哪个位置,一般的本地仓库位置在 C:\Users\username ...

  8. gcc编译器创建和使用静态库、动态库

    http://www.cnblogs.com/dyllove98/archive/2013/06/25/3155599.html 目录树结构: test/include/hello.h #ifdef ...

  9. 【图形学手记】Inverse Transform Sampling 逆转换抽样

    需求: 我们通过调查,得知大多数人在20岁左右初恋,以20岁为基准,以随机变量X表示早于或晚于该时间的年数,为了简单,假设X值域为[-5,5],并且PDF(X)是一个正态分布函数(当然可以为任意分布, ...

  10. logstash 写入数据到elasticsearch 索引相差8小时解决办法

    问题说明 Logstash用的UTC时间, logstash在按每天输出到elasticsearch时,因为时区使用utc,造成每天8:00才创建当天索引,而8:00以前数据则输出到昨天的索引 # 使 ...