tag 标签: 中星微zc301b摄像头

相关博文
  • 热度 12
    2013-1-14 09:51
    2875 次阅读|
    0 个评论
      硬件环境:友善之臂mini2440开发板+中星微zc301b摄像头 软件环境:linux2.6.29内核+上位机Ubuntu8.04 日    期:2012-12-19 于广州日顺电子科技有限公司 作   者:行者无疆 or 蜗牛   提示:感谢网友的倾情付出,我也是在网友的基础上整理,归类,然后通过实验验证罢了。   关于如何移植驱动,可以在google上搜索, 移植完驱动后,启动开发板,挂载NFS进入系统后,插上USB摄像头,串口出现如下信息: usb 1-1: new full speed USB device using s3c2410-ohci and address 4 usb 1-1: device descriptor read/64, error -62 usb 1-1: device descriptor read/64, error -62 usb 1-1: new full speed USB device using s3c2410-ohci and address 5 usb 1-1: New USB device found, idVendor=0ac8, idProduct=301b usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 1-1: Product: PC Camera usb 1-1: Manufacturer: Vimicro Corp. usb 1-1: configuration #1 chosen from 1 choice gspca: probing 0ac8:301b zc3xx: probe 2wr ov vga 0x0000 zc3xx: probe 3wr vga 1 0xe400 zc3xx: probe 3wr vga 2 0x0000 zc3xx: Sensor UNKNOW_0 force Tas5130 gspca: probe ok           # ./server_arm fastspeed.txt  start 2.0... Device name:PC Camera Width:640 ~ 48 Height:480 ~ 32 Frames:4 Buffer size:475136 Offset:0 encoded:38016, 4228 bytes. encoded:38016, 152 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. gspca: ISOC data error:   len=38, status=-84 encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes. encoded:38016, 12 bytes.     //------------------------------------------------------------------------------------------------------------------- 仔细查看,我们不难发现有两个问题: 其一:zc3xx: Sensor UNKNOW_0 force Tas5130,提示没有找到摄像头感光芯片,强制为Tas5130,其实中星微zc3xx摄像头感光芯片Tas5130CK,ID号为14。有些网友用的不是linux2.6.29内核版本,ID号为16,其实我们可以从内核中找到答案: 摘自 //////////////////////////////////// 从内核zc3xx..c中copy 5, /* SENSOR_CS2102 0 */ 5, /* SENSOR_CS2102K 1 */ 4, /* SENSOR_GC0305 2 */ 4, /* SENSOR_HDCS2020b 3 */ 4, /* SENSOR_HV7131B 4 */ 4, /* SENSOR_HV7131C 5 */ 4, /* SENSOR_ICM105A 6 */ 4, /* SENSOR_MC501CB 7 */ 3, /* SENSOR_OV7620 8 */ 4, /* SENSOR_OV7630C 9 */ 4, /* SENSOR_PAS106 10 */ 4, /* SENSOR_PAS202B 11 */ 4, /* SENSOR_PB0330 12 */ 4, /* SENSOR_PO2030 13 */ 4, /* SENSOR_TAS5130CK 14 */ 4, /* SENSOR_TAS5130CXX 15 */ 3, /* SENSOR_TAS5130C_VF0250 16 */   既然找到问题,那就好办了,使用root权限,输入下列命令 # echo 14  /sys/module/gspca_zc3xx/parameters/force_sensor 或者直接修改/sys/module/gspca_zc3xx/parameters/force_sensor文件,将文件清空然后输入14保存   重新插上你的摄像头就可以用了   当然,如果想一劳永逸呢,就编辑/etc/modprobe.conf加入这行 options gspca_zc3xx force_sensor=16 保存就OK! 但是这个一劳永逸的解决方法在此版本上不能用,没有modprobe.conf这个配置文件。   其二: gspca: ISOC data error:   len=38, status=-84 解决USB摄像头出现ISOC data error的问题gspcav1-20071224/gspca_core.c:   ISOC data e rror:   len=XX, status=-84                 XX代表一些不定的数字   这个问题在我用VIDCAT的时候遇到了,这个主要是USB-host的问题。 下面是解决的办法: 修改drivers/usb/host/ohci-s3c2410.c文件中的s3c2410_start_hc函数,开始部分添加以下内容:     unsigned long s3c2410_upllcon=(unsigned long)ioremap(0x4C000008, 4);   unsigned long upllvalue=(0x3812)|(0x024)|(0x02); while(upllvalue!=__raw_readl(s3c2410_upllcon)){ __raw_writel(upllvalue,s3c2410_upllcon); mdelay(1); } 然后重新编译内核,即可解决。     好了,我们可以开始走上正途了: 重新拔了usb摄像头,再插上,弹出如下信息: # echo 14  /sys/module/gspca_zc3xx/parameters/force_sensor # usb 1-1: USB disconnect, address 3 gspca: disconnect complete usb 1-1: new full speed USB device using s3c2410-ohci and address 4 usb 1-1: New USB device found, idVendor=0ac8, idProduct=301b usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=0 usb 1-1: Product: PC Camera usb 1-1: Manufacturer: Vimicro Corp. usb 1-1: configuration #1 chosen from 1 choice gspca: probing 0ac8:301b zc3xx: probe 2wr ov vga 0x0000 zc3xx: probe 3wr vga 1 0xe400 zc3xx: probe 3wr vga 2 0x0000 zc3xx: sensor forced to 14 gspca: probe ok     激动人心的时刻到了,摄像头终于找到自己的家了,zc3xx: sensor forced to 14   运行我们的单帧采集测试程序,马上在同一目录下抓拍到图片。 # ./v4l  open success! set_norm success init success! size=475136 memory map success! get picture success! img address 0x40001000 #    测试程序源代码如下:   /********************************************************* 中星微摄像头zc301b感光芯片是Tas5130CK,在linux2.6.29版本中, ID号14   # echo 14  /sys/module/gspca_zc3xx/parameters/force_sensor **********************************************************/     #include  #include  #include  #include  #include  #include  #include  #include  #include  //#include "v4l.h"   #include  #include          #define DEFAULT_DEVICE "/dev/video0"         #include  #define norm VIDEO_MODE_NTSC #define DEFAULT_FILE_NAME "picture"      //PAL CIF NTSC tuner mode        #define PAL_WIDTH 768   #define PAL_HEIGHT 576  #define CIF_WIDTH 352  #define CIF_HEIGHT 288  #define NTSC_WIDTH 80   //  #define NTSC_HEIGHT 60  #define DEFAULT_PALETTE VIDEO_PALETTE_RGB32    struct _v4l_device {     int fd;     struct video_capability capability;     struct video_picture picture;     struct video_window window;     struct video_channel channel ;     struct video_mbuf mbuf;     struct video_capture capture;     struct video_buffer vbuffer;     struct video_mmap mmap;     unsigned char *map;     int frame;     int framestat ;  }; typedef struct _v4l_device v4ldevice;     int v4l_open(char *dev,v4ldevice *vd) {     if (!dev){dev = DEFAULT_DEVICE;} ;       if((vd-fd=open(dev,O_RDWR,10705))0)     {         return -1;     };     if(v4l_get_capability(vd)0)         return -1;     if(v4l_get_picture(vd)0)         return -1;     return 0; }   int v4l_get_capability(v4ldevice *vd) {     if(ioctl(vd-fd,VIDIOCGCAP,(vd-capability))0)     {             perror("v4l_get_capability:");         return -1;     };      return 0;   }   int v4l_get_picture(v4ldevice *vd) {     if(ioctl(vd-fd,VIDIOCGPICT,(vd-picture))0)     {         perror("v4l_get_picture");         return -1;             };      return 0;     }       int v4l_set_norm(v4ldevice *vd, int nrm)   {  int i; for(i=0;i vd-capability.channels ; i++){ // vd-channel =nrm ; };   return 0;   }           int v4l_grab_init(v4ldevice *vd,int width,int height) {     vd-mmap.width=width;     vd-mmap.height=height;     vd-mmap.format=vd-picture.palette;                     vd-frame=0;     vd-framestat =0;     vd-framestat =0;         return 0; }   int v4l_mmap_init(v4ldevice *vd) {     if(v4l_get_mbuf(vd)0)         return -1;     if((vd-map=mmap(0,vd-mbuf.size,PROT_READ|PROT_WRITE,MAP_SHARED,vd-fd,0) )0)     {         return -1;     }     return 0; }   int v4l_get_mbuf(v4ldevice *vd) {     if(ioctl(vd-fd,VIDIOCGMBUF,(vd-mbuf))0)     {         perror("v4l_get_mbuf:");             return -1;     }     printf("size=%d\n",vd-mbuf.size); return 0; }    int v4l_grab_start(v4ldevice *vd,int frame) {     vd-mmap.frame=frame;     if(ioctl(vd-fd,VIDIOCMCAPTURE,(vd-mmap))0)     {         exit(-1);         return -1;     }     vd-framestat =1;     return 0; } int v4l_grab_sync(v4ldevice *vd,int frame) {     if(ioctl(vd-fd,VIDIOCSYNC,frame)0)     {         return -1;         }     vd-framestat =0;     return 0; }   unsigned char * v4l_get_address(v4ldevice *vd) {   return (vd-map+vd-mbuf.offsets ); //   return (vd-map+vd-mbuf.offsets ); }   int v4l_close(v4ldevice *vd) {     close(vd-fd);     return 0; }   /*************************************************************/   /******************main.c************************/   /*name :main.c     date:2009-5-20     author:kevin     copyright:all is reserved   ************************************/   char *buffer=NULL;   int main() {         v4ldevice VD;     v4ldevice *vd=VD;       int frame=0;     int f_d;            int NUM, write_number = 0;       f_d=open(DEFAULT_FILE_NAME,O_RDWR|O_CREAT,0666);         printf("f_d = %d \n",f_d);               if(0==v4l_open("/dev/video0",vd))          printf("open success!\n");     else          printf("open failure\n");       if(0==v4l_set_norm(vd,norm))         printf("set_norm success\n");     else         printf("set_norm failure\n");     if(0==v4l_grab_init(vd,NTSC_WIDTH,NTSC_HEIGHT))           printf("init success!\n");     else         printf("init failure\n");     if(0==v4l_mmap_init(vd))         printf("memory map success!\n");     else         printf("memory map failure\n");     if(0==v4l_grab_start(vd,frame))         printf("get picture success!\n");     else         printf("get picture failure\n");            v4l_grab_sync(vd,frame);                buffer=(char *)v4l_get_address(vd);     printf("img address %p\n",buffer);                write_number = write(f_d,buffer,NTSC_WIDTH*3*NTSC_HEIGHT); //每一帧的字节数 80*60*3=14400byte          printf("write_number = %d bytes\n",write_number);            v4l_close(vd);     return 0;      }   Copy这段代码,注意查看驱动文件,在mini2440运行即可。