标签:ret stdio.h ase 文件 pcl 头文件 kernel volatile 变量
1 /* 2 pwm 硬件手册24章 3 蜂鸣器 GPD0_0 配置成 tout0 pwm0的输出 4 5 从硬件手册P446页 查出 总线的频率是100Mhz 6 7 TCFG0 配置一级分频 0-7位 配置timer0~1的预分频 8 8~15 配置timer2 3 4预分频 9 TCFG1 设置5个timer的二级分频 10 TCON pwm定时器的控制寄存器 11 [0] 定时器0的开关 12 [1] 将TCNTB0和TCMPB0的值分别写入定时器0内部 13 注意一点,写入的操是瞬间完成,写完之后要立即把该位清0 14 否则,写入的操作将会连续不断的持续进行,那么定时器就无法计数 15 [2] 输出电平的极性,参照1300 ,该值会影响到占空比的计算 16 [3] 单次开启还是连续开启 (每个计数周期结束之后会自动将TCMB0写入计数器中,开始新的周期) 17 18 TINT_CSTAT 使能和清除,对应的中断 19 20 21 linux 内核 设备和设备分离 22 23 */ 24 #include <linux/module.h> 25 #include <linux/init.h> 26 #include <linux/kernel.h> //printk 27 28 #include <linux/miscdevice.h> //misc_register.... 29 #include <linux/fs.h> //file_operations 30 #include <mach/regs-gpio.h> //S5P_VA_GPIO2 31 #include <linux/ioport.h> //request_mem_region 32 33 #include <linux/io.h> 34 35 #include "pwm_ctl.h" 36 37 #define DEVNAME "ldm" 38 39 40 #define TCFG0 (*(volatile u32 *)ioremap(0x139d0000, 4)) 41 #define TCFG1 (*(volatile u32 *)ioremap(0x139d0004, 4)) 42 #define TCON (*(volatile u32 *)ioremap(0x139d0008, 4)) 43 #define TCNTB0 (*(volatile u32 *)ioremap(0x139d000c, 4)) 44 #define TCMPB0 (*(volatile u32 *)ioremap(0x139d0010, 4)) 45 #define TINT_CSTAT (*(volatile u32 *)ioremap(0x139d0044, 4)) 46 47 #define GPD0CON (*(volatile u32 *)ioremap(0x114000a0, 4)) 48 49 struct ldm_info 50 { 51 struct miscdevice dev; 52 struct file_operations ops; 53 }; 54 55 struct ldm_info ldm; 56 57 //跟时钟配置相关 58 59 60 // int pwm_init() 61 // { 62 // //GPD0CON 配置成复用模式 63 64 // //设置频率 65 66 // //设置TCNTB0 TCMPB0 两个寄存器 67 // //提供应用层相关的接口 68 69 // //把TCNTB0 和 TCMPB0 加载到 定时器中 70 // TCON |= 1 << 1; 71 // TCON &= ~(1 << 1); 72 73 // //打开定时器,开启连续触发的模式 74 75 76 // //加入到misc 子系统中 以提供给用户层访问 77 78 79 static inline void timer0_cout_set(u32 cmp, u32 cnt) 80 { 81 TCNTB0 = cnt; 82 TCMPB0 = cmp; 83 84 TCON |= 1 << 1; 85 TCON &= ~(1 << 1); 86 } 87 88 long ldm_ioctl(struct file * file, unsigned int cmd, unsigned long arg) 89 { 90 91 switch(cmd) { 92 case SET_CMP: 93 timer0_cout_set(arg, TIMER0_KHZ /2); 94 break; 95 default: 96 break; 97 } 98 return 0; 99 } 100 101 static int ldm_init(void) 102 { 103 int ret = 0; 104 printk("%s:%s, %d\n", __FILE__, __FUNCTION__, __LINE__); 105 106 ////GPD0CON 配置成复用模式 107 GPD0CON = (GPD0CON & ~0xf) | 0x2; 108 109 //设置频率 110 TCFG0 = (TCFG0 & ~0xff) | PWM_PRESCALER0; 111 TCFG1 = (TCFG1 & ~0xf) | DIV; 112 113 //占空比为50% 114 timer0_cout_set(TIMER0_KHZ/4, TIMER0_KHZ /2); 115 116 //把TCNTB0 和 TCMPB0 加载到 定时器中 117 TCON |= 1 << 1; 118 TCON &= ~(1 << 1); 119 120 //打开定时器,选择连续触发模式 121 TCON &= ~(1 << 2); 122 TCON |= 1<< 3 | 1; 123 124 //给应用层提供接口 125 ldm.dev.minor = MISC_DYNAMIC_MINOR; 126 ldm.dev.name = DEVNAME; 127 ldm.dev.fops = &ldm.ops; 128 ldm.ops.unlocked_ioctl = ldm_ioctl; 129 130 ret = misc_register(&ldm.dev); 131 if(ret < 0) { 132 printk("misc_register failed\n"); 133 goto err_misc_register; 134 } 135 136 return 0; 137 err_misc_register: 138 return -1; 139 140 } 141 142 static void ldm_exit(void) 143 { 144 printk("%s:%s, %d\n", __FILE__, __FUNCTION__, __LINE__); 145 misc_deregister(&ldm.dev); 146 } 147 148 149 150 module_init(ldm_init); 151 module_exit(ldm_exit); 152 MODULE_LICENSE("GPL");
.h
1 #pragma once 2 3 #include <linux/ioctl.h> 4 //参考下内核文档 linux/linux-3.5/Documentation/ioctl 5 //ioctl-decoding.txt 和 ioctl-number.txt 6 //例如 实现 控制LED灯 7 /* 8 _IO (魔数, 基数); 9 • _IOR (魔数, 基数, 变量型) 10 • _IOW (魔数, 基数, 变量型) 11 • _IOWR (魔数, 基数,变量型 ) 12 */ 13 14 enum 15 { 16 //4412 P446 100MHZ 17 PCLK_PERIL = 100000000, 18 PWM_PRESCALER0 = 99, 19 DIV = 4, 20 21 TIMER0_HZ = PCLK_PERIL / (PWM_PRESCALER0 + 1) / 16, 22 TIMER0_KHZ = TIMER0_HZ /1000, 23 }; 24 25 //写 26 #define SET_CMP _IOW(‘l‘, 1, unsigned int) 27 //底层的驱动生成的一系列 命令 这个头文件同样也需要提供给应用层 28 29 #define DUTY_0 TIMER0_KHZ/2 30 //#define DUTY_25 31 #define DUTY_50 TIMER0_KHZ/4 32 //#define DUTY_75 33 #define DUTY_100 0
.app
//应用层 #include <stdio.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <sys/ioctl.h> #include "pwm_ctl.h" int main(int argc, char const *argv[]) { int fd = open("/dev/ldm", O_RDWR); if(fd < 0) { perror("open"); goto err_open; } //ioctl(fd, LED_STATUS, led_status); //ioctl(fd, LED1_ON); ioctl(fd, SET_CMP, DUTY_100); close(fd); return 0; err_open: return -1; }
标签:ret stdio.h ase 文件 pcl 头文件 kernel volatile 变量
原文地址:http://www.cnblogs.com/baoshulin/p/6477014.html