2440 OV9652摄像头驱动调试

2440 OV9652摄像头驱动调试

//-----------------------------------------------------------------------------------------------------------

// 作者:wogoyixikexie@gliet(gooogleman)

// 版权:桂林电子科技大学一系科协wogoyixikexie@gliet

// 平台:wince5.0 2440 5.0 BSP

// 发布日期:2009年5月4日 11:05:19

// 最后修改:2009年5月20日 8:51:39

// 注意事项:未经作者同意,不得在转载的时候擅自修改、删除文章的任何部分

//-----------------------------------------------------------------------------------------------------------

C/C++ code
 
    
我使用GPIO模拟IIC初始化OV9652 已经成功(我读出来和写入数值一致)并且用应用程序打开摄像头驱动时候,摄像头驱动也已经能够不停的产生中断。但是不知道怎么回事,但是图像死活不出现。——我用老的BSP 编译出NK 摄像头可以正常采集,排除了硬件问题。但是我把老的BSP的代码搬到5. 0 却死活不出图像了。我推测是DMA问题,我根据内存映射表修改了一番,可是还是没有结果。我的内存映射表g_oalAddressTableDCD 0x80000000 , 0x30000000 , 64 ; 32 MB DRAM BANK 6 DCD 0x84000000 , 0x10000000 , 32 ; nGCS2: PCMCIA / PCCARDDCD 0x86000000 , 0x18000000 , 32 ; 32 MB SROM(SRAM / ROM) BANK 3 DCD 0x88000000 , 0x20000000 , 32 ; 32 MB SROM(SRAM / ROM) BANK 4 DCD 0x8A000000 , 0x28000000 , 32 ; 32 MB SROM(SRAM / ROM) BANK 5 DCD 0x8C000000 , 0x08000000 , 32 ; 32 MB SROM(SRAM / ROM) BANK 1 DCD 0x90800000 , 0x48000000 , 1 ; Memory control registerDCD 0x90900000 , 0x49000000 , 1 ; USB Host registerDCD 0x90A00000 , 0x4A000000 , 1 ; Interrupt Control registerDCD 0x90B00000 , 0x4B000000 , 1 ; DMA control registerDCD 0x90C00000 , 0x4C000000 , 1 ; Clock & Power registerDCD 0x90D00000 , 0x4D000000 , 1 ; LCD control registerDCD 0x90E00000 , 0x4E000000 , 1 ; NAND flash control registerDCD 0x90F00000 , 0x4F000000 , 1 ; Camera control registerDCD 0x91000000 , 0x50000000 , 1 ; UART control registerDCD 0x91100000 , 0x51000000 , 1 ; PWM timer registerDCD 0x91200000 , 0x52000000 , 1 ; USB device registerDCD 0x91300000 , 0x53000000 , 1 ; Watchdog Timer registerDCD 0x91400000 , 0x54000000 , 1 ; IIC control registerDCD 0x91500000 , 0x55000000 , 1 ; IIS control registerDCD 0x91600000 , 0x56000000 , 1 ; I / O Port registerDCD 0x91700000 , 0x57000000 , 1 ; RTC control registerDCD 0x91800000 , 0x58000000 , 1 ; A / D convert registerDCD 0x91900000 , 0x59000000 , 1 ; SPI registerDCD 0x91A00000 , 0x5A000000 , 1 ; SD Interface registerDCD 0x92000000 , 0x00000000 , 32 ; 32 MB SROM(SRAM / ROM) BANK 0 DCD 0x94D00000 , 0x34000000 , 64 ; 64 MB SDRAM BANK 6 ——我使用的128M SDRAM 非连续方法扩展DCD 0x00000000 , 0x00000000 , 0 ; end of table我的config.bib的DMA内存设置。MEMORYNK 80200000 01E00000 RAMIMAGERAM 82000000 02000000 RAMFLASH 92000000 00100000 RESERVED; Common RAM areasAUD_DMA 80002000 00000800 RESERVEDSDIO_DMA 80010000 00010000 RESERVEDARGS 80020800 00000800 RESERVEDDBGSER_DMA 80022000 00002000 RESERVEDSER_DMA 80024000 00002000 RESERVEDIR_DMA 80026000 00002000 RESERVEDSLEEP 80028000 00002000 RESERVEDEDBG 80030000 00020000 RESERVED; DISPLAY 80100000 00100000 RESERVED; camera DMA 用于摄像头DMACAMERA 80050000 00110000 RESERVEDDISPLAY 84800000 00100000 RESERVEDCAMERA_CODE 84000000 00800000 RESERVED在camera驱动中我是这么定义的 // ----------------------------------yl2440 4.2-->5.0 BSP 's set--------------------------- // 1st Ping-pong Address   #define COPIFRAMEBUFFER_A 0x30050000 // 320*240 * 2(RGB 16bit) * 4 frames = 614400 = 0x96000 // 0x30030000 + 0x96000 = 0x300c6000 // #define COPIFRAMEBUFFER_B 0x32000000 // Max buffer size of Port : 0x1c2000 (640*480+640*480*2/4)*4 #define COPIFRAMEBUFFER_B 0x34000000 // 0x32000000-->0x34000000 // 要把CODE通道DMA地址放到不影响其他部分运行的RAM地址 #define VIRTUAL_OFFSET 0x7C000000 #define VIRTUAL_ADDR_OFFSET VIRTUAL_OFFSET // for MPEG4 中断的线程已经不停的执行,调用了 Display_Cam_Image( 0 , 0 , 240 , 240 , PORT_A);这明明是用来显示的,但是怎么会不出图像呢?------------------------------------------找到一点问题了
 
    
引用 6 楼 morris88 的回复:
dma 的配置、启用、停止很简单,使用物理地址,网卡、硬盘等经常使用...
你贴的东西没用...


我觉得就是DMA使用的问题。

我在config.bib这样使用

CAMERA                80050000  00110000  RESERVED ——这个没有问题
——下面两个84000000 以上了就是超过34000000 /64M的 范围,导致DMA不能落在SDRAM映射范围以内了!
    DISPLAY            84800000  00100000  RESERVED——
    CAMERA_CODE        84000000  00800000  RESERVED

虽然我的内存是128M的,但是使用了不连续的映射方法,所以不出问题才怪!
 
    

引用 13 楼 xajhuang 的回复:
DMA 寄存器里面的源地址和目的地址是物理地址,你不要写成虚拟地址了。
#define COPIFRAMEBUFFER_B    0x34000000 你的内存总共就64M 0x34000000 就是你内存结束的地方了 所以0x34000000后面没有可用的内存了。
还有就是 DMA 所用的内存必须是连续的,所以你DMA的缓冲区最好用RESERVED的内存地址
或者用DMA专用的内存分配函数分配DMA Buffer


那我在config.bib使用 后面那块内存应该可以吧?

就是这里:DCD    0x94D00000, 0x34000000, 64      ; 64 MB SDRAM BANK 6——我使用的128M SDRAM 非连续方法扩展
让我纳闷的是。我把
;    DISPLAY            80100000  00100000  RESERVED

    DISPLAY            80138000  00100000  RESERVED
改了,在LCD驱动中没有改动,但是LCD照样能正常运行。这是怎么回事?如果不正确,那么LCD不是会黑屏吗?
 
    
有点进展了,我把原来的config.bib和内存映射文件替换了。

但是非常郁闷,图像直接显示在LCD上,不会显示在应用程序上。并且,只显示一小部分,不知道咋回事,现在贴图。希望大家帮分析一下。

2440 OV9652摄像头驱动调试_第1张图片
 
    
我发现一个奇怪的问题——这个图像刚好覆盖了wince的背景图标!当我把wince背景图标设为无得时候,这个摄像头也不再显示了,真不知道为什么会这样
2440 OV9652摄像头驱动调试_第2张图片
 
    
引用 13 楼 xajhuang 的回复:
DMA 寄存器里面的源地址和目的地址是物理地址,你不要写成虚拟地址了。
#define COPIFRAMEBUFFER_B    0x34000000 你的内存总共就64M 0x34000000 就是你内存结束的地方了 所以0x34000000后面没有可用的内存了。
还有就是 DMA 所用的内存必须是连续的,所以你DMA的缓冲区最好用RESERVED的内存地址
或者用DMA专用的内存分配函数分配DMA Buffer


昨天看了一下代码,发现用DMA专用的内存分配函数分配DMA Buffer 比较合适,昨天出了奇怪的图像,现在重新搞。

// Allocate a block of virtual memory (physically contiguous) for the DMA buffers.
    //
    pVirtPreviewAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter1, Preview_Mem_Size, &g_PhysPreviewAddr, FALSE);
    if (pVirtPreviewAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Preview.\r\n")));
    }

    pVirtCodecAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter2, Codec_Mem_Size, &g_PhysCodecAddr, FALSE);
    if (pVirtCodecAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Codec.\r\n")));
    }
有了点进展,不过非常郁闷,自己产生异常了。

[CAM_HW] InterruptThread : Waiting For a Single Object

CameraCaptureThread(0)++
CamClockOn = 0
[CAM_HW] InterruptThread : bIdlePwrDown = TRUE
[CAM_HW] InterruptThread : Waiting For a Single Object

CAMERA: CIS_Open
IOCTL_CAM_GETINFO:Width=0, Height=0, Bytes=0, scale=0
WM_SIZE:wParam=0, nHeight=269, nCyCam=153
WM_PAINT:nCxCam=218, nCyCam=153
WM_PAINT:nCxCam=218, nCyCam=153
CamClockOn = 1
Prefetch Abort: Thread=988b2b3c Proc=81d26340 'device.exe'
AKY=ffffffff PC=024330b4(???+0x024330b4) RA=024330b4(???+0x024330b4) BVA=024330b4 FSR=00000005
怎么会出现个问号的异常呢?
对了,我想请教一下,打开config.bib里面的 AUTOSIZE=ON有影响吗?
 
    
这个世界真是无奇不有啊。
我把config.bib的 AUTOSIZE=ON
改为
AUTOSIZE=OFF

;0x30 / 0xff = 15%
  FSRAMPERCENT=0x30808080

固定程序内存和存储内存比例,一旦使用摄像头,居然死机了。改回来又好了。

这两天不停的尝试,做了很多无用功。
 
    
引用 28 楼 gooogleman 的回复:
引用 13 楼 xajhuang 的回复:
DMA 寄存器里面的源地址和目的地址是物理地址,你不要写成虚拟地址了。
#define COPIFRAMEBUFFER_B    0x34000000 你的内存总共就64M 0x34000000 就是你内存结束的地方了 所以0x34000000后面没有可用的内存了。
还有就是 DMA 所用的内存必须是连续的,所以你DMA的缓冲区最好用RESERVED的内存地址
或者用DMA专用的内存分配函数分配DMA Buffer


// Allocate a block of virtual memory (physically contiguous) for the DMA buffers.
    //
    pVirtPreviewAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter1, Preview_Mem_Size, &g_PhysPreviewAddr, FALSE);
    if (pVirtPreviewAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Preview.\r\n")));
    }

    pVirtCodecAddr = (PBYTE)HalAllocateCommonBuffer(&Adapter2, Codec_Mem_Size, &g_PhysCodecAddr, FALSE);
    if (pVirtCodecAddr == NULL)
    {
        RETAILMSG(TRUE, (TEXT("Camera:Virtual_Alloc() - Failed to allocate DMA buffer for Codec.\r\n")));
    }


照着DMA专用的内存分配函数分配DMA Buffer 能够显示图像区域了,但是不知道怎么回事,却不能出现图像,采集到不停闪烁的花纹,请有经验的大哥们指导一下。
2440 OV9652摄像头驱动调试_第3张图片
 
    
引用 34 楼 abo77281 的回复:
lz上面好象差不多了,有数据了,只不过是数据格式和大小可能有问题.

查下你的源图像的大小和编码格式有没有设置错?目标图像的大小有没有设置错。

camera要有dma buffer,你用HalAllocateCommonBuffer来开辟,只要用足够的ram就没有问题。查下你开辟的ram区大小,这个要根据图像的大小和编码格式来确定dma buffer的大小。 不要开辟小了,大了浪费内存,小了造成桢与桢数据重叠,显示模糊或是花屏。

查下你的显示区域…


是这样的。我使用config.bib预留内存的时候是可以显示图像的。难道真的是我计算错误了,初始化的代码在4.2BSP是已经正常使用的。

我算算。
 
    
越来越雷人了。我把
;    AUTOSIZE=ON
AUTOSIZE=OFF——这样图像只会出现一些有规律的蓝点。咋别人这么做就行呢。我已经改大了啊。
2440 OV9652摄像头驱动调试_第4张图片
 
    
==========================================================
 
    
哈哈哈哈哈哈,搞定了!!!!!!!!!!图像显示正常了。

上面那个异常,刚好是有个东西没有改,造成异常了。
//要把CODE通道DMA地址放到不影响其他部分运行的RAM地址
//#define VIRTUAL_OFFSET 0x7C000000
#define VIRTUAL_OFFSET 0x70000000——这个才行的。
 
    
为什么是这个偏移地址,呢,因为在config.bib和内存映射文件决定了,4.2BSP和5.0BSP不同,所以这个也要做相应改变, 否则会产生异常的。加上这个虚拟地址偏移地址刚好是uncached 的虚拟地址,可以在wince访问了 。但是,我有点纳闷的是
 
    
我使用动态申请DMA的方法却不行,即使我修改了虚拟地址偏移。也没有异常产生,按照道理这应该是可行并且比较有效利用
 
    
内存的办法的,实在是可惜了。以后有空再研究吧。
这天是最后一天期限,终于顺利完成任务,不然要扣钱的。谢谢各位了。这几天的郁闷让我学到了好多东西。
 
    
发个照片上来
虽然立宇泰有些驱动做的比较劣质,价格也挺贵,但是毕竟带我入了门。
哈哈。
2440 OV9652摄像头驱动调试_第5张图片

 
    
 总结一下2440 OV9650 Camera驱动的流程:初始化接口(并打开电源,我的板子改了,我上次相当郁闷,用别人的驱动没有加入打开电源的动作
 
    
结果导致,初始化OV9650一直不成功,我还以为是什么问题,真是很弱智的错误)——》初始化中断,绑定线程——)等待线程中断——》
 
    
产生中断——》显示图像,更新图像。
 
    
最后,我要提醒的是config.bib的修改注意事项:不能随便删除config.bib的保内存(reserve),因为在这里删除换成别的,但是在驱动又
 
    
没有做相应修改的话,那么这个内存就会被不同的驱动使用,撞车了,那么就会出现严重个后果,我上次死活不成功就是这个原因。后来我在
 
    
最后面增加内存给camera,遗憾的是这样可用内存被减小了很多。个人觉得使用动态申请时最合适的,可惜我失败了,不知道为什么三星的
 
    
其他DMA内存也在config.bib预留,如果全部使用动态申请不是更好吗?明白了!有时候只要不使用RAM区域来划分就没有必要了,现在我
 
    
直接在RAM区域画出内存给DMA了。郁闷!
 
    
 

转载于:https://www.cnblogs.com/gooogleman/archive/2010/11/05/1869690.html

你可能感兴趣的:(2440 OV9652摄像头驱动调试)