天嵌 ARM开发社区

 找回密码
 注册
查看: 4117|回复: 12

TQ2440 OV3640 无法调通

[复制链接]
minghui2009 发表于 2012-11-1 10:14:22 | 显示全部楼层 |阅读模式
我配置了linux AT2402 I2C 能正确读写,但无法通过I2C总想读取OV3640的的寄存器配置。PWD 已经拉低
 楼主| minghui2009 发表于 2012-11-1 10:17:13 | 显示全部楼层
能否给一个简单的测试代码,测试OV3640是否正常
回复

使用道具 举报

TQ-ZQL 发表于 2012-11-1 10:48:01 | 显示全部楼层
本帖最后由 TQ-ZQL 于 2012-11-1 10:48 编辑

先保证你的硬件工作正常。默认即使不配置i2c,ov3640也会有图像输出的。你可以看下有没有数据个输出。然后注意下3640的寄存器地址是2字节的。与9650有点不同。
回复

使用道具 举报

 楼主| minghui2009 发表于 2012-11-1 12:20:23 | 显示全部楼层
用示波器测试了,硬件没问题,在CAMCLK输入24M信号,在CAM_PCLK有信号输出,按照你说的硬件就应该没问题
回复

使用道具 举报

 楼主| minghui2009 发表于 2012-11-1 12:23:25 | 显示全部楼层
这是我修改9650的程序,读出3640设备号。如下
u8 sccb_read(u8 IdAddr, u16 SubAddr)
{
        u8 data;
    u8 SubAddrL ,SubAddrH ;
        SubAddrL = SubAddr&0x00FF;
        SubAddrH = SubAddr>>8 ;
        printk("subAddrH is %2x subAddrL is %2x \n",SubAddrH,SubAddrL);
        down(&bus_lock);
        sccb_start();
        sccb_write_byte(IdAddr);  
        sccb_write_byte(SubAddrH);      
        sccb_write_byte(SubAddrL);        
        sccb_stop();

        sccb_start();
        sccb_write_byte(IdAddr|0x01);
        data = sccb_read_byte();
        sccb_stop();
        up(&bus_lock);
       
        return data;
}
回复

使用道具 举报

 楼主| minghui2009 发表于 2012-11-1 12:29:11 | 显示全部楼层
本帖最后由 minghui2009 于 2012-11-1 12:35 编辑

然后再s3c2440_ov3640_init中加入
ov3640_poweron();
mdelay(100);
printk("ov3640 SCCB ID is 0x%x\n",sccb_read(0x78,0x300c);//0x300c  SCCB ID
);
但就是sccb_read(0x78,0x300c);读出的数据为0xff应该为0x78才对
所以考虑应该是i2c 的问题,但这程序在9650中测试过应该没问题啊
回复

使用道具 举报

 楼主| minghui2009 发表于 2012-11-1 12:31:42 | 显示全部楼层
本帖最后由 minghui2009 于 2012-11-1 12:36 编辑

// 公司    :红蝶科技(深圳)有限公司
// 作者    :文元波 0755-86139000-1024/13332904048
// 文件名  :test7725.c
// 功能    :读写I2C的寄存器。运行在LINUX的APP层。
// 日期    :2012-8-21 16:50
// 维护者  :
// 维护记录:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <ctype.h>
#include <stdint.h>
#include<stdlib.h>
#include<sys/ioctl.h>
#include <linux/fb.h>
#include <string.h>


// /home/disk2/PP1938-V2.4.1/customer_release# grep I2C_TENBIT . -r
// ./compile_scripts/linux-2.6.29-maximus/include/linux/i2c-dev.h
#define I2C_RETRIES 0x0701 /* number of times a device address should
be polled when not acknowledging */
#define I2C_TIMEOUT 0x0702 /* set timeout in units of 10 ms */
/* NOTE: Slave address is 7 or 10 bits, but 10-bit addresses
* are NOT supported! (due to code brokenness)
*/
#define I2C_SLAVE 0x0703 /* Use this slave address */
#define I2C_SLAVE_FORCE 0x0706 /* Use this slave address, even if it
is already in use by a driver! */
#define I2C_TENBIT 0x0704 /* 0 for 7 bit addrs, != 0 for 10 bit */
#define I2C_FUNCS 0x0705 /* Get the adapter functionality mask */
#define I2C_RDWR 0x0707 /* Combined R/W transfer (one STOP only) */
#define I2C_PEC  0x0708 /* != 0 to use PEC with SMBus */
#define I2C_SMBUS 0x0720 /* SMBus transfer */


//#define IC_ADDRESS (0x42>>1)
// OV3640
#define IC_ADDRESS (0x78>>1)
#define RW_DELAY 10
#define I2C_OV7725 "/dev/i2c-0"
int i2c_fd;


// 函数名称:i2c_init
// 函数功能:打开I2C
// 参数列表:
// 返回值  :
int i2c_init(char *fn)
{
i2c_fd = open(fn, O_RDWR);
printf("i2c_fd = %d\n", i2c_fd);
if (i2c_fd < 0)
{
  printf("I2CLIB: error open device\n");
  return 0;
}
return i2c_fd;
}


// 函数名称:i2c_close
// 函数功能:关闭I2C
// 参数列表:
// 返回值  :
int i2c_close(void)
{
close(i2c_fd);
return 0;
}


// 0x3005
// ./test7725 r 12293
// 0x40=64
// ./test7725 w 12293 13
// 函数名称:i2c_write
// 函数功能:往I2C寄存器中读一个字节
// 参数列表:
// 返回值  :
// void i2c_write(unsigned char addr,unsigned char value)
void i2c_write(int addr,unsigned char value)
{
unsigned char temp[3];
temp[0] = addr >> 8;
temp[1] = addr & 0xff;
// temp[1] = value;
temp[2] = value;
// if (ioctl(i2c_fd, I2C_SLAVE, IC_ADDRESS) < 0)
if (ioctl(i2c_fd, I2C_SLAVE_FORCE, IC_ADDRESS) < 0)
{
  printf("I2CLIB_W: error set IC_ADDRESS\n");
}

// if(write(i2c_fd, temp, 2)!=2)
if(write(i2c_fd, temp, 3)!=3)
{
  printf("I2C write failure???? addr=%04d,0x%04x\n", addr, addr);
}




// 写入之后再读出来。
usleep(RW_DELAY*1000);
// if(write(i2c_fd, temp, 2)!=1)
if(write(i2c_fd, temp, 2)<0)
{
  // printf("TVIN:I2C Write Addr %x fail.\n",temp[0]);
  printf("TVIN:I2C Write Addr %x fail.\n", addr);
}
usleep(RW_DELAY*1000);
unsigned char temp2 = 0;

// if(read(i2c_fd, temp, 1)!=1)
// if(read(i2c_fd, temp, 2)<0)
if(read(i2c_fd, &temp2, 1)<0)
{
  // printf("TVIN:I2C Read Data[%d]=%x fail.\n",temp[0],temp[0]);
  printf("TVIN:I2C Read Register Address [%04x] Data fail.\n", addr);
}

printf("temp2=%03d, 0x%04x \n", temp2, temp2);
usleep(RW_DELAY*1000);
}


// 函数名称:i2c_read
// 函数功能:从I2C寄存器中读一个字节
// 参数列表:
// 返回值  :
int i2c_read(int start_add)
{
unsigned char temp[2];
temp[0] = start_add >> 8;
temp[1] = start_add & 0xff;
// printf("temp[0]=%x, temp[1]=%x\n", temp[0], temp[1]);
// printf("address=0x%02x%02x\n", temp[0], temp[1]);
//DBG_TVP("Running i2c_read_register().\n");
// if (ioctl(i2c_fd, I2C_SLAVE, IC_ADDRESS) < 0)
if (ioctl(i2c_fd, I2C_SLAVE_FORCE, IC_ADDRESS) < 0)
{
  printf("I2CLIB_R1: error set IC_ADDRESS =0x%04x \n", IC_ADDRESS);
  return -1;
}
if (ioctl(i2c_fd, I2C_RETRIES, 1) < 0)
{
  printf("I2CLIB_R2: error set IC_ADDRESS\n");
  return -1;
}
usleep(RW_DELAY*1000);
// if(write(i2c_fd, temp, 2)!=1)
if(write(i2c_fd, temp, 2)<0)
{
  // printf("TVIN:I2C Write Addr %x fail.\n",temp[0]);
  printf("TVIN:I2C Write Addr %x fail.\n",start_add);
}
usleep(RW_DELAY*1000);
// if(read(i2c_fd, temp, 1)!=1)
// if(read(i2c_fd, temp, 2)<0)
if(read(i2c_fd, temp, 1)<0)
{
  // printf("TVIN:I2C Read Data[%d]=%x fail.\n",temp[0],temp[0]);
  printf("TVIN:I2C Read Register Address [%04x] Data fail.\n", start_add);
}
usleep(RW_DELAY*1000);
return temp[0];
}


// 函数名称:main
// 函数功能:
// 参数列表:
// 返回值  :
#include <stdlib.h>
int main(int argc, char **argv)
{
int address = 0;
// int value = 0;
unsigned char value = 0;
char command;
sscanf(argv[1], "%c", &command);
if(argc ==3 )
{
  // 2012-8-21 17:18 请特别注意,使用 sscanf 会出错
  // sscanf(argv[2], "0x%x", &address);
  address = atoi(argv[2]);
}  
else if(argc ==4)
{
  address = atoi(argv[2]);
  value = atoi(argv[3]);
  
  printf("argv[3] value=%d, 0x%04x\n", value, value);
}
else
{
  printf("parameter error\n");
  return 0;
}
printf("argv[2] address=%d, 0x%04x\n", address, address);
i2c_init(I2C_OV7725);

if(command == 'r')
{
  value = i2c_read(address);
  
  printf("read, [0x%04x] = 0x%02x = %03d\n", address, value, value);
}
else if(command == 'w')
{
  printf("write,[0x%x] = 0x%x\n",address,value);
  
  i2c_write(address,value);
}
else
{
  printf("unknown command %c\n", command);
}
i2c_close();
return 0;
}
用网上的这个程序也不行,实在是弄不明白啊
回复

使用道具 举报

TQ-ZQL 发表于 2012-11-1 14:18:59 | 显示全部楼层
你用示波器看下你sccb的输出时序对不对,看下是没有数据还是有数据你读不到
回复

使用道具 举报

 楼主| minghui2009 发表于 2012-11-1 14:39:07 | 显示全部楼层
读出来的全为1,错误的
回复

使用道具 举报

 楼主| minghui2009 发表于 2012-11-1 14:40:06 | 显示全部楼层
本帖最后由 minghui2009 于 2012-11-1 14:42 编辑

设备号是0x78,但为什么有些程序要进行0x78>>1.会不会是地址的问题????
回复

使用道具 举报

TQ-ZQL 发表于 2012-11-1 15:55:25 | 显示全部楼层
本帖最后由 TQ-ZQL 于 2012-11-1 15:55 编辑

你用示波器看下你sccb的输出时序对不对,sccb的话地址不用移
回复

使用道具 举报

 楼主| minghui2009 发表于 2012-11-1 16:04:41 | 显示全部楼层
sccb的输出时序不对,怎么办???
回复

使用道具 举报

ww110052181 发表于 2012-11-5 13:35:24 | 显示全部楼层
:@:@:@:@:@:@:@
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2025-6-23 11:46 , Processed in 2.046455 second(s), 19 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表