diff --git a/21_iic/.vscode/c_cpp_properties.json b/21_iic/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000000000000000000000000000000..79c6d19a12c235b7345b1cdd14efbde03c2b4f75 --- /dev/null +++ b/21_iic/.vscode/c_cpp_properties.json @@ -0,0 +1,50 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "linux-gcc-x64", + "browse": { + "path": [ + "${workspaceFolder}", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ] + } + }, + { + "name": "Win32", + "includePath": [ + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/generated", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/arch/arm/include/asm", + "../../../linux-imx-rel_imx_4.1.15_2.1.0_ga/drivers", + "${workspaceFolder}/**", + "${default}" + ], + "defines": ["__KERNEL__","__linux__"], + "compilerPath": "C:/Qt/Qt5.12.9/Tools/mingw730_64/bin/gcc.exe", + "cStandard": "c11", + "cppStandard": "c++17", + "intelliSenseMode": "windows-gcc-x64" + } + ], + "version": 4 +} diff --git a/21_iic/.vscode/settings.json b/21_iic/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..1a2a04ac7a2d6b080404235adcd34b94bc581cb4 --- /dev/null +++ b/21_iic/.vscode/settings.json @@ -0,0 +1,21 @@ +{ + "search.exclude": { + "**/node_modules": true, + "**/bower_components": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + }, + "files.exclude": { + "**/.git": true, + "**/.svn": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/*.o":true, + "**/*.su":true, + "**/*.cmd":true, + "Documentation":true, + } +} \ No newline at end of file diff --git a/21_iic/Makefile b/21_iic/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..750cd50e1db5e341d17b7aab7a91184feeca8c43 --- /dev/null +++ b/21_iic/Makefile @@ -0,0 +1,13 @@ +KERNELDIR := ../../../linux-imx-rel_imx_4.1.15_2.1.0_ga +CURRENT_PATH := $(shell pwd) +obj-m := ap3216c.o + +build: kernel_modules + +kernel_modules: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) modules + +clean: + $(MAKE) -C $(KERNELDIR) M=$(CURRENT_PATH) clean + + diff --git a/21_iic/ap3216c.c b/21_iic/ap3216c.c new file mode 100644 index 0000000000000000000000000000000000000000..a30d8be9ac54ac431b5732706633d756ddc06f92 --- /dev/null +++ b/21_iic/ap3216c.c @@ -0,0 +1,230 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ap3216creg.h" + +#define AP3216C_CNT 1 +#define AP3216C_NAME "ap3216c" + +struct ap3216c_dev +{ + dev_t devid; /* 设备号 */ + struct cdev cdev; + struct device *device; + struct class *class; + struct device_node *nd; + int major; + void *private_data; + unsigned short ir, als, ps; /* 三个光传感器数据 */ +}; + +static struct ap3216c_dev ap3216cdev; + +static s32 ap3216c_write_regs(struct ap3216c_dev *dev,u8 reg,u8 *buf,u8 len) +{ + u8 b[256]; + struct i2c_msg msg; + struct i2c_client *client = (struct i2c_client *)dev->private_data; + b[0] = reg; + memcpy(&b[1], buf, len); + msg.addr = client->addr; + msg.flags = 0; + msg.buf = b; + msg.len = len + 1; + return i2c_transfer(client->adapter, &msg, 1); +} + +static void ap3216c_write_reg(struct ap3216c_dev *dev,u8 reg,u8 data) +{ + u8 buf = 0; + buf = data; + ap3216c_write_regs(dev, reg, &buf, 1); +} + +static int ap3216c_open(struct inode *nd, struct file *filp) +{ + filp->private_data = &ap3216cdev; + ap3216c_write_reg(&ap3216cdev, AP3216C_SYSTEMCONG, 0x04); + mdelay(50); + ap3216c_write_reg(&ap3216cdev, AP3216C_SYSTEMCONG, 0x03); + return 0; +} + +static int ap3216c_read_regs(struct ap3216c_dev *dev,u8 reg,void *val,int len) +{ + int ret; + struct i2c_msg msg[2]; + struct i2c_client *client = (struct i2c_client *)dev->private_data; + + msg[0].addr = client->addr; + msg[0].flags = 0; + msg[0].buf = ® + msg[0].len = 1; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = val; + msg[1].len = len; + + ret = i2c_transfer(client->adapter, msg, 2); + if (ret == 2) + { + ret = 0; + }else { + printk("i2c read failed=%d,reg=%06x,len=%d\r\n", ret, reg, len); + ret = -EREMOTEIO; + } + + return ret; +} + +static unsigned char ap3216c_read_reg(struct ap3216c_dev *dev,u8 reg) +{ + u8 data = 0; + ap3216c_read_regs(dev, reg, &data, 1); + return data; +} + +void ap3216c_readdata(struct ap3216c_dev *dev) +{ + unsigned char i = 0; + unsigned char buf[6]; + + for (i = 0; i < 6;i++){ + buf[i] = ap3216c_read_reg(dev, AP3216C_IRDATALOW + i); + } + if(buf[0] & 0x80) + dev->ir = 0; + else + dev->ir = ((unsigned short)buf[1] << 2) | (buf[0] & 0x03); + dev->als = ((unsigned short)buf[3] << 8) | buf[2]; + if(buf[4] & 0x40) + dev->ps = 0; + else + dev->ps = ((unsigned short)(buf[5] & 0x3F) << 4) | (buf[4] & 0x0F); +} + +static ssize_t ap3216c_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) +{ + short data[3]; + long err = 0; + struct ap3216c_dev *dev = (struct ap3216c_dev *)filp->private_data; + ap3216c_readdata(dev); + data[0] = dev->ir; + data[1] = dev->als; + data[2] = dev->ps; + err = copy_to_user(buf, data, sizeof(data)); + return 0; +} + +static int ap3216c_release(struct inode *inode, struct file *file) +{ + + return 0; +} + +static const struct file_operations ap3216c_ops = { + .owner = THIS_MODULE, + .open = ap3216c_open, + .read = ap3216c_read, + .release = ap3216c_release, + +}; + +static int ap3216c_probe(struct i2c_client *client, const struct i2c_device_id *id) +{ + /* 1、构建设备号 */ + if(ap3216cdev.major){ + ap3216cdev.devid = MKDEV(ap3216cdev.major, 0); + register_chrdev_region(ap3216cdev.devid, AP3216C_CNT,AP3216C_NAME); + }else { + alloc_chrdev_region(&ap3216cdev.devid, 0, AP3216C_CNT,AP3216C_NAME); + ap3216cdev.major = MAJOR(ap3216cdev.devid); + } + + /* 2、 注册设备 */ + cdev_init(&ap3216cdev.cdev, &ap3216c_ops); + cdev_add(&ap3216cdev.cdev, ap3216cdev.devid, AP3216C_CNT); + + /* 3、创建类 */ + ap3216cdev.class = class_create(THIS_MODULE, AP3216C_NAME); + if (IS_ERR(ap3216cdev.class)) + { + return PTR_ERR(ap3216cdev.class); + } + + /* 4、创建设备 */ + ap3216cdev.device = device_create(ap3216cdev.class, NULL, ap3216cdev.devid, NULL, AP3216C_NAME); + if(IS_ERR(ap3216cdev.device)){ + return PTR_ERR(ap3216cdev.device); + } + + ap3216cdev.private_data = client; + return 0; +} + +static int ap3216c_remove(struct i2c_client *client) +{ + cdev_del(&ap3216cdev.cdev); + unregister_chrdev_region(ap3216cdev.devid, AP3216C_CNT); + + device_destroy(ap3216cdev.class, ap3216cdev.devid); + class_destroy(ap3216cdev.class); + return 0; +} + +static struct i2c_device_id ap3216c_id[] = { + {"alienek,ap3216c", 0}, + {/* */} +}; + + +static struct of_device_id ap3216c_of_match[] = { + {.compatible = "alientek,ap3216c" }, + {/* */} +}; + + + +struct i2c_driver ap3216c_driver = { + .probe = ap3216c_probe, + .remove = ap3216c_remove, + .driver = { + .owner = THIS_MODULE, + .name = "ap3216c", + .of_match_table = ap3216c_of_match, + }, + .id_table = ap3216c_id, +}; + +static int __init ap3216c_init(void) +{ + int ret = 0; + + ret = i2c_add_driver(&ap3216c_driver); + return ret; +} + +static void __exit ap3216c_exit(void) +{ + i2c_del_driver(&ap3216c_driver); +} + +module_init(ap3216c_init); +module_exit(ap3216c_exit); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("zhangchaoliang"); diff --git a/21_iic/ap3216cApp.c b/21_iic/ap3216cApp.c new file mode 100644 index 0000000000000000000000000000000000000000..610d3b66092de8fe6fa85a0722c4e44ad84b43bc --- /dev/null +++ b/21_iic/ap3216cApp.c @@ -0,0 +1,48 @@ +#include "stdio.h" +#include "unistd.h" +#include "sys/types.h" +#include "sys/stat.h" +#include "sys/ioctl.h" +#include "fcntl.h" +#include "stdlib.h" +#include "string.h" +#include +#include +#include +#include +#include + +int main(int argc,char *argv[]) +{ + int fd; + char *filename; + unsigned short databuf[3]; + + unsigned short ir, als, ps; + int ret = 0; + if(argc !=2){ + printf("Error Usage!\r\n"); + return -1; + } + + filename = argv[1]; + fd = open(filename, O_RDWR); + if(fd <0 ){ + printf("can't open file %s\r\n", filename); + return -1; + } + + while (1) + { + ret = read(fd, databuf, sizeof(databuf)); + if(ret == 0){ + ir = databuf[0]; + als = databuf[1]; + ps = databuf[2]; + printf("ir = %d, als = %d, ps = %d\r\n", ir, als, ps); + } + usleep(200000); + } + close(fd); + return 0; +} \ No newline at end of file diff --git a/21_iic/ap3216creg.h b/21_iic/ap3216creg.h new file mode 100644 index 0000000000000000000000000000000000000000..39f161427702a053ba8710552c592674f1d38576 --- /dev/null +++ b/21_iic/ap3216creg.h @@ -0,0 +1,14 @@ +#ifndef AP3216C_H +#define AP3216C_H + +#define AP3216C_SYSTEMCONG 0x00 /* 配置寄存器 */ +#define AP3216C_INTSTATUS 0X01 /* 中断状态寄存器 */ +#define AP3216C_INTCLEAR 0X02 /* 中断清除寄存器 */ +#define AP3216C_IRDATALOW 0x0A /* IR 数据低字节 */ +#define AP3216C_IRDATAHIGH 0x0B /* IR 数据高字节 */ +#define AP3216C_ALSDATALOW 0x0C /* ALS 数据低字节 */ +#define AP3216C_ALSDATAHIGH 0X0D /* ALS 数据高字节 */ +#define AP3216C_PSDATALOW 0X0E /* PS 数据低字节 */ +#define AP3216C_PSDATAHIGH 0X0F /* PS 数据高字节 */ + +#endif // \ No newline at end of file diff --git a/21_iic/iic.code-workspace b/21_iic/iic.code-workspace new file mode 100644 index 0000000000000000000000000000000000000000..4575012c7e24b6c8553576fdabca8635f0f4e51e --- /dev/null +++ b/21_iic/iic.code-workspace @@ -0,0 +1,22 @@ +{ + "folders": [ + { + "path": "." + } + ], + "settings": { + "files.associations": { + "ide.h": "c", + "init.h": "c", + "time.h": "c", + "stdlib.h": "c", + "i2c.h": "c", + "interrupt.h": "c", + "hardirq.h": "c", + "irq.h": "c", + "types.h": "c", + "proc_fs.h": "c" + } + + } +} \ No newline at end of file