📄 csi2c.c
字号:
/*Special notes for CMOS sensor data capture.*/#include <linux/kernel.h>#include <linux/module.h>#include <linux/compatmac.h>#include <linux/hdreg.h>#include <linux/vmalloc.h>#include <linux/fs.h>#include <linux/module.h>#include <linux/blkpg.h>#include <linux/i2c.h>#include <linux/i2c-algo-bit.h>#include <linux/i2c-id.h>#include <linux/slab.h>#include <asm/io.h>#include <linux/mm.h>#include <linux/wrapper.h>#include <asm/dma.h>#include <linux/miscdevice.h>#include <asm/arch/mx2.h>#include "type.h"#define MCLK 24 /* 24MHz */#define SYSCLK 133 /* 96MHz */#define CSI_IRQ 31#define QVGA_SIZE 320*240*2 /* YUV4:2:2 */#define OV7649_ADDR 0x42//#define _ADS20_ 1// functions and interfacestatic int csi2c_open(struct inode *inode, struct file *filp);static int csi2c_release(struct inode *inode, struct file *filp);static ssize_t csi2c_read(struct file *filp, char *buf, size_t size, loff_t *l);static ssize_t csi2c_write(struct file *filp, const char *buf, size_t size, loff_t *l);static int csi2c_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);static void dma_complete_handler(void);static UINT32 *csi_data_buf=0;static UINT32 dma_buf_phy_addr;static UINT32 gMajor;//static UINT32 capture_frames = 0;static int number_sof = 0;static int number_dma = 0;//static int flag = 1;static int g_bad_frame = 0;static int _gDmaChanel=-1;static DECLARE_WAIT_QUEUE_HEAD(g_capture_wait);struct file_operations csi2c_fops = { open: csi2c_open, release: csi2c_release, read: csi2c_read, write: csi2c_write, ioctl: csi2c_ioctl,};void delay500ns(){ int i; for(i=0;i<100;i++);}void delay1us(){ delay500ns(); delay500ns();}void delay2us(){ delay1us(); delay1us();}void delay5us(){ delay2us(); delay2us(); delay1us();}void delay8us(){ delay5us(); delay2us(); delay1us();}void delay10us(){ delay5us(); delay5us();}SINT32 set_sda_input(){ /* * PE3 : SDA * PE4 : SCL */ _reg_GPIO_DDIR(GPIOE) &= ~0x00000008; return 0;}SINT32 set_sda_output(){ /* * PE3 : SDA * PE4 : SCL */ _reg_GPIO_DDIR(GPIOE) |= 0x00000008; return 0;}SINT32 set_sda_value(UINT8 flag){ /* * PE3 : SDA * PE4 : SCL */ if(flag) _reg_GPIO_DR(GPIOE) |= 0x00000008; else _reg_GPIO_DR(GPIOE) &= ~0x0000008; return 0;}SINT32 set_scl_high(){ /* * PE3 : SDA * PE4 : SCL */ _reg_GPIO_DR(GPIOE) |= 0x00000010; return 0;}SINT32 set_scl_low(){ /* * PA15 : SDA * PA16 : SCL */ _reg_GPIO_DR(GPIOE) &= ~0x00000010; return 0;}/* Read sda status */UINT8 get_sda_value(){ if(_reg_GPIO_SSR(GPIOE) & 0x00000008) return 0x01; else return 0x00;}/* SCCB write */ void sccb_write(UINT8 reg, UINT8 data){ int i; UINT8 addr; addr = OV7649_ADDR; set_sda_value(1); set_scl_high(); delay10us(); set_sda_value(0); // Issue start command /* Send ID address */ for(i=0;i<8;i++) { delay10us(); set_scl_low(); // First clock start delay500ns(); set_sda_value((addr >> (7-i)) & 0x01); delay10us(); set_scl_high(); } delay10us(); set_scl_low(); // The Ninth clock start delay1us(); set_sda_input(); delay8us(); set_scl_high(); // Dont't care bit delay10us(); set_scl_low(); delay2us(); set_sda_output(); /* Send sub address */ for(i=0;i<8;i++) { delay500ns(); set_sda_value((reg >> (7-i)) & 0x01); delay10us(); set_scl_high(); delay10us(); set_scl_low(); } delay1us(); set_sda_input(); delay8us(); set_scl_high(); // Dont't care bit delay10us(); set_scl_low(); delay2us(); set_sda_output(); /* Send sub address */ for(i=0;i<8;i++) { delay500ns(); set_sda_value((data >> (7-i)) & 0x01); delay10us(); set_scl_high(); delay10us(); set_scl_low(); } delay1us(); set_sda_input(); delay8us(); set_scl_high(); // Dont't care bit delay10us(); set_scl_low(); delay2us(); set_sda_output(); set_sda_value(0); delay10us(); set_scl_high(); delay10us(); set_sda_value(1); // Stop return; }/* SCCB write */ void sccb_read(UINT8 reg, UINT8 *data){ int i; UINT8 addr,ret; ret = 0; *data = 0; /* 2-phases write */ addr = OV7649_ADDR; set_sda_value(1); set_scl_high(); delay10us(); set_sda_value(0); // Issue start command /* Send ID address */ for(i=0;i<8;i++) { delay10us(); set_scl_low(); // First clock start delay500ns(); set_sda_value((addr >> (7-i)) & 0x01); delay10us(); set_scl_high(); } delay10us(); set_scl_low(); // The Ninth clock start delay1us(); set_sda_input(); delay8us(); set_scl_high(); // Dont't care bit delay10us(); set_scl_low(); delay2us(); set_sda_output(); /* Send sub address */ for(i=0;i<8;i++) { delay500ns(); set_sda_value((reg >> (7-i)) & 0x01); delay10us(); set_scl_high(); delay10us(); set_scl_low(); } delay1us(); set_sda_input(); delay8us(); set_scl_high(); // Dont't care bit delay10us(); set_scl_low(); delay2us(); set_sda_output(); set_sda_value(0); delay10us(); set_scl_high(); delay10us(); set_sda_value(1); // Stop 2-phases write /****************************************************************/ /* 2-phases read */ addr = OV7649_ADDR + 1; set_sda_value(1); set_scl_high(); delay10us(); set_sda_value(0); // Issue start command /* Send ID address */ for(i=0;i<8;i++) { delay10us(); set_scl_low(); // First clock start delay500ns(); set_sda_value((addr >> (7-i)) & 0x01); delay10us(); set_scl_high(); } delay10us(); set_scl_low(); // The Ninth clock start delay1us(); set_sda_input(); delay8us(); set_scl_high(); // Dont't care bit delay10us(); for(i=0;i<8;i++) { set_scl_low(); delay10us(); set_scl_high(); delay5us(); ret = get_sda_value(); *data |= (ret << (7-i)); delay5us(); } set_scl_low(); // The Ninth clock start delay1us(); set_sda_output(); delay500ns(); set_sda_value(1); delay8us(); set_scl_high(); // Dont't care bit delay10us(); set_scl_low(); delay5us(); set_sda_value(0); delay10us(); set_scl_high(); delay10us(); set_sda_value(1); // Stop 2-phases write }/* Initialize SCCB signal, simulation SCCB timing by GPIO */SINT32 sccb_init(){ /* * PA15 : SDA * PA16 : SCL */ _reg_GPIO_GIUS(GPIOE) |= 0x00000018; _reg_GPIO_OCR1(GPIOE) |= 0x000003C0; _reg_GPIO_DDIR(GPIOE) |= 0x00000018; set_sda_value(1); set_scl_high(); return 0;} int sccb_write_check(UINT8 reg, UINT8 data){ UINT8 ret = 0; sccb_write(reg,data); sccb_read(reg,&ret); if(ret != data) printk("I2C write error!\n");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -