DM8168 PWM驱动与测试程序

昨天把DM8168的Timer设置给摸了一遍,为写PWM的底层驱动做好了准备,现在就要进入主题了。

dm8168_pwm.c:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/uaccess.h> /* copy_to_user,copy_from_user */
#include <linux/miscdevice.h>
#include <linux/device.h>
#include <asm/io.h>

static struct class  *pwm_class;

volatile unsigned long *CLK_CTL;
volatile unsigned long *TCLR;
volatile unsigned long *TCRR;
volatile unsigned long *TLDR;
volatile unsigned long *TMAR;

int pwm_open (struct inode *inode,struct file *filp)

{
	*CLK_CTL = 0x00000002;
	*TCLR    = 0;
	*TLDR    = 0xffffffe0;
	*TMAR    = 0xfffffff0;
	*TCRR    = 0xffffffe0;
	return 0;
}

ssize_t pwm_read (struct file *filp, char __user *buf, size_t count,loff_t *f_pos)
{
	return 0;
}

ssize_t pwm_write (struct file *filp, const char __user *buf, size_t count,loff_t *f_pos)
{
	char duty_buf[2];
	int ret;
	ret = copy_from_user(duty_buf,buf,count);		
	*TMAR    = 0xffffffe0 + (unsigned char)(duty_buf[0]*30/100);  //分辨率略低,仅为demo
	*TCLR    = 0x1843;
	return count;
}

struct file_operations pwm_fops =
{
	.owner   = THIS_MODULE,
	.open    = pwm_open,
	.read    = pwm_read,
	.write   = pwm_write,
} ;

int major;
int pwm_init (void)
{ 	
	
	major = register_chrdev(0,"DM8168_PWM",&pwm_fops);
	pwm_class = class_create(THIS_MODULE, "DM8168_PWM");
	device_create(pwm_class,NULL,MKDEV(major,0),NULL,"pwm");

	CLK_CTL = (volatile unsigned long *)ioremap(0x4818157C,4);
	TCLR    = (volatile unsigned long *)ioremap(0x48044038,4);
	TCRR    = (volatile unsigned long *)ioremap(0x4804403C,4);
	TLDR    = (volatile unsigned long *)ioremap(0x48044040,4);
	TMAR    = (volatile unsigned long *)ioremap(0x4804404C,4);
	printk ("pwm is ready\n");
	return 0;
}

void pwm_exit (void)
{
	unregister_chrdev(major,"DM8168_PWM");
	device_destroy(pwm_class,MKDEV(major,0));
	class_destroy(pwm_class);

	iounmap(CLK_CTL);
	iounmap(TCLR);
	iounmap(TCRR);
	iounmap(TLDR);
	iounmap(TMAR);
	printk ("module exit\n");
	return ;
}

MODULE_LICENSE("GPL");
module_init(pwm_init);
module_exit(pwm_exit);

Makefile:

obj-m:= dm8168_pwm.o

CROSSCOMPILE := /opt/codesourcery/arm-2009q1/bin/arm-none-linux-gnueabi-

CC  := $(CROSSCOMPILE)gcc 

KDIR:=/home/***/ti-ezsdk_dm816x-evm_5_03_01_15/board-support/linux-2.6.37-psp04.00.01.13.patch2

PWD :=$(shell pwd)

default:
	$(MAKE) -C $(KDIR) M=$(PWD) modules ARCH=arm CROSS_COMPILE=arm-none-linux-gnueabi-
clean:
	rm -rf *.ko *.o .*cmd *.mod.c .tmp_versions 


测试程序 pwm_test.c:

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

int pow_10(char m)
{
	int j;
	int res=1;
	for(j=0;j<m;j++)
	{
		res = res * 10;
	}	
	return res;
}

int main(int argc, char *argv[])
{
	int  fd;
	char *buf;
	char i;
	int  val=0;

	fd=open("/dev/pwm",O_RDWR);
	if(fd<0)
	{
		printf("open device failed !\n");
		exit(1);
	}
	else
	{
		printf("open success ! duty_cycle : %s\n",argv[1]);
		buf=argv[1];
		buf+=strlen(argv[1])-1;
	}

	for(i=0;i<strlen(argv[1]);i++)
	{
		val += pow_10(i)*(*buf-0x30);
		buf --;	
	}
	write(fd,&val,1);
	close(fd);
	return 0;
}



测试 :

模块编译后加载:insmod dm8168_pwm.ko

交叉编译测试程序:arm-none-linux-gnueabi-gcc -o pwm_test pwm_test.c

运行:./pwm_test 50

输出为50%的PWM波形,测试成功。

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Marvin_wu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值