[セットトップ]DM 8168 PWMドライバとテストプログラム
昨日DM 8168のTimerをセットしてタッチして、PWMの下地駆動を書く準備をして、今からテーマに入ります.
dm8168_pwm.c:
Makefile:
テストプログラムpwm_test.c:
テスト:
モジュールコンパイル後のロード:insmod dm 8168_pwm.ko
クロスコンパイルテストプログラム:arm-none-linux-gnueabi-gcc-o pwm_test pwm_test.c
実行:./pwm_test 50
出力50%の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
");
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
");
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 !
");
exit(1);
}
else
{
printf("open success ! duty_cycle : %s
",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 dm 8168_pwm.ko
クロスコンパイルテストプログラム:arm-none-linux-gnueabi-gcc-o pwm_test pwm_test.c
実行:./pwm_test 50
出力50%のPWM波形で試験に成功した.