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的,但是使用了不连续的映射方法,所以不出问题才怪!
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不是会黑屏吗?
引用 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有影响吗?
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
固定程序内存和存储内存比例,一旦使用摄像头,居然死机了。改回来又好了。
这两天不停的尝试,做了很多无用功。
我把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 能够显示图像区域了,但是不知道怎么回事,却不能出现图像,采集到不停闪烁的花纹,请有经验的大哥们指导一下。
引用 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 能够显示图像区域了,但是不知道怎么回事,却不能出现图像,采集到不停闪烁的花纹,请有经验的大哥们指导一下。
引用 34 楼 abo77281 的回复:
lz上面好象差不多了,有数据了,只不过是数据格式和大小可能有问题.
查下你的源图像的大小和编码格式有没有设置错?目标图像的大小有没有设置错。
camera要有dma buffer,你用HalAllocateCommonBuffer来开辟,只要用足够的ram就没有问题。查下你开辟的ram区大小,这个要根据图像的大小和编码格式来确定dma buffer的大小。 不要开辟小了,大了浪费内存,小了造成桢与桢数据重叠,显示模糊或是花屏。
查下你的显示区域…
是这样的。我使用config.bib预留内存的时候是可以显示图像的。难道真的是我计算错误了,初始化的代码在4.2BSP是已经正常使用的。
我算算。
lz上面好象差不多了,有数据了,只不过是数据格式和大小可能有问题.
查下你的源图像的大小和编码格式有没有设置错?目标图像的大小有没有设置错。
camera要有dma buffer,你用HalAllocateCommonBuffer来开辟,只要用足够的ram就没有问题。查下你开辟的ram区大小,这个要根据图像的大小和编码格式来确定dma buffer的大小。 不要开辟小了,大了浪费内存,小了造成桢与桢数据重叠,显示模糊或是花屏。
查下你的显示区域…
是这样的。我使用config.bib预留内存的时候是可以显示图像的。难道真的是我计算错误了,初始化的代码在4.2BSP是已经正常使用的。
我算算。
==========================================================
哈哈哈哈哈哈,搞定了!!!!!!!!!!图像显示正常了。
上面那个异常,刚好是有个东西没有改,造成异常了。
//要把CODE通道DMA地址放到不影响其他部分运行的RAM地址
//#define VIRTUAL_OFFSET 0x7C000000
#define VIRTUAL_OFFSET 0x70000000——这个才行的。
上面那个异常,刚好是有个东西没有改,造成异常了。
//要把CODE通道DMA地址放到不影响其他部分运行的RAM地址
//#define VIRTUAL_OFFSET 0x7C000000
#define VIRTUAL_OFFSET 0x70000000——这个才行的。
为什么是这个偏移地址,呢,因为在config.bib和内存映射文件决定了,4.2BSP和5.0BSP不同,所以这个也要做相应改变,
否则会产生异常的。加上这个虚拟地址偏移地址刚好是uncached 的虚拟地址,可以在wince访问了 。但是,我有点纳闷的是
我使用动态申请DMA的方法却不行,即使我修改了虚拟地址偏移。也没有异常产生,按照道理这应该是可行并且比较有效利用
内存的办法的,实在是可惜了。以后有空再研究吧。
这天是最后一天期限,终于顺利完成任务,不然要扣钱的。谢谢各位了。这几天的郁闷让我学到了好多东西。
这天是最后一天期限,终于顺利完成任务,不然要扣钱的。谢谢各位了。这几天的郁闷让我学到了好多东西。
总结一下2440 OV9650 Camera驱动的流程:初始化接口(并打开电源,我的板子改了,我上次相当郁闷,用别人的驱动没有加入打开电源的动作
结果导致,初始化OV9650一直不成功,我还以为是什么问题,真是很弱智的错误)——》初始化中断,绑定线程——)等待线程中断——》
产生中断——》显示图像,更新图像。
最后,我要提醒的是config.bib的修改注意事项:不能随便删除config.bib的保内存(reserve),因为在这里删除换成别的,但是在驱动又
没有做相应修改的话,那么这个内存就会被不同的驱动使用,撞车了,那么就会出现严重个后果,我上次死活不成功就是这个原因。后来我在
最后面增加内存给camera,遗憾的是这样可用内存被减小了很多。个人觉得使用动态申请时最合适的,可惜我失败了,不知道为什么三星的
其他DMA内存也在config.bib预留,如果全部使用动态申请不是更好吗?明白了!有时候只要不使用RAM区域来划分就没有必要了,现在我
直接在RAM区域画出内存给DMA了。郁闷!