📄 tlc2543_ad_driver.c
字号:
#include <linux/config.h>//配置头文件
#include <linux/kernel.h>//内核头文件
#include <linux/sched.h>
#include <linux/timer.h>//时钟头文件
#include <linux/init.h>//用户定义模块初始化函数名需引用的头文件
#include <linux/module.h>//模块加载的头文件
#include <asm/hardware.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#define CMD_CS_LOW 0
#define CMD_CS_HIGH 1
#define ADC_CS_LOW write_gpio_bit(GPIO_F0,0)
#define ADC_CS_HIGH write_gpio_bit(GPIO_F0,1)
#define ADC_SCK_LOW write_gpio_bit(GPIO_F2,0)
#define ADC_SCK_HIGH write_gpio_bit(GPIO_F2,1)
#define ADC_DIN_LOW write_gpio_bit(GPIO_G3,0)
#define ADC_DIN_HIGH write_gpio_bit(GPIO_G3,1)
//定义设备号
#define DEV_MAJOR 97
//定义设备名
#define DEV_NAME "ADC"
//驱动程序实现的方法
ssize_t ADC_open (struct inode * inode ,struct file * file);
ssize_t ADC_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops);
ssize_t ADC_read (struct file * file ,char * buf, size_t count);
ssize_t ADC_release (struct inode * inode ,struct file * file);
ssize_t ADC_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long data);
// -------------------------------------------------
struct file_operations ADC_ctl_ops ={
owner: THIS_MODULE,
open: ADC_open,
write: ADC_write,
read: ADC_read,
release: ADC_release,
ioctl: ADC_ioctl,
};
// ------------------- READ ------------------------
ssize_t ADC_read (struct file * file ,char * buf, size_t count)
{
unsigned int Chel_Bits=0x24; //选用芯片的十一路通道中的通道2,输出数据的长度为8位
int i,j;
unsigned char buf_tmp=0;
//使能TLC2543
ADC_CS_HIGH;
udelay(10); //CS的转换时间最少为10us
ADC_CS_LOW;
for(j=0;j<count;j++){
for(i=7;i>=0;i--){
if(Chel_Bits & (0x01<<i) ){ //write Din pin
write_gpio_bit(GPIO_G3,1);
}else{
write_gpio_bit(GPIO_G3,0);
}
//保证CS 的建立时间t(cs)最小为1.425us和Dout从高阻态到第一位有效数据的时间tPZH/tPZL为0.7us
udelay(10); //其实不一定要,因为后面还有延时。
if( read_gpio_bit(GPIO_G11) ){ //read the Din pin
//printk("%x\n",Read_Bit);
buf_tmp |= 0x01<<i;
}else{
//printk("%x\n",Read_Bit);
buf_tmp &= ~(0x01<<i);
}
ADC_SCK_LOW;//可以不要
udelay(10); //保证Din 的建立时间 最少为100ns和Din的电平转换过度时间最大为10us
ADC_SCK_HIGH;
udelay(40); //时钟高电平持续时间最少150ns
ADC_SCK_LOW;
udelay(20); //时钟低电平持续时间最少150ns,
}
udelay(20); //补偿第一字节最好一个数据位的时钟低电平时间,同时保证CS的保持时间
count=j+1;
}
copy_to_user((void *)buf,(void *)&buf_tmp,sizeof(buf_tmp));
ADC_DIN_HIGH; //恢复初始状态,SCK在这之前为低,所以这里不用恢复
ADC_CS_HIGH; //关闭AD
return count;
}
// ------------------- WRITE -----------------------
ssize_t ADC_write (struct file * file ,const char * buf, size_t count, loff_t * f_ops)
{
return count;
}
// ------------------- OPEN ------------------------
ssize_t ADC_open (struct inode * inode ,struct file * file)
{
MOD_INC_USE_COUNT;
return 0;
}
// ------------------- IOCTL -----------------------
ssize_t ADC_ioctl (struct inode * inode ,struct file * file, unsigned int cmd, long data)
{
switch (cmd)
{
case CMD_CS_HIGH : {
write_gpio_bit(GPIO_F0,1);break;
}
case CMD_CS_LOW : {
write_gpio_bit(GPIO_F0,0);break;
}
default :{printk ("lcd control : no cmd run [ --kernel-- ]\n"); return (-EINVAL);}
}
return 0;
}
// ------------------- RELEASE/CLOSE ---------------
ssize_t ADC_release (struct inode * inode ,struct file * file)
{
MOD_DEC_USE_COUNT;
return 0;
}
// ------------------- INIT ------------------------
static devfs_handle_t devfs_handle;
static int ADC_CTL_init(void)
{
int ret = -ENODEV;
printk("--------------------------------------------------------------------------------\n");
//初始化S3C2410与TLC2543相连的管脚
set_gpio_ctrl (GPIO_F0 | GPIO_PULLUP_EN | GPIO_MODE_OUT); //EINT0-------CS
set_gpio_ctrl (GPIO_F2 | GPIO_PULLUP_EN | GPIO_MODE_OUT); //EINT2-------SCK
set_gpio_ctrl (GPIO_G3 | GPIO_PULLUP_EN | GPIO_MODE_OUT); //ENIT11------Din
set_gpio_ctrl (GPIO_G11 | GPIO_PULLUP_EN | GPIO_MODE_IN); //EINT19------Dout
//初始引脚的电平
write_gpio_bit(GPIO_F0,1); //CS为高电平
write_gpio_bit(GPIO_F2,0); //SCK为低电平
write_gpio_bit(GPIO_G3,1); //Din为高电平
//这里Dout为输入管脚,不用初始化电平
ret = register_chrdev(DEV_MAJOR, DEV_NAME, &ADC_ctl_ops);
if( ret < 0 ){
printk (" S3C2410: init_module failed with %d\n", ret);
return ret;
}else{
printk("S3C2410 gpio_led_driver register success!!! \n");
}
devfs_handle = devfs_register(NULL, DEV_NAME, DEVFS_FL_DEFAULT,
DEV_MAJOR, 0, S_IFCHR | S_IRUSR | S_IWUSR, &ADC_ctl_ops, NULL);
return ret;
}
//---------------驱动程序初始化函数----------------------
static int __init TLC2543_ADC_init(void)
{
int ret = -ENODEV;
ret = ADC_CTL_init();
if (ret)
return ret;
return 0;
}
//---------------驱动程序清楚函数------------------------
static void __exit TLC2543_ADC_Clr(void)
{
unregister_chrdev (DEV_MAJOR, DEV_NAME );
}
//----------------------------------------------------------
module_init(TLC2543_ADC_init);
module_exit(TLC2543_ADC_Clr);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -