⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ccmcp.c

📁 linux平台上的开放源代码的网络摄像机程序.实现视频捕捉,传输以及云台控制等.非常具有参考价值.
💻 C
字号:
/*!****************************************************************************! 05.03.2002 splitted huge cmoscam.c*! FILE NAME  : ccmcp.c*!*! DESCRIPTION: TBD*//****************** INCLUDE FILES SECTION ***********************************/#include <linux/module.h>#include <linux/sched.h>#include <linux/slab.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/string.h>#include <linux/init.h>#include <linux/config.h>#include <asm/system.h>#include <asm/svinto.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/delay.h>#include <asm/uaccess.h>#include <asm/cmoscama.h>#include "cc303.h"#include "cci2c.h"#include "ccmcp.h"#define D(x)// MCP static datastatic int	MCP_shadow[MCP_W_size];static int	MCP_addr;static int	MCP_exists;	// 0- no MCP board, 1 - MCP board present, 2 - positioner presentvoid	MCP_reset(int resetOn);int	MCP_init(void);void	MCPSendDibit(int dibit);int	MCPSendGetDibit(int dibit);int MCPSendA (int wnr, int a);void MCPWriteD (int d);int MCPReadD (void);int MCPWriteSyncTab(void);int MCPDemoSequencer(void);int MCPpresent(void) {return MCP_exists;}int positionerPresent(void) {return (MCP_exists==2);}/************************************** MCP functions *******************************************//*Will assume 16-bit words, first MCP_W_size (1024) mapped to MCP write space (with shadow), next MCP_R_size (256) - to MCP read address space*//*#define	MCP_W_size	1024#define	MCP_R_size	256#define	MCPOtherBits	0xffa7a7ff#define MCPReset	0x00000800#define MCPNoReset	0x00105800#define MCPToggleA	0x00080000#define MCPToggleB	0x00001000#define MCPctlseq	0x00#define MCPsofttg	0x02#define MCPeackn	0x03#define MCPctlgate	0x04#define MCPwstdly	0x06#define MCPwrsmsk	0x07#define MCPwrsup	0x08#define MCPwrmons	0x09#define MCPwnom		0x0a#define MCPwdenom	0x0b#define MCPwoutw	0x0c#define MCPwinvctl	0x0d#define MCPctlsync	0x0e#define MCPwrdlys	0x10#define MCPwinv		0x40#define MCPwshared	0x80#define MCPwrsynctb	0x100#define MCPwrseq	0x200static int MCP_shadow[MCP_W_size];static int	MCP_addr;*//* ----------------- low level MCP control routines ------------------ */int	MCP_initmodule(void) {	//- once, with loading linux  int i;// Init unused shadow data as negative  for (i=0;i<MCP_W_size;i++) MCP_shadow[i]= -1;  MCP_reset(1);	// to be sure  MCP_reset(0);	// reset off// check that "in control" but no "request"  MCP_exists=0;//  i=MCPSendA(0,0);//D(printk("MCPSendA returned %x\r\n",i));//  if ((i & 3)!=1) {//	D(printk("Should return -1!! %x\r\n",i));//	return -1;	// (not in control) or "request" - no MCP board present//	}  if ((MCPSendA(0,0) & 3)!=1) return -1;	// (not in control) or "request" - no MCP board present// modified to include positioner board (MCP_exists==2)//  MCP_exists=1;  MCPSendA(0,0x80);	//  MCP_exists=((MCPReadD()>>9)&&7)+1;//  MCP - 1, positioner - 2  if (MCPpresent()) {    MCPWriteSyncTab();		// write 256x4 sync table    MCPDemoSequencer();		// program some demo/reasonable sequencer parameters  }  return 0;}void	MCP_reset(int resetOn) {	if (resetOn) ccamCRAndOr (MCPOtherBits,MCPReset);  	else         ccamCRAndOr (MCPOtherBits,MCPNoReset);}int	MCP_init(void) {// make sure external reset is off  if ((ccamGetCR() & CCAM_MASK(XRST)) == 0) {MCP_reset(1); MCP_reset(0); return 1;} // reset was on  return 0;}void	MCPSendDibit(int dibit) {	// 0- "start", 1 - "0", 2 - "1", 3 - "act"  if (dibit & 2) ccamCRXor (MCPToggleB);  else		 ccamCRXor (MCPToggleA);//  ccamCRXor (0); // delay needed? - it did work before  if (dibit & 1) ccamCRXor (MCPToggleB);  else		 ccamCRXor (MCPToggleA);}int	MCPSendGetDibit(int dibit) {	// 0- "start", 1 - "0", 2 - "1", 3 - "act" - returns dibit read    int  d;//  int i;//  int ii;  d = (port_csp0_addr[1] >>2) & 1;   if (dibit & 2) ccamCRXor (MCPToggleB);  else		 ccamCRXor (MCPToggleA);  ccamCRXor (0); // delay needed 1 was enough, - maybe with extra restore_flags() - now not needed anymore  d |= (port_csp0_addr[1] >>1) & 2;  if (dibit & 1) ccamCRXor (MCPToggleB);  else		 ccamCRXor (MCPToggleA);//  printk("%d",d);  return d;}int MCPSendA (int wnr, int a) {	// wnr 0 - read, 1 - write  int	wr,d;  wr=MCP_init();	// 1 - "reset was active"  MCP_addr=a;  MCPSendDibit(0);	// start  d=MCPSendGetDibit((wnr & 1)+1);	// "0" - read, "1" - write  if (wr) d |=4;	// mark that was reset;// later - check "in control" here...  do { // at least one 0/1 should be sent     MCPSendDibit((a & 1)+1);     a = (a >> 1);//     printf ("a= %x\r\n",a);  } while (a);  if (wnr) MCPSendDibit(3);	// act  return d;}void MCPWriteD (int d) {  if ((MCP_addr >= 0) && (MCP_addr < MCP_W_size) ) {    MCP_shadow[MCP_addr++]=d;    while (d) {     MCPSendDibit((d & 1)+1);     d = (d >> 1);    }    MCPSendDibit(3);	// act  }}int MCPReadD (void) { // will always read 12 bit data  int d;  MCPSendDibit(3);	// act  d  = MCPSendGetDibit(1); // while sending 0  d |= MCPSendGetDibit(1) <<  2;   d |= MCPSendGetDibit(1) <<  4;   d |= MCPSendGetDibit(1) <<  6;   d |= MCPSendGetDibit(1) <<  8;   d |= MCPSendGetDibit(1) << 10;   return d;}int MCPWriteSyncTab(void) { // write 256x4 sync table  int	i,d;  if ((MCPSendA(1,MCPwrsynctb)&& 1)==0) return -1;	// (not in control) synctab  for (i=0;i<256;i++) {    d=-1;    if      ((i & 0xff) == 0xff) d = 0x0;    else if ((i & 0xff) == 0x00) d = 0x8;    else if ((i & 0x03) == 0x02) d = 0x1;    else if ((i & 0x03) == 0x01) d = 0x9;    else if ((i & 0x07) == 0x04) d = 0x2;    else if ((i & 0x07) == 0x03) d = 0xa;    else if ((i & 0x0f) == 0x08) d = 0x3;    else if ((i & 0x0f) == 0x07) d = 0xb;    else if ((i & 0x1f) == 0x10) d = 0x4;    else if ((i & 0x1f) == 0x0f) d = 0xc;    else if ((i & 0x3f) == 0x20) d = 0x5;    else if ((i & 0x3f) == 0x1f) d = 0xd;    else if ((i & 0x7f) == 0x40) d = 0x6;    else if ((i & 0x7f) == 0x3f) d = 0xe;    else if ((i & 0xff) == 0x80) d = 0x7;    else if ((i & 0xff) == 0x7f) d = 0xf;    MCPWriteD (d);  }  return 0;}int MCPDemoSequencer(void) { // program some demo/reasonable sequencer parameters/* 2-pulse sequence:    1-st pulse - delay 0, duration 10    2-nd pulse - delay 1000, duration 10000   if ((MCPSendA(1,MCPwrseq)&& 1)==0) return -1;	// (not in control) sequencer table    MCPWriteD (  0x09);		// first word - ON-OFF-NOP-NOP    MCPWriteD (0x0018);		// delay after first word (in 40-ns steps) up to 15 bits+ "extend" bit =16bits    MCPWriteD (  0x04);		// second word - NOP-ON-NOP-NOP    MCPWriteD (0x00f9);		// delay after second word    MCPWriteD (  0x38);		// third word - NOP-OFF-END-NOP*//* 1-pulse sequence:    1-st pulse - delay 0, duration 100,000ns*/   if ((MCPSendA(1,MCPwrseq)&& 1)==0) return -1;	// (not in control) sequencer table    MCPWriteD (  0x01);		// first word - ON-NOP-NOP-NOP    MCPWriteD (0x09c3);		// delay after first word (in 40-ns steps) up to 15 bits+ "extend" bit =16bits    MCPWriteD (  0x0e);		// second word - OFF-END-NOP-NOP    MCPWriteD (0x0000);		// delay after second word// program sync delay mask (to prevent "glitches" - needs adjustment?    MCPSendA(1,MCPwrsmsk);	//    MCPWriteD (  0x2);		// 4-step 0..3// write "on" support period    MCPSendA(1,MCPwrsup);	//    MCPWriteD (  0x1);		// 4-step 0..3// set all minimal delays - updated    MCPSendA(1,MCPwrdlys);	//    MCPWriteD (  0x0);    MCPWriteD (  0x3);    MCPWriteD (  0x0);    MCPWriteD (  0x0);    MCPWriteD (  0x0);    MCPWriteD (  0x3);    MCPWriteD (  0x0);    MCPWriteD (  0x0);// Enable outputs to transistors    MCPSendA(1,MCPctlgate+1);    MCPWriteD (  0x0);// program inverter    MCPSendA(1,MCPwinv);	//    MCPWriteD (  0x1800);	// wait 200usec - make it 300 to reduce voltage    MCPWriteD (  0x4043);	// 1-st transistor on for 3.4usec    MCPWriteD (  0x8043);	// 2-nd transistor on for 3.4usec//    MCPWriteD (  0x4043);	// 1-st transistor on for 3.4usec//    MCPWriteD (  0x8043);	// 2-nd transistor on for 3.4usec    MCPWriteD (  0xc000);	// restart sequence// turn it on//    MCPSendA(1,MCPwinvctl);	////    MCPWriteD ( 4);		// always on (to resetting after trigger)// program PWM    MCPSendA  (1,MCPwnom);	//    MCPWriteD (  0x2000);	// MCPwnom (0.4..0.7)under thershold    MCPWriteD (  0xe000);	// MCPwdenom 8000/c000/e000/f000/f8000    MCPWriteD (  0x00f0);	// MCPwoutw// that's all for now...// put something in shared...    MCPSendA(1,MCPwshared);    MCPWriteD (  0x01);    MCPWriteD (  0x02);    MCPWriteD (  0x04);    MCPWriteD (  0x08);    MCPWriteD (  0x10);    MCPWriteD (  0x20);    MCPWriteD (  0x40);    MCPWriteD (  0x80);    MCPWriteD (  0x100);	D(printk("Default data to MCP written\r\n"));  	return 0;	}/* --------- MCP I/O functions ---------------------*/int MCP_open(struct inode *inode, struct file *filp) { // set filesize//	int p = MINOR(inode->i_rdev);	if (!MCPpresent())  return -ENXIO;	// no MCP board detected during Linux startup// enable if not in use or is reset	inode->i_size=   (MCP_W_size + MCP_R_size) << 1;	return 0;}ssize_t MCP_read(struct file * file, char * buf, size_t count, loff_t *off) {  unsigned long p,left;  unsigned long bp=0;//  unsigned short buf16[MCP_W_size + MCP_R_size];  unsigned short buf16[MCP_W_size + MCP_R_size +1]; //not fixed yet?// printk("MCP_read: buf address=%x count=%x\r\n",(long) buf, (long) count);  p = (file->f_pos) >> 1;  count=count >> 1;// printk ("p= %x\r\n",p);// printk ("Just return and do nothing more\r\n");// return count<<1;  if(p >= (MCP_W_size + MCP_R_size)) return -EFAULT;  if( (p + count) > (MCP_W_size + MCP_R_size)) { /* truncate count */    count = (MCP_W_size + MCP_R_size) - p;  }  left=count;/* is it reading some shadow data? */// printk ("p=%x, left=%x, bp=%x, sizeof(buf16)=%lx\r\n",p, left, bp, sizeof(buf16));// return count<<1;  while ((p<MCP_W_size) && left--)   buf16[bp++]=(unsigned short) (MCP_shadow[p++]);//  printk ("buf16[0]= %x buf16[1]= %x\r\n",buf16[0],buf16[1]);// return count<<1;/* is it reading some real data? */  if (++left) {  if ((MCPSendA(0, p - MCP_W_size) && 1)==0) return -EIO;	// Set start address (read), check "in control"    while (left--) buf16[bp++] =  MCPReadD ();  }//  printk ("buf16[0]= %x buf16[1]= %x\r\n",buf16[0],buf16[1]);  count=count<<1;  if ((p=copy_to_user(buf,buf16,count))) return -EFAULT;  file->f_pos += count;// printk("MCP_read returned %x\r\n", count);  return count;}ssize_t MCP_write(struct file * file, const char * buf, size_t count, loff_t *off) {  unsigned long p,left;  unsigned long bp=0;  unsigned short buf16[MCP_W_size];// printk("MCP_write: buf address=%x count=%x\r\n",(long) buf, (long) count);  p = (file->f_pos) >> 1;  count=count>>1;// printk ("p= %x\r\n",p);// printk ("buf[0]= %x buf[1]= %x buf[2]= %x buf[3]= %x\r\n",buf[0],buf[1],buf[2],buf[3]);  if(p >= MCP_W_size) return -EFAULT;  if( (p + count) > MCP_W_size ) { /* truncate count */    count = MCP_W_size - p;  }  left=count;  if (copy_from_user(buf16,buf,count<<1)) return -EFAULT;// printk ("buf16[0]= %x buf16[1]= %x\r\n",buf16[0],buf16[1]);  if ((MCPSendA(1, p) && 1)==0) return -EFAULT;	// Set start address (write), check "in control"  while (left--)  MCPWriteD (buf16[bp++]);  count=count<<1;  file->f_pos += count;// printk ("MCP_write returned %x\r\n", count);// printk ("New file->f_pos = %lx\r\n",file->f_pos);  return count;}loff_t MCP_lseek(struct file * file, loff_t offset, int orig){/* *  orig 0: position from begning of data *  orig 1: relative from current position *  orig 2: position from last data */  unsigned long fs;  fs=(MCP_W_size + MCP_R_size) << 1;// printk("MCP_lseek - fs= %x\r\n", fs);    switch (orig)  {   case 0:     file->f_pos = offset;     break;   case 1:     file->f_pos += offset;     break;   case 2:     file->f_pos = fs - offset;     break;   default:     return -EINVAL;  }  /* truncate position */  if (file->f_pos < 0) {    file->f_pos = 0;        return(-EOVERFLOW);  }    if (file->f_pos >= fs) {    file->f_pos = fs - 1;    return(-EOVERFLOW);  }// printk("MCP_lseek returned %x\r\n", (int) file->f_pos);  return ( file->f_pos );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -