/*
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 interface
static 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");
return 0;
}
void set_ov7649_reg_yuv422()
{
int i;
sccb_write(0x12,0x80); // Reset all registers
for(i=0;i<1000;i++)
delay10us();
sccb_write_check(0x03,0xA4);
sccb_write_check(0x04,0x30);
sccb_write_check(0x05,0x88);
sccb_write_check(0x06,0x60);
sccb_write_check(0x11,0x00);
sccb_write_check(0x12,0x05);
sccb_write_check(0x13,0xA3);
sccb_write_check(0x14,0x24); //0x04 for VGA, 0x24 for QVGA
sccb_write_check(0x15,0x04);
sccb_write_check(0x1F,0x41);
sccb_write_check(0x20,0xD0);
sccb_write_check(0x23,0xDE);
sccb_write_check(0x24,0xA0);
sccb_write_check(0x25,0x80);
sccb_write_check(0x26,0x32);
sccb_write_check(0x27,0xE2);
sccb_write_check(0x28,0x20);
sccb_write_check(0x2A,0x11);
sccb_write_check(0x2B,0x00);
sccb_write_check(0x2D,0x05);
sccb_write_check(0x2F,0x9C);
sccb_write_check(0x30,0x00);
sccb_write_check(0x31,0xC4);
sccb_write_check(0x60,0x86);
sccb_write_check(0x61,0xE0);
sccb_write_check(0x62,0x88);
sccb_write_check(0x63,0x11);
sccb_write_check(0x64,0x89);
sccb_write_check(0x65,0x00);
sccb_write_check(0x67,0x14); //0x94 for YCrCb, 0x14 for YUV
sccb_write_check(
csi.rar_csi
版权申诉
184 浏览量
2022-09-23
07:45:09
上传
评论
收藏 12KB RAR 举报
小贝德罗
- 粉丝: 68
- 资源: 1万+
最新资源
- 基于STM32F103C8T6单片机蓄电池在线监测系统主板硬件(原理图+PCB)工程文件.zip
- mysql大纲资料.txt
- c++大纲资料.txt
- 效率工具bat脚本实现日志提取
- MyBatis 中动态 SQL 的示例
- STM8L101F3P6单片机+CC1100模块433M遥控器设计硬件(原理图+PCB)工程文件.zip
- 上传下载铁人下载系统 Liuxing 1.0-liuxing1.0.rar
- 南京邮电大学数学实验实力雄厚,凭借其优秀的师资力量、丰富的实践教学资源和卓越的科研成果,成为国内一流的数学实验教学和科研基地
- 【火爆朋友圈的今天吃什么源码 v1.0】随机的为用户带来每一天的用餐选择和推荐.rar
- MPU6050中文版数据手册
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈