linux3.2下adt7320的spi驱动编写
来源:互联网 发布:串口数据采集软件 编辑:程序博客网 时间:2024/05/16 15:36
在3.2中没有spi_read/spi_write, 更改为了spi_write_then_read, 好用惨了
驱动程序adt7320_driver.c
#include <linux/init.h>#include <linux/module.h>#include <linux/ioctl.h>#include <linux/fs.h>#include <linux/device.h>#include <linux/err.h>#include <linux/list.h>#include <linux/errno.h>#include <linux/mutex.h>#include <linux/slab.h>#include <linux/compat.h>#include <linux/spi/spi.h>#include <linux/spi/spidev.h>#include <asm/uaccess.h>#define Contin_Mode 0x00#define OneShot_Mode 0x01#define SPS1_Mode 0x02#define ShutDown_Mode 0x03#define Bit16_Mode 1#define Bit13_Mode 0#define CMDREAD 1#define CMDWRITE 0#define STATUS_REG 0x00#define CONFIG_REG 0x01#define TEMPVAL_REG 0x02#define ID_REG 0x03#define TCRIT_REG 0x04#define THYST_REG 0x05#define THIGH_REG 0x06#define TLOW_REG 0x07#define Dummy_Byte 0x5A#define INIT 0x1#define RESET 0x0#define SPIDEV_MAJOR 153static struct class *adt7320_class;static struct spi_device *adt7320_spi_device;static char rx_buf[5] = {0}, tx_buf[5] = {0};/*adt7301 adt7302adt7310adt7316*//******************************************************************************** Function Name : Reg_Select* Description : 选中 adt7320 的寄存器, 指定操作读或写* Input : operate: 0 读 / 1 写, val 寄存器编号* Return : None*******************************************************************************/unsigned char Reg_Select(unsigned char operate, unsigned char val){unsigned char cmd = 0;if (operate)//bit7: 1 读 , 0 写{cmd |= (1 << 6);}else{cmd &= ~(1 << 6);}cmd |= (val << 3);cmd &= ~((1<<7) | (1<<2) | (1<<1) | (1<<0));return cmd;}/******************************************************************************* * desc: get temperature from adt7320*******************************************************************************/static ssize_t adt7320_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos){int ret = 0;int adcVal = 0;float tempVal = 0;tx_buf[0] = Reg_Select(CMDREAD, TEMPVAL_REG);spi_write_then_read(adt7320_spi_device, tx_buf, 1, rx_buf, 2);adcVal = (rx_buf[0] << 8) + rx_buf[1];ret = copy_to_user(&adcVal, buf, sizeof(float));return ret;}static unsigned char getID(void){tx_buf[0] = Reg_Select(CMDREAD, ID_REG);spi_write_then_read(adt7320_spi_device, tx_buf, 1, rx_buf, 1);return rx_buf[0];}/******************************************************************************* * desc: read chip_id, if chip_id equals to 0xC3 , chip initail success * return: chip initail success return 0, else return -1 *******************************************************************************/static int Init(void){unsigned char chip_id = 0;chip_id = getID();if (chip_id == 0xC3){printk ("init success\n");return 0;}else{printk ("init failed\n");return -1;}}//adt7320 reset by 4 byte '0xFF'static void Reset(void){tx_buf[0] = 0xFF;tx_buf[1] = 0xFF;tx_buf[2] = 0xFF;tx_buf[3] = 0xFF;spi_write_then_read(adt7320_spi_device, tx_buf, 4, rx_buf, 0);}static long adt7320_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){switch (cmd ){case INIT:Init();break;case RESET:Reset();break;default:break;}printk ("adt7320 ioctl\n");return 0;}static int adt7320_open(struct inode *inode, struct file *filp){printk ("adt7320 open!\n");return 0;}static int adt7320_release(struct inode *inode, struct file *filp){printk ("adt7320 release!\n");return 0;}static struct file_operations adt7320_fops = {.owner = THIS_MODULE,.open = adt7320_open,.read = adt7320_read,.unlocked_ioctl = adt7320_ioctl,.release = adt7320_release,};/* * desc: ÔÚprobeÖд´½¨É豸 * device_create * */static int __devinit adt7320_probe(struct spi_device *spi){adt7320_spi_device = spi;device_create(adt7320_class, NULL, MKDEV(SPIDEV_MAJOR, 0), NULL, "adt7320");return 0;}/* *desc: ÔÚremoveÖÐ×¢ÏúÉ豸 * device_destroy * */static int __devexit adt7320_remove(struct spi_device *spi){device_destroy(adt7320_class, MKDEV(SPIDEV_MAJOR, 0));return 0;}static struct spi_driver adt7320_driver = {.driver = {.name = "adt7320",.owner = THIS_MODULE,},.probe = adt7320_probe,.remove = __devexit_p(adt7320_remove),};static int adt7320_init(void){register_chrdev(SPIDEV_MAJOR, "spi_temp", &adt7320_fops);adt7320_class = class_create(THIS_MODULE, "adt7320_class");spi_register_driver(&adt7320_driver);return 0;}static void adt7320_exit(void){spi_unregister_driver(&adt7320_driver); class_destroy(adt7320_class); unregister_chrdev(SPIDEV_MAJOR, "spi_temp");}module_init(adt7320_init);module_exit(adt7320_exit);MODULE_LICENSE("GPL");因为编译为模块添加到内核总是提示函数未定义, 只好将它添加到内核里了. (kernel)/driver/spi/Makefile 中在 spidev.o 后添加 adt7320_driver.o 重新编译内核即可.
测试程序adt7320.c
#include <stdint.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <getopt.h>#include <fcntl.h>#include <sys/ioctl.h>#define INIT 0x1#define RESET 0x0static const char *device = "/dev/adt7320";static void pabort(const char *s){ perror(s); abort();}int main(int argc, char const *argv[]){ float tempVal = 0; int adcVal = 0; int fd = 0; fd = open(device, O_RDWR); if (fd < 0) { pabort("can not open device"); } ioctl(fd, RESET); ioctl(fd, INIT); while(1) { read(fd, &adcVal, sizeof(int)); tempVal = (float)(adcVal >> 3); //低3位为标志位 if (adcVal & 0x8000) //最高位为1则为负值 { tempVal = (tempVal - 8192) / 16.0; } else { tempVal = tempVal / 16.0; } printf ("temperature: %f C\n", tempVal); sleep (1); } close(fd); return 0;}另外内核里不能使用浮点数, 只能将adc的值返回到用户空间, 再换算为温度值
0 0
- linux3.2下adt7320的spi驱动编写
- beaglebone black spi使用笔记(2)-adt7320代码编写
- Linux3.6.9下AD7490的SPI通信驱动设计
- Linux下SPI从设备驱动的编写
- Linux下SPI从设备驱动的编写
- Linux下SPI从设备驱动的编写
- Linux3.5下的PWM蜂鸣器驱动测试 (2)
- Linux3.5下的蜂鸣器驱动测试
- spi驱动(基于linux3.4.2)
- Linux下的spi驱动
- SPI驱动编写
- 基于6467T的linux平台下的SPI驱动编写
- Linux下SPI和IIC驱动免在设备树上添加设备信息的编写方法
- 编写i2c驱动-基于Linux3.10
- 编写i2c驱动-基于Linux3.10
- linux下SPI驱动的补充
- Linux下的SPI总线驱动
- Linux下SPI驱动的分析
- 理解 Statement 和 PreparedStatement区别
- 高频热点账户(和库存类似但稍有不同)如何解决高并发余额计数问题?
- hdu4513 吉哥系列故事——完美队形II
- 需要这样一个记事本-15 ReportViewer打印默认页边距、页面方向问题
- 值得一看的博客
- linux3.2下adt7320的spi驱动编写
- POJ1149 PIGS (最大流)
- 大数据专家Bernard Marr:大数据是如何对抗癌症的?
- A1062 Talent and Virtue (25)
- (四) Basic Build Customization(基本的构建定制 :签名,构建,混淆)
- 两段函数求值
- poj 2752 Seek the Name, Seek the Fame
- 浅析JVM
- 数据结构基础(24) --红黑树的设计与实现(下)