📄 cc303.c
字号:
case IO_CCAM_EXPOSE : i1=arg; printk ("i1= %x\r\n",i1); if (i1>100000) i1=100000; // 1 sec for (;i1>0;i1--) udelay (10); printk ("ccam_cr_shadow= %lx\r\n",ccam_cr_shadow); case IO_CCAM_EXPOS_END : // should continue to dma start CCAM_ARO_ON ; { RESET_DMA( 5 ); WAIT_DMA( 5 ); *R_DMA_CH5_FIRST = virt_to_phys (&ccam_dma_descr[0]); *R_DMA_CH5_CMD = IO_STATE(R_DMA_CH5_CMD, cmd, start); EXT_DMA_0_START ; FPGA_DMA_START ;// wait for VACT high while (CCAM_SR(VACT) == 0) ; // just wait// wait for VACT low - may sleep? while (CCAM_SR(VACT) != 0) ; // just wait -fancy later return 0; } } switch(CCAM_CTRL(cmd)){// read (abstract) sensor parameters 0..63 case CCAM_RPARS:{ return imageParamsR[CCAM_ADDR(cmd)]; }// write (abstract) sensor parameters 0..63 (if [P_UPDATE] is off)// trigger update if necessary case CCAM_WPARS: { if (CCAM_ADDR(cmd) == P_UPDATE) { if (imageParamsR[P_UPDATE] == 3) return -EINVAL ; // too late to abort... TODO: support waiting, change error code save_flags(flags); cli(); imageParamsW[P_UPDATE]= (arg>2)? 2: arg; if (imageParamsW[P_UPDATE]) imageParamsR[P_UPDATE]=2; // waiting to be updated else imageParamsR[P_UPDATE]=0; // will not be updated restore_flags(flags); if (imageParamsW[P_UPDATE]==1) return programSensor(); // update at once return 0; } else { if (imageParamsR[P_UPDATE]>1) return -EINVAL ; // no write permitted if update is schedulled. TODO: Change error code imageParamsR[P_PARS_CHANGED] |= (imageParamsW[CCAM_ADDR(cmd)]!=arg); imageParamsW[CCAM_ADDR(cmd)]=arg; return 0; } }/* unsigned long flags; save_flags(flags); cli(); port_csp0_addr[CCAM_WA_WCTL]= (ccam_cr_shadow &= d); restore_flags(flags);*/ default:return -EINVAL ; }}static int cmoscam_open_raw(struct inode *inode, struct file *filp) { // set filesize loff_t fs; unsigned long l; fs=((imageParamsR[P_ACTUAL_WIDTH] * imageParamsR[P_ACTUAL_HEIGHT]) << 1); l=(inode->i_size); D1(printk("cmoscam_open_raw: fs=%lx, inode->i_size=%lx\r\n",fs,l)); inode->i_size=fs;// inode->i_mtime=0x7ffffff; l=(inode->i_size); D1(printk("cmoscam_open_raw2: fs=%lx, inode->i_size=%lx\r\n",fs,l)); return 0;}static int cmoscam_open_dma(struct inode *inode, struct file *filp) { // set filesize D1(printk("cmoscam_open_dma: fs=%lx\r\n",imageParamsR[P_IMAGE_SIZE])); inode->i_size=imageParamsR[P_IMAGE_SIZE];// inode->i_atime=0x7ffffff;// inode->i_mtime=0x7ffffff;// inode->i_ctime=0x7ffffff; return 0;}static int cmoscam_mmap_dma (struct file *filp, struct vm_area_struct *vma) { int rslt; D1(printk("vm_start=%lx\r\n",vma->vm_start)); D1(printk("vm_end=%lx\r\n",vma->vm_end)); D1(printk("vm_pgoff=%lx\r\n",vma->vm_pgoff)); D1(printk("vm_file=%lx\r\n",(unsigned long) (vma->vm_file))); D1(printk("ccam_dma_buf=%lx\r\n",(unsigned long) (virt_to_phys (&ccam_dma_buf[0])))); rslt=remap_page_range(vma->vm_start, virt_to_phys (&ccam_dma_buf[0]) , vma->vm_end-vma->vm_start, vma->vm_page_prot); D1(printk("remap_page_range returned=%x\r\n",rslt)); return rslt;}/* ======================================== Top level file operations =================================================================== */static int cmoscam_open(struct inode *inode, struct file *filp) { int p,res; p = MINOR(inode->i_rdev); D1(printk("cmoscam_open: minor=%x\r\n",p) ); D1(printk("filp=%lx\r\n",(unsigned long)filp) ); switch ( p ) { case CMOSCAM_MINOR_IORW : case CMOSCAM_MINOR_I2C : { if (minors[p]) return -EACCES; // maybe different number - channel in use break; } case CMOSCAM_MINOR_RAW : { if ((res =cmoscam_open_raw(inode, filp))) return res; break; } case CMOSCAM_MINOR_DMA : { if ((res =cmoscam_open_dma(inode, filp))) return res; break; } case CMOSCAM_MINOR_MCP : { if ((minors[p]) && ((ccam_cr_shadow & CCAM_MASK(XRST)) != 0)) return -EACCES; if ((res =MCP_open(inode, filp))) return res; break; } default: return -EINVAL; } minors[p]=p; filp->private_data = &minors[p]; return 0;}static int cmoscam_release(struct inode *inode, struct file *filp) { int p = MINOR(inode->i_rdev); switch ( p ) { case CMOSCAM_MINOR_IORW : case CMOSCAM_MINOR_I2C : case CMOSCAM_MINOR_MCP : { minors[p]=0; break; } case CMOSCAM_MINOR_RAW : case CMOSCAM_MINOR_DMA : { break; } default: return -EINVAL; } D(printk("cmoscam_release: done\r\n")); return 0;}static int cmoscam_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) { // switch by minor int rv;// unsigned long flags; D(printk("cmoscam_ioctl cmd= %x, arg= %x\n\r",cmd,arg)); D(printk("cmoscam_ioctl: ((int *)filp->private_data)[0]= %x\n\r",((int *)filp->private_data)[0])); switch (((int *)filp->private_data)[0]) { case CMOSCAM_MINOR_IORW : return csp0rw_ioctl (inode, filp, cmd, arg); case CMOSCAM_MINOR_I2C : return i2c_ioctl (inode, filp, cmd, arg);// case CMOSCAM_MINOR_DMA : return ccam_DMA_ioctl(inode, filp, cmd, arg); case CMOSCAM_MINOR_DMA : {// save_flags(flags);// cli(); rv= ccam_DMA_ioctl(inode, filp, cmd, arg);// restore_flags(flags); return rv; } default:return -EINVAL; }}static loff_t cmoscam_lseek(struct file * file, loff_t offset, int orig) { switch (((int *)file->private_data)[0]) { case CMOSCAM_MINOR_RAW : return cmoscam_raw_lseek (file, offset, orig); case CMOSCAM_MINOR_MCP : return MCP_lseek (file, offset, orig); default: return -EINVAL; }}static ssize_t cmoscam_read(struct file * file, char * buf, size_t count, loff_t *off) {// printk("cmoscam_read: ((int *)file->private_data)[0]= %x\r\n",((int *)file->private_data)[0]); switch (((int *)file->private_data)[0]) { case CMOSCAM_MINOR_RAW : return cmoscam_raw_read (file, buf, count, off); case CMOSCAM_MINOR_MCP : return MCP_read (file, buf, count, off); default: return -EINVAL; }}static ssize_t cmoscam_write(struct file * file, const char * buf, size_t count, loff_t *off) {// printk("cmoscam_write: ((int *)file->private_data)[0]= %x\r\n",((int *)file->private_data)[0]); switch (((int *)file->private_data)[0]) { case CMOSCAM_MINOR_MCP : return MCP_write (file, buf, count, off); default: return -EINVAL; }}static int cmoscam_mmap (struct file *filp, struct vm_area_struct *vma) { int p=((int *)filp->private_data)[0]; // int p = MINOR(inode->i_rdev); D1(printk("cmoscam_mmap, minor=%x\r\n",p)); D1(printk("filp=%lx\r\n",(unsigned long)filp)); D1(printk("vm_start=%lx\r\n",vma->vm_start)); D1(printk("vm_end=%lx\r\n",vma->vm_end)); D1(printk("vm_pgoff=%lx\r\n",vma->vm_pgoff)); D1(printk("vm_file=%lx\r\n",(unsigned long) (vma->vm_file))); switch ( p ) { case CMOSCAM_MINOR_IORW : case CMOSCAM_MINOR_I2C : case CMOSCAM_MINOR_RAW : return -EINVAL; case CMOSCAM_MINOR_DMA :// return cmoscam_mmap_dma (inode, filp, vma); return cmoscam_mmap_dma (filp, vma); default: return -EINVAL; } return 0;}static ssize_t cmoscam_raw_read(struct file * file, char * buf, size_t count, loff_t *off) { switch (imageParamsR[P_BITS]) { case 10: return cmoscam_raw_read10(file, buf, count, off); case 8: return cmoscam_raw_read8 (file, buf, count, off); case 4: return cmoscam_raw_read4 (file, buf, count, off); default: return -EINVAL; }}static ssize_t cmoscam_raw_read10(struct file * file, char * buf, size_t count, loff_t *off) { unsigned long i, left, x,y,xl,xb,dp,bp,w2; unsigned long p,d,fs;// printk("cmoscam_raw_read: buf address=%x count=%x\r\n",(long) buf, (long) count); fs=((imageParamsR[P_ACTUAL_WIDTH]*imageParamsR[P_ACTUAL_HEIGHT]) << 1); w2= imageParamsR[P_ACTUAL_WIDTH] << 1; // twice number of pixels/line p = file->f_pos;// printk ("p= %x imageParamsR[P_IMAGE_SIZE]=%x file size=%x\r\n",p,imageParamsR[P_IMAGE_SIZE],fs); if(p >= fs) return -EFAULT; if( (p + count) > fs) { /* truncate count */ count = fs - p; }/*actual read goes here *//* first aproach - simple, but very slow */ y= p / w2 ; // 2 bytes/pixel x= p - y * w2; xl = x / 6 ; xb = x - xl*6; dp= y*imageParamsR[P_LPR]+xl; bp=0; left=count;/* align to the source 32(30)-bit word */ d=ccam_dma_buf[dp]; while ((left > 0) && (xb != 0) && (x < w2)) { switch (xb++) { case 1: {buf[bp++]= (d >> 8 ) & 0x03; break;} case 2: {buf[bp++]= (d >> 10 ) & 0xff; break;} case 3: {buf[bp++]= (d >> 18 ) & 0x03; break;} case 4: {buf[bp++]= (d >> 20 ) & 0xff; break;} case 5: {buf[bp++]= (d >> 28 ) & 0x03; xb=0; dp++; break;} } x++; left--; } while (left >0) {/* advance to next line if needed */ if ( x>=w2) { if (xb) {dp++; xb=0;} // 32-bit align with the start of the next line y++; x=0; }/* calculate number of full triplets in the current line to output *//* xb should be 0 here */ i=w2-x; if (i>left) i=left; i=i/6; x+=(i*6); left-=(i*6); for (;i > 0;i--) { d=ccam_dma_buf[dp++]; buf[bp++]= (d ) & 0xff; buf[bp++]= (d >> 8 ) & 0x03; buf[bp++]= (d >> 10 ) & 0xff; buf[bp++]= (d >> 18 ) & 0x03; buf[bp++]= (d >> 20 ) & 0xff; buf[bp++]= (d >> 28 ) & 0x03; }/* finish line / buf - less than 6 bytes */ d=ccam_dma_buf[dp]; while ((left > 0) && (x<w2)) { switch (xb++) { case 0: {buf[bp++]= (d ) & 0xff; break;} case 1: {buf[bp++]= (d >> 8 ) & 0x03; break;} case 2: {buf[bp++]= (d >> 10 ) & 0xff; break;} case 3: {buf[bp++]= (d >> 18 ) & 0x03; break;} case 4: {buf[bp++]= (d >> 20 ) & 0xff; break;} case 5: {buf[bp++]= (d >> 28 ) & 0x03; xb=0; dp++; break;} } x++; left--; } } file->f_pos += count;// printk("cmoscam_raw_read returned %x\r\n", count); return count;}static ssize_t cmoscam_raw_read8(struct file * file, char * buf, size_t count, loff_t *off) { unsigned long p,bp,dp,fs,x,l,n; char * bccam_dma_buf= (char *) ccam_dma_buf;//imageParamsR[P_LPR]// printk("cmoscam_raw_read: buf address=%x count=%x\r\n",(long) buf, (long) count); fs=(imageParamsR[P_ACTUAL_WIDTH]*imageParamsR[P_ACTUAL_HEIGHT]); p = file->f_pos;// printk ("p= %x imageParamsR[P_IMAGE_SIZE]=%x file size=%x\r\n",p,imageParamsR[P_IMAGE_SIZE],fs); if(p >= fs) return -EFAULT; if( (p + count) > fs) { /* truncate count */ count = fs - p; }// line length may be not aligned to 32-bit words l=imageParamsR[P_LPR]<<2; n=p/imageParamsR[P_ACTUAL_WIDTH]; x=p-n*imageParamsR[P_ACTUAL_WIDTH]; dp=n*l+x; //copy first line n=imageParamsR[P_ACTUAL_WIDTH]-x; if (n>count) n=count; bp=0; while (bp<count) { for (;dp<n;bp++) buf[bp]=bccam_dma_buf[dp++]; dp+=(l-imageParamsR[P_ACTUAL_WIDTH]); n=imageParamsR[P_ACTUAL_WIDTH]; if (n>(count-bp)) n=count-bp; } file->f_pos += count;// printk("cmoscam_raw_read returned %x\r\n", count);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -