阅读脚本控制pwm代码

在现有的项目上通过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: [email protected] {
	compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss";
	reg = <0x48442000 0x30>;
	ti,hwmods = "epwmss2";
	#address-cells = <1>;
	#size-cells = <1>;
	status = "okay";
	ranges;

	ehrpwm2: [email protected] {
		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,然后才能在生成新的文件之后做其他操作.

原文地址:https://www.cnblogs.com/cheyihaosky/p/11595073.html

时间: 2024-08-29 20:39:11

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

怎么学习阅读大型项目的代码

第一章: 导论 ++++++++++++ 1.要养成一个习惯, 经常花时间阅读别人编写的高品质代码. 2.要有选择地阅读代码, 同时, 还要有自己的目标. 您是想学习新的模式|编码风格|还是满足某些需求的方法. 3.要注意并重视代码中特殊的非功能性需求, 这些需求也许会导致特殊的实现风格. 4.在现有的代码上工作时, 请与作者和维护人员进行必要的协调, 以避免重复劳动或产生厌恶情绪. 5.请将从开放源码软件中得到的益处看作是一项贷款, 尽可能地寻找各种方式来回报开放源码社团. 6.多数情况下,

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

阅读目录: 1.背景介绍 2.简单介绍表模块模式.事务脚本模式 3.正确的编写表模块模式.事务脚本模式的代码 4.总结 1.背景介绍 要想正确的设计系统架构就必须能正确的搞懂每个架构模式的用意,而不是胡子眉毛一把抓.现在有一个现象是什么呢,项目的结构从表面上看是很不错,层分的很合理,其实对业务系统来说也就那么几种层设计方法,但是现在很多项目的逻辑架构的设计不是理想,有很多概念大家并不是很了解,当然也许每个人对技术的追求不同罢了.不管你追求不追求,事实我们还是要去往正确的方向努力才对的. 很多人包

如何阅读大型项目的代码?

本文转载自:http://blog.csdn.net/jk110333/article/details/7563718 Technorati 标签: 源码阅读 -------------------------------我是分割线的开始------------------------------------------ ++++++++++++++++++++ 第一章: 导论 ++++++++++++ 1.要养成一个习惯, 经常花时间阅读别人编写的高品质代码. 2.要有选择地阅读代码, 同时,

Unity3D 学习教程 11 c#脚本控制摄像头

首先新建一个脚本 点击创建一个文件夹起名C# 点击文件夹 创建一个C#脚本 建好文件后 双击文件 启动脚本编辑器 void Start () 是场景运行时加载程序 void Update ()  是每调用一针执行一次  可以认为是试试执行的程序 下面编写第一个脚本 控制摄像机移动 using UnityEngine; using System.Collections; public class acc : MonoBehaviour { int speed=50; void Start () {

Unity3D教程宝典之光影烘焙:第四讲脚本控制

上一讲讲了用Light probes实现动态物体的非实时阴影,这一讲讲用代码实现代码实现动态物体的非实时阴影. 实现步骤:(1)新建一个场景,并建一个plane作为大地(2)创建Cube并缩放成扁平面后.复制Cube并旋转拼接搭建成一个敞篷.(3)讲上述物体设置static并烘焙.(4)创建一个player.这里用的unity自带的Character Controller包里的 3rd person controller这个prefab,拖进敞篷边.在该人物下找到Bip001 Pelvis这个节

脚本控制animation的事件

由于动作设计经常修改动作,所以每次改完都要再添加一次animation的事件,所以就直接写了个脚本,当然以后可以做成表格,然后用脚本从表格中读取,然后生成对应的animation事件.在Assets/Editor目录中放置代码,参考代码如下: using UnityEngine; using System.Collections; using UnityEditor; public class AddEventsToAnimations : MonoBehaviour { [MenuItem("

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

TIMER门控模式控制PWM输出长度 参照一些网友代码做了些修改,由TIM4来控制TIM2的PWM输出长度, 采用主从的门控模式,即TIM4输出高时候TIM2使能输出 //TIM2 PWM输出,由TIM4来控制其输出与停止 //frequency_tim2:TIM2 PWM输出周期:KHz //duty_tim2:TIM2 PWM占空比 0-100 //period_tim4: TIM4控制TIM2总周期,单位0.1ms //duty_tim4: TIM4控制TIM2输出时间,单位0.1ms v

Unity3D中的第三人称镜头的脚本控制

原地址:http://blog.csdn.net/mobanchengshuang/article/details/27591271 好久没有敲Blog了,谢谢大家的留言.关注.私信等支持,但是我好像已经没有办法让自己继续写以前的博客系列了,因为我发现网上关于unity3D的内容太少了,所以我无法自拔地想写U3D相关的文章!!! 第三人称视角 第三人称视角是什么?很简单,CS就是一种第一人称视角游戏,玩家没有办法看到自己的角色形象,只能观察除开自己之外的游戏内容.第三人称视角那么就明显是能够看到

【HTML5】用脚本控制交互元素details元素的使用

1.源码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Con