Commit c96d81bb authored by Mikhail Karpenko's avatar Mikhail Karpenko
Browse files

WIP: imgsrv stops at reading frame params

parent 99dc26ff
Loading
Loading
Loading
Loading
+59 −69
Original line number Original line Diff line number Diff line
@@ -31,9 +31,9 @@
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/fs.h>
#include <linux/string.h>
//#include <linux/string.h>
#include <linux/init.h>
#include <linux/init.h>
#include <linux/time.h>
//#include <linux/time.h>
#include <linux/wait.h>
#include <linux/wait.h>
#include <linux/dma-mapping.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/platform_device.h>
@@ -43,7 +43,7 @@
//#include <asm/system.h>
//#include <asm/system.h>
//#include <asm/arch/memmap.h>
//#include <asm/arch/memmap.h>
//#include <asm/svinto.h> obsolete
//#include <asm/svinto.h> obsolete
#include <asm/io.h>
//#include <asm/io.h>


/*#include <asm/arch/dma.h>
/*#include <asm/arch/dma.h>
#include <asm/arch/hwregs/dma_defs.h>
#include <asm/arch/hwregs/dma_defs.h>
@@ -52,11 +52,11 @@
#include <asm/arch/hwregs/bif_dma_defs.h>
#include <asm/arch/hwregs/bif_dma_defs.h>
*/
*/


#include <asm/irq.h>
//#include <asm/irq.h>
#include <asm/atomic.h>
//#include <asm/atomic.h>




#include <asm/delay.h>
//#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <elphel/driver_numbers.h>
#include <elphel/driver_numbers.h>
#include <elphel/c313a.h>
#include <elphel/c313a.h>
@@ -71,11 +71,6 @@
#include "x393_macro.h"
#include "x393_macro.h"
#include "x393.h"
#include "x393.h"


//#define MD10(x) printk("%s:%d:",__FILE__,__LINE__);x
#define MD10(x)
//#define MD11(x) printk("%s:%d:",__FILE__,__LINE__);x
#define MD11(x)

struct circbuf_priv_t circbuf_priv[IMAGE_CHN_NUM];
struct circbuf_priv_t circbuf_priv[IMAGE_CHN_NUM];
struct circbuf_priv_t *circbuf_priv_ptr = circbuf_priv;
struct circbuf_priv_t *circbuf_priv_ptr = circbuf_priv;


@@ -117,7 +112,8 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev)
	ccam_dma_buf = ccam_dma_buf_ptr;
	ccam_dma_buf = ccam_dma_buf_ptr;


	// set circbuf size in bytes
	// set circbuf size in bytes
	set_globalParam(G_CIRCBUFSIZE, pElphel_buf->size * PAGE_SIZE);
	//set_globalParam(G_CIRCBUFSIZE, pElphel_buf->size * PAGE_SIZE);
	set_globalParam(G_CIRCBUFSIZE, CCAM_DMA_SIZE);


	for (i = 0; i < IMAGE_CHN_NUM; i++) {
	for (i = 0; i < IMAGE_CHN_NUM; i++) {
		circbuf_priv[i].buf_ptr = ccam_dma_buf_ptr + BYTE2DW(CIRCBUF_START_OFFSET + i * CCAM_DMA_SIZE);
		circbuf_priv[i].buf_ptr = ccam_dma_buf_ptr + BYTE2DW(CIRCBUF_START_OFFSET + i * CCAM_DMA_SIZE);
@@ -185,7 +181,7 @@ int circbuf_all_open(struct inode *inode, struct file *filp)
int circbuf_all_release(struct inode *inode, struct file *filp) {
int circbuf_all_release(struct inode *inode, struct file *filp) {
  int res=0;
  int res=0;
  int p = MINOR(inode->i_rdev);
  int p = MINOR(inode->i_rdev);
 MD10(printk("circbuf_all_release, minor=0x%x\n",p));
 dev_dbg(g_dev_ptr, "minor = 0x%x\n", p);
  switch ( p ) {
  switch ( p ) {
    case  CMOSCAM_MINOR_CIRCBUF :
    case  CMOSCAM_MINOR_CIRCBUF :
//        res=circbuf_release(inode,filp);
//        res=circbuf_release(inode,filp);
@@ -232,7 +228,7 @@ loff_t circbuf_all_lseek(struct file * file, loff_t offset, int orig)
ssize_t circbuf_all_read(struct file * file, char * buf, size_t count, loff_t *off) {
ssize_t circbuf_all_read(struct file * file, char * buf, size_t count, loff_t *off) {
     struct circbuf_pd * privData;
     struct circbuf_pd * privData;
     privData = (struct circbuf_pd *) file->private_data;
     privData = (struct circbuf_pd *) file->private_data;
 MD10(printk("circbuf_all_read, minor=0x%x\n",privData-> minor));
 dev_dbg(g_dev_ptr, "minor = 0x%x\n", privData->minor);
     switch (privData->minor) {
     switch (privData->minor) {
       case CMOSCAM_MINOR_CIRCBUF :      return  circbuf_read   (file, buf, count, off);
       case CMOSCAM_MINOR_CIRCBUF :      return  circbuf_read   (file, buf, count, off);
       case CMOSCAM_MINOR_JPEAGHEAD :    return  jpeghead_read  (file, buf, count, off);
       case CMOSCAM_MINOR_JPEAGHEAD :    return  jpeghead_read  (file, buf, count, off);
@@ -243,7 +239,7 @@ ssize_t circbuf_all_read(struct file * file, char * buf, size_t count, loff_t *o
ssize_t circbuf_all_write(struct file * file, const char * buf, size_t count, loff_t *off) {
ssize_t circbuf_all_write(struct file * file, const char * buf, size_t count, loff_t *off) {
     struct circbuf_pd * privData;
     struct circbuf_pd * privData;
     privData = (struct circbuf_pd *) file->private_data;
     privData = (struct circbuf_pd *) file->private_data;
 MD10(printk("circbuf_all_write, minor=0x%x, count=%d, off=%d\n",privData-> minor, (int) count,(int)*off));
 dev_dbg(g_dev_ptr, "minor = 0x%x, count = %d, off = %d\n", privData->minor, (int)count, (int)*off);
     switch (privData->minor) {
     switch (privData->minor) {
       case CMOSCAM_MINOR_CIRCBUF :       return  circbuf_write  (file, buf, count, off);
       case CMOSCAM_MINOR_CIRCBUF :       return  circbuf_write  (file, buf, count, off);
//       case CMOSCAM_MINOR_JPEAGHEAD :     return  jpeghead_write (file, buf, count, off); // same as other - write header
//       case CMOSCAM_MINOR_JPEAGHEAD :     return  jpeghead_write (file, buf, count, off); // same as other - write header
@@ -256,7 +252,7 @@ ssize_t circbuf_all_write(struct file * file, const char * buf, size_t count, lo
int circbuf_all_mmap (struct file *file, struct vm_area_struct *vma) {
int circbuf_all_mmap (struct file *file, struct vm_area_struct *vma) {
     struct circbuf_pd * privData;
     struct circbuf_pd * privData;
     privData = (struct circbuf_pd *) file->private_data;
     privData = (struct circbuf_pd *) file->private_data;
 MD10(printk("circbuf_all_mmap, minor=0x%x\n",privData-> minor));
 dev_dbg(g_dev_ptr, "minor = 0x%x\n", privData->minor);
     switch (privData->minor) {
     switch (privData->minor) {
       case  CMOSCAM_MINOR_CIRCBUF :   return  circbuf_mmap   (file, vma);
       case  CMOSCAM_MINOR_CIRCBUF :   return  circbuf_mmap   (file, vma);
       default: return -EINVAL;
       default: return -EINVAL;
@@ -266,7 +262,7 @@ int circbuf_all_mmap (struct file *file, struct vm_area_struct *vma) {
unsigned int circbuf_all_poll (struct file *file, poll_table *wait) {
unsigned int circbuf_all_poll (struct file *file, poll_table *wait) {
     struct circbuf_pd * privData;
     struct circbuf_pd * privData;
     privData = (struct circbuf_pd *) file->private_data;
     privData = (struct circbuf_pd *) file->private_data;
 MD10(printk("circbuf_all_poll, minor=0x%x\n",privData-> minor));
 dev_dbg(g_dev_ptr, "minor = 0x%x\n", privData->minor);
     switch (privData->minor) {
     switch (privData->minor) {
       case  CMOSCAM_MINOR_CIRCBUF :
       case  CMOSCAM_MINOR_CIRCBUF :
          return circbuf_poll (file, wait);
          return circbuf_poll (file, wait);
@@ -291,8 +287,9 @@ int circbuf_open(struct inode *inode, struct file *filp) { // set filesize
   filp->private_data = privData;
   filp->private_data = privData;
   privData-> minor=MINOR(inode->i_rdev);
   privData-> minor=MINOR(inode->i_rdev);


   inode->i_size = ((CCAM_DMA_SIZE) << 2);
   //inode->i_size = ((CCAM_DMA_SIZE) << 2);
 MD10(printk("circbuf_open, inode->i_size=0x%x\n", (int)inode->i_size));
   inode->i_size = CCAM_DMA_SIZE;
   dev_dbg(g_dev_ptr, "inode->i_size = 0x%x\n");


//!should be removed (or else you can not ftp file - it will start from WP)
//!should be removed (or else you can not ftp file - it will start from WP)
//   circbuf_lseek(filp, LSEEK_CIRC_LAST, SEEK_END); //! position at last acquired frame, ignore result
//   circbuf_lseek(filp, LSEEK_CIRC_LAST, SEEK_END); //! position at last acquired frame, ignore result
@@ -351,82 +348,68 @@ void dump_interframe_params(struct interframe_params_t *params)
	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, params, sizeof(struct interframe_params_t));
	print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, params, sizeof(struct interframe_params_t));
}
}


unsigned long get_image_length(int offset, unsigned int chn, int *last_chunk_offset)
unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chunk_offset)
{
{
	unsigned long len32;
	unsigned long len32;
	int last_image_chunk = DW2BYTE(offset) - OFFSET_X40;
	int last_image_chunk = byte_offset - OFFSET_X40;


	if (last_image_chunk < 0)
	if (last_image_chunk < 0)
		last_image_chunk += CCAM_DMA_SIZE;
		last_image_chunk += CCAM_DMA_SIZE;
	len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH))];
	len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH))];

	dev_dbg(g_dev_ptr, "got len32 = 0x%x at 0x%x\n", len32, last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH));

	if (last_chunk_offset != NULL)
	if (last_chunk_offset != NULL)
		*last_chunk_offset = last_image_chunk;
		*last_chunk_offset = last_image_chunk;


	return len32;
	return len32;
}
}


// rp is byte offset
int circbufValidPointer(int rp, struct interframe_params_t ** fpp, unsigned int chn)
int circbufValidPointer(int rp, struct interframe_params_t ** fpp, unsigned int chn)
{
{
	int last_image_chunk;
	int last_image_chunk;
	unsigned int sec;
	unsigned int sec;
	unsigned int usec;
	unsigned int usec;
	int wp = camseq_get_jpeg_wp(chn);
	int wp = camseq_get_jpeg_wp(chn);
	unsigned int len32 = get_image_length(wp, chn, &last_image_chunk);
	unsigned int len32 = get_image_length(DW2BYTE(wp), chn, &last_image_chunk);
	struct interframe_params_t *fp;
	struct interframe_params_t *fp;
	int p = BYTE2DW(rp);


	if (rp & 0x1f) {  //!rp is not 32-bytes aligned
	if (rp & 0x1f) {  //!rp is not 32-bytes aligned
		//MD10(printk("circbufValidPointer: misaligned pointer\n"));
		//MD10(printk("circbufValidPointer: misaligned pointer\n"));
		dev_dbg(g_dev_ptr, "misaligned pointer rp = 0x%x for channel %d\n", rp, chn);
		dev_dbg(g_dev_ptr, "misaligned pointer rp = 0x%x for channel %d\n", rp, chn);
		return -2;
		return -2;
	}
	}
	fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[X393_BUFFSUB(p, INTERFRAME_PARAMS_SZ)];
	fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[BYTE2DW(X393_BUFFSUB(rp, OFFSET_X40))];
	*fpp = fp;
	*fpp = fp;


	dump_interframe_params(fp);
	dump_interframe_params(fp);
	/*int wp = camseq_get_jpeg_wp(chn);
	int p = rp >> 2; // index inccam_dma_buf
	struct interframe_params_t * fp;
	fp = (struct interframe_params_t *) &ccam_dma_buf[X313_BUFFSUB(p, 8)]; //! 32 bytes before the frame pointer, may roll-over to the end of ccam_dma_buf

	//MD10(printk("rp=0x%x (0x%x), offset=0x%x\n",rp,p,(int)&ccam_dma_buf[p]-(int)fp); dumpFrameParams(fp, "in circbufValidPointer:"));
	dev_dbg(g_dev_ptr, "rp=0x%x (0x%x), offset=0x%x\n", rp, p, (int)&ccam_dma_buf[p]-(int)fp);

	*fpp=fp;
	//MD11(printk("p=0x%x , wp==0x%x\n",p,wp));
	dev_dbg(g_dev_ptr, "p=0x%x , wp==0x%x\n", p, wp);
	if (p == wp) {
		return 0; // frame not yet acquired, fp - not valid
	}
	if (fp->signffff != MARKER_FF) { //! signature is overwritten
		//MD10(printk("circbufValidPointer: signanure overwritten\n"));
		dev_dbg(g_dev_ptr, "signature 0xFF overwritten\n");
		return -1;
	}
	if ((fp->timestamp_sec) & X313_LENGTH_MASK) {
		//MDF(printk ("Should not get here - fp->timestamp_sec=0x%x\n",(int) fp->timestamp_sec));
		dev_dbg(g_dev_ptr, "Should not get here - fp->timestamp_sec=0x%x\n", (int) fp->timestamp_sec);
		return 0; //! should not get here - should be caught by (p==wp)
	}*/


	if (BYTE2DW(rp) == wp)
	if (BYTE2DW(rp) == wp)
		// frame not yet acquired (?)
		// frame not yet acquired (?)
		return 0;
		return 0;


	dev_dbg(g_dev_ptr, "checking end of frame marker len32 = 0x%x at offset = 0x%x\n", len32, DW2BYTE(wp));
	dev_dbg(g_dev_ptr, "checking end of frame marker len32 = 0x%x at offset = 0x%x\n", fp->len32 & FRAME_LENGTH_MASK, rp);
	if ((len32 & MARKER_FF) != MARKER_FF) {
	/*if ((len32 & MARKER_FF) != MARKER_FF) {
		wp -= CHUNK_SIZE;
		wp -= CHUNK_SIZE;
		len32 = get_image_length(wp, chn, &last_image_chunk);
		len32 = get_image_length(DW2BYTE(wp), chn, &last_image_chunk);
		if ((len32 & MARKER_FF) != MARKER_FF) {
		if ((len32 & MARKER_FF) != MARKER_FF) {
			dev_dbg(g_dev_ptr, "failed to get marker 0xFF at CORRECTED offset\n");
			dev_dbg(g_dev_ptr, "failed to get marker 0xFF at CORRECTED offset\n");
			return -1;
			return -1;
		}
		}
	}*/
	if ((fp->len32 & MARKER_FF) != MARKER_FF) {
		len32 = get_image_length(rp - CHUNK_SIZE, chn, &last_image_chunk);
		if ((len32 & MARKER_FF) != MARKER_FF) {
			dev_dbg(g_dev_ptr, "failed to get marker 0xFF at CORRECTED offset 0x%x\n", rp - CHUNK_SIZE);
			return -1;
		}
	}
	}


	// check timestamp
	// check timestamp
	sec = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_SEC))];
	//sec = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_SEC))];
	usec = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk +(CHUNK_SIZE - CCAM_MMAP_META_USEC))];
	//usec = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk +(CHUNK_SIZE - CCAM_MMAP_META_USEC))];
	dev_dbg(g_dev_ptr, "reading time stamp: sec = 0x%x, usec = 0x%x\n", sec, usec);
	dev_dbg(g_dev_ptr, "reading time stamp: sec = 0x%x, usec = 0x%x\n", fp->timestamp_sec, fp->timestamp_usec);


	return 1;
	return 1;
}
}
@@ -448,7 +431,7 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
   int fvld=-1;
   int fvld=-1;
   int rp, bp; //, p;
   int rp, bp; //, p;
//   int pf; // previous frame
//   int pf; // previous frame
 MD11(printk("circbuf_lseek, offset=0x%x, orig=0x%x\n",(int) offset, (int) orig));
 dev_dbg(g_dev_ptr, "start processing LSEEK operation: offset = 0x%x, orig = 0x%x\n",(int) offset, (int) orig);
   switch(orig) {
   switch(orig) {
   case SEEK_SET:
   case SEEK_SET:
     file->f_pos = offset;
     file->f_pos = offset;
@@ -478,9 +461,11 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
        }
        }
        switch (offset) {
        switch (offset) {
          case LSEEK_CIRC_FREE:
          case LSEEK_CIRC_FREE:
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_FREE: checking remaining memory in circbuf\n");
        	  bp = file->f_pos - (camseq_get_jpeg_wp(chn) << 2);
        	  bp = file->f_pos - (camseq_get_jpeg_wp(chn) << 2);
             return (file->f_pos = (bp > 0) ? bp : (bp + l)); //!Has a side effect of moving a file pointer!
             return (file->f_pos = (bp > 0) ? bp : (bp + l)); //!Has a side effect of moving a file pointer!
          case LSEEK_CIRC_USED:
          case LSEEK_CIRC_USED:
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_USED: checking used memory in circbuf\n");
        	  bp = (camseq_get_jpeg_wp(chn) << 2) - file->f_pos;
        	  bp = (camseq_get_jpeg_wp(chn) << 2) - file->f_pos;
             return (file->f_pos = (bp > 0) ? bp : (bp + l)); //!Has a side effect of moving a file pointer!
             return (file->f_pos = (bp > 0) ? bp : (bp + l)); //!Has a side effect of moving a file pointer!
          case LSEEK_CIRC_TORP:
          case LSEEK_CIRC_TORP:
@@ -498,18 +483,18 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
        	  dev_dbg(g_dev_ptr, "mem dump of last 0x40 bytes in buffer number %d\n", chn);
        	  dev_dbg(g_dev_ptr, "mem dump of last 0x40 bytes in buffer number %d\n", chn);
        	  print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, &circbuf_priv[chn].buf_ptr[BYTE2DW(next_img - OFFSET_X40)], OFFSET_X40);
        	  print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, &circbuf_priv[chn].buf_ptr[BYTE2DW(next_img - OFFSET_X40)], OFFSET_X40);


        	  len32 = get_image_length(next_img, chn, NULL);
        	  len32 = get_image_length(next_img, chn, &last_image_chunk);
        	  if ((len32 & MARKER_FF) != MARKER_FF) {
        	  if ((len32 & MARKER_FF) != MARKER_FF) {
        		  // we should not be here as the position was checked in circbufValidPointer
        		  // we should not be here as the position was checked in circbufValidPointer
        		  dev_dbg(g_dev_ptr, "failed to get marker 0xFF at 0x%x, len32: 0x%x\n", next_img, len32);
        		  dev_dbg(g_dev_ptr, "failed to get marker 0xFF at 0x%x, len32: 0x%x\n", next_img, len32);
        		  return -EOVERFLOW;
        		  return -EOVERFLOW;
        	  }
        	  }
        	  /*len32 &= 0xffffff;
        	  len32 &= 0xffffff;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  img_start = last_image_chunk + CHUNK_SIZE - inserted_bytes - CCAM_MMAP_META - len32;
        	  img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - inserted_bytes - CCAM_MMAP_META, len32);
        	  dev_dbg(g_dev_ptr, "calculated start address = 0x%x, length = 0x%x\n", img_start, len32);*/
        	  dev_dbg(g_dev_ptr, "calculated start address = 0x%x, length = 0x%x\n", img_start, len32);
        	  file->f_pos = next_img;
        	  file->f_pos = img_start;
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_LAST: moving file->f_pos to 0x%x\n", file->f_pos);
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_LAST: moving file->f_pos to 0x%llx\n", file->f_pos);
        	  break;
        	  break;
          case LSEEK_CIRC_PREV:
          case LSEEK_CIRC_PREV:
        	  next_img = camseq_get_jpeg_wp(chn) << 2;
        	  next_img = camseq_get_jpeg_wp(chn) << 2;
@@ -527,7 +512,7 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
        	  }
        	  }
        	  len32 &= 0xffffff;
        	  len32 &= 0xffffff;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  img_start = last_image_chunk + CHUNK_SIZE - inserted_bytes - CCAM_MMAP_META - len32;
        	  img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - inserted_bytes - CCAM_MMAP_META, len32);
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_PREV: calculated start address = 0x%x, length = 0x%x\n", img_start, len32);
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_PREV: calculated start address = 0x%x, length = 0x%x\n", img_start, len32);


        	  // move file pointer only if previous frame valid
        	  // move file pointer only if previous frame valid
@@ -541,9 +526,10 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
             if (fvld <= 0)
             if (fvld <= 0)
                return -EOVERFLOW; //! no frames after current
                return -EOVERFLOW; //! no frames after current
             // calculate the full length of current frame and advance file pointer by this value
             // calculate the full length of current frame and advance file pointer by this value
             len32 = fp->len32 & FRAME_LENGTH_MASK;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  padded_frame = fp->len32 + inserted_bytes + CHUNK_SIZE + CCAM_MMAP_META;
        	  padded_frame = len32 + inserted_bytes + CHUNK_SIZE + CCAM_MMAP_META;
             file->f_pos = X393_BUFFADD(file->f_pos >> 2, padded_frame) << 2 ;// do it even if the next frame does not yet exist
             file->f_pos = X393_BUFFADD(file->f_pos, padded_frame); // do it even if the next frame does not yet exist
             dev_dbg(g_dev_ptr, "LSEEK_CIRC_NEXT: moving file->f_pos to 0x%x\n", file->f_pos);
             dev_dbg(g_dev_ptr, "LSEEK_CIRC_NEXT: moving file->f_pos to 0x%x\n", file->f_pos);
             break;
             break;
          case LSEEK_CIRC_FIRST:
          case LSEEK_CIRC_FIRST:
@@ -562,13 +548,13 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
               preprev_p = prev_p; //! second known good (at least first one)
               preprev_p = prev_p; //! second known good (at least first one)
               prev_p=rp;        //!now - current, known good
               prev_p=rp;        //!now - current, known good
               //fl=ccam_dma_buf[X313_BUFFSUB(rp, 9)] ^ X313_LENGTH_MASK;
               //fl=ccam_dma_buf[X313_BUFFSUB(rp, 9)] ^ X313_LENGTH_MASK;
               len32 = get_image_length(rp, chn, last_image_chunk);
               len32 = get_image_length(DW2BYTE(rp), chn, last_image_chunk);
 	 	 	   dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x", nf, rp, fvld, len32);
 	 	 	   dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: number of frames = %d, rp = 0x%x, fvld = %d, len32 = 0x%x", nf, rp, fvld, len32);
               if ((len32 & MARKER_FF) != MARKER_FF ) break;  //! no frames before rp (==prev_p)
               if ((len32 & MARKER_FF) != MARKER_FF ) break;  //! no frames before rp (==prev_p)
//! move rp to the previous frame
//! move rp to the previous frame
        	  len32 &= 0xffffff;
        	  len32 &= 0xffffff;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  inserted_bytes = ((CHUNK_SIZE - (((len32 % CHUNK_SIZE) + CCAM_MMAP_META) % CHUNK_SIZE) - ADJUSTMENT) % CHUNK_SIZE ) + ADJUSTMENT;
        	  img_start = last_image_chunk + CHUNK_SIZE - inserted_bytes - CCAM_MMAP_META - len32;
        	  img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - inserted_bytes - CCAM_MMAP_META, len32);
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: calculated start address = 0x%x, length = 0x%x\n", img_start, len32);
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: calculated start address = 0x%x, length = 0x%x\n", img_start, len32);
               rp = BYTE2DW(img_start);
               rp = BYTE2DW(img_start);
               if (rp > prev_p) nz-- ; // rolled through zero - make sure we'll not stuck in this loop forever
               if (rp > prev_p) nz-- ; // rolled through zero - make sure we'll not stuck in this loop forever
@@ -579,15 +565,19 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
          }
          }
          case LSEEK_CIRC_SETP:
          case LSEEK_CIRC_SETP:
             //camSeqSetJPEG_rp(file->f_pos>>2);
             //camSeqSetJPEG_rp(file->f_pos>>2);
        	  camseq_set_jpeg_rp(file->f_pos >> 2, chn);
        	  dev_dbg(g_dev_ptr, "LSEK_CIRC_SETP: Setting jpeg_rp for channel %d to file->f_pos = 0x%x\n", chn, file->f_pos);
        	  camseq_set_jpeg_rp(chn, file->f_pos >> 2);
             break;
             break;
          case LSEEK_CIRC_VALID:
          case LSEEK_CIRC_VALID:
        	  // no actions to be done here, the pointer was checked on previous step
        	  // no actions to be done here, the pointer was checked on previous step
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_VALID: no action required\n");
             break;
             break;
          case LSEEK_CIRC_READY:
          case LSEEK_CIRC_READY:
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_READY: checking fvld, fvld = %d\n", fvld);
             if (fvld <=0) return -EINVAL; //! no frame is available better code?
             if (fvld <=0) return -EINVAL; //! no frame is available better code?
             break;
             break;
          case LSEEK_CIRC_WAIT:
          case LSEEK_CIRC_WAIT:
        	  dev_dbg(g_dev_ptr, "LSEEK_CIRC_WAIT\n");
              while (((fvld=circbufValidPointer(file->f_pos, &fp, chn)))==0) { //! only while not ready, ready or BAD - return
              while (((fvld=circbufValidPointer(file->f_pos, &fp, chn)))==0) { //! only while not ready, ready or BAD - return
                //wait_event_interruptible(circbuf_wait_queue,(camSeqGetJPEG_wp()<<2)!=file->f_pos);
                //wait_event_interruptible(circbuf_wait_queue,(camSeqGetJPEG_wp()<<2)!=file->f_pos);
                wait_event_interruptible(circbuf_wait_queue, (camseq_get_jpeg_wp(chn) << 2) != file->f_pos);
                wait_event_interruptible(circbuf_wait_queue, (camseq_get_jpeg_wp(chn) << 2) != file->f_pos);
@@ -719,10 +709,10 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait)
	struct circbuf_pd * privData;
	struct circbuf_pd * privData;
	privData = (struct circbuf_pd *) file->private_data;
	privData = (struct circbuf_pd *) file->private_data;
	int rslt; //!result of testing read poinetr
	int rslt; //!result of testing read poinetr
	MD10(printk("circbuf_poll\n"));
	dev_dbg(g_dev_ptr, "minor = 0x%x\n", minor);
	rslt= circbufValidPointer(file->f_pos, &fp, chn);
	rslt= circbufValidPointer(file->f_pos, &fp, chn);
	if        (rslt < 0) { //! not a valid read pointer, probable buffer overrun
	if        (rslt < 0) { //! not a valid read pointer, probable buffer overrun
		MD10(printk("circbuf_poll:invalid pointer\n"));
		dev_dbg(g_dev_ptr, "invalid pointer file->f_pos = 0x%x\n", file->f_pos);
		return  POLLHUP ;
		return  POLLHUP ;
	} else if (rslt > 0) {
	} else if (rslt > 0) {
		return POLLIN | POLLRDNORM; //! there was frame already available
		return POLLIN | POLLRDNORM; //! there was frame already available
+98 −90

File changed.

Preview size limit exceeded, changes collapsed.

+1 −1
Original line number Original line Diff line number Diff line
@@ -38,7 +38,7 @@ struct huffman_pd {
int  jpeg_htable_is_programmed(void);
int  jpeg_htable_is_programmed(void);
void jpeg_htable_init (void);
void jpeg_htable_init (void);
int  jpeg_htable_fpga_encode (void);
int  jpeg_htable_fpga_encode (void);
void jpeg_htable_fpga_pgm (void);
void jpeg_htable_fpga_pgm (unsigned int chn);
int  jpeg_prep_htable (struct huffman_encoded_t * htable, struct huffman_fpga_code_t * hcodes);
int  jpeg_prep_htable (struct huffman_encoded_t * htable, struct huffman_fpga_code_t * hcodes);


#endif /* _JPEGHEAD */
#endif /* _JPEGHEAD */
+18 −7
Original line number Original line Diff line number Diff line
@@ -283,7 +283,15 @@ inline void updateIRQFocus(struct jpeg_ptr_t *jptr)
	u32 high_freq = x393_cmprs_hifreq(jptr->chn_num);
	u32 high_freq = x393_cmprs_hifreq(jptr->chn_num);
}
}



static void set_default_interframe(struct interframe_params_t *params)
{
	params->height = 1936;
	params->width = 2592;
	params->byrshift = 0;
	params->color = 0;
	params->quality2 = 127;
	dev_dbg(NULL, "%s: DEBUG, setting default interframe parameters\n", __func__);
}


/**
/**
 * @brief Locate area between frames in the circular buffer
 * @brief Locate area between frames in the circular buffer
@@ -310,10 +318,13 @@ inline struct interframe_params_t* updateIRQ_interframe(struct jpeg_ptr_t *jptr)
	int circbuf_size = BYTE2DW(get_globalParam(G_CIRCBUFSIZE));
	int circbuf_size = BYTE2DW(get_globalParam(G_CIRCBUFSIZE));
	int len_offset = X393_BUFFSUB(jptr->jpeg_wp, 8);
	int len_offset = X393_BUFFSUB(jptr->jpeg_wp, 8);
	int len32 = circbuf_priv_ptr[jptr->chn_num].buf_ptr[len_offset] & FRAME_LENGTH_MASK;
	int len32 = circbuf_priv_ptr[jptr->chn_num].buf_ptr[len_offset] & FRAME_LENGTH_MASK;
	int frame_params_offset = X393_BUFFSUB(jptr->jpeg_wp, INTERFRAME_PARAMS_SZ);
	int frame_params_offset = X393_BUFFSUB(jptr->jpeg_wp, OFFSET_X40);


	interframe = (struct interframe_params_t *) &circbuf_priv_ptr[jptr->chn_num].buf_ptr[frame_params_offset];
	interframe = (struct interframe_params_t *) &circbuf_priv_ptr[jptr->chn_num].buf_ptr[frame_params_offset];
	interframe->frame_length = len32;
	//interframe->frame_length = len32;

	set_default_interframe(interframe);

	set_globalParam(G_FRAME_SIZE, len32);
	set_globalParam(G_FRAME_SIZE, len32);


   return interframe;
   return interframe;
@@ -462,9 +473,9 @@ static irqreturn_t compressor_irq_handler(int irq, void *dev_id)
	if (updateIRQJPEG_wp(priv)) {
	if (updateIRQJPEG_wp(priv)) {
		update_irq_circbuf(priv);
		update_irq_circbuf(priv);
		updateIRQFocus(priv);
		updateIRQFocus(priv);
		/*interframe = updateIRQ_interframe();
		interframe = updateIRQ_interframe(priv);
		updateIRQ_Exif(interframe);
		//updateIRQ_Exif(interframe);
		wake_up_interruptible(&circbuf_wait_queue);*/
		wake_up_interruptible(&circbuf_wait_queue);
	}
	}
	//wake_up_interruptible(&framepars_wait_queue);
	//wake_up_interruptible(&framepars_wait_queue);


@@ -513,7 +524,7 @@ void tasklet_fpga_function(unsigned long arg) {
  int len32;
  int len32;
  int circbuf_size = get_globalParam(G_CIRCBUFSIZE);
  int circbuf_size = get_globalParam(G_CIRCBUFSIZE);
  unsigned long *buf_ptr;
  unsigned long *buf_ptr;
  printk(KERN_DEBUG "%s: get_globalParam(G_CIRCBUFSIZE) = %d", __func__, circbuf_size);
  printk(KERN_DEBUG "%s: get_globalParam(G_CIRCBUFSIZE) = %d\n", __func__, circbuf_size);




#ifdef TEST_DISABLE_CODE
#ifdef TEST_DISABLE_CODE
+9 −29
Original line number Original line Diff line number Diff line
@@ -1641,37 +1641,17 @@ struct sensorproc_t {
///*32-35*/ unsigned long  timestamp_usec; //! number of microseconds to add
///*32-35*/ unsigned long  timestamp_usec; //! number of microseconds to add
//};
//};


/* Some fields were rearranged to make old code happy, this should to be fixed
/* Some fields were removed, may be we will need them later
 * Last three double words contain time stamp and (length+0xff) marker in new camera
 * Last three double words contain time stamp and (length+0xff) marker in new camera
 */
 */
struct interframe_params_t {
struct interframe_params_t {
/// This data will survive as long as the frame itself in the circular buffer. Some other fields (like exposure) are stored in Exif 
	unsigned long quality2;
/// dont move - should partially match P_* area
	unsigned long color;
	union {
	unsigned long byrshift;
   union{unsigned long hash32_r; struct{unsigned short scale_r; union {unsigned short hash16_r; struct{unsigned char gamma_r; unsigned char black_r; };};};}; ///00-03
	unsigned long width;
   union{unsigned long hash32_g; struct{unsigned short scale_g; union {unsigned short hash16_g; struct{unsigned char gamma_g; unsigned char black_g; };};};}; ///04-07
	unsigned long height;
	};
	unsigned long  timestamp_sec;        //! number of seconds since 1970 till the start of the frame exposure
   union{unsigned long hash32_gb;struct{unsigned short scale_gb;union {unsigned short hash16_gb;struct{unsigned char gamma_gb;unsigned char black_gb;};};};}; ///08-11
	unsigned long  timestamp_usec;       //! number of microseconds to add
   union{unsigned long hash32_b; struct{unsigned short scale_b; union {unsigned short hash16_b; struct{unsigned char gamma_b; unsigned char black_b; };};};}; ///12-15
   unsigned short quality2;       /// Quality is represented by 2-byte value. Each byte uses Y table if the value is Q<128,// 16-17
                                  /// and C table with (Q-128) if it is Q>=128.
                                  /// If the High byte is zero, it is treated as Q^0x80  (Q|=(Q^0x80)<<8) for compatibility
                                  /// with a standard single-byte Q value
/// updated in 8.0.8.37 - bit 7 in quality2 means "portrait mode"
   unsigned char  color;          /// color mode //18
   unsigned char  byrshift;       /// bayer shift in compressor //19
   unsigned short width;          /// frame width, pixels   20-21 - NOTE: should be 20-21
   unsigned short height;         /// frame height, pixels  22-23

/*24   *//// unsigned char  bindec_hor;     //! ((bh-1) << 4) | (dh-1) & 0xf (binning/decimation horizontal, 1..16 for each)
/*25   *//// unsigned char  bindec_vert;    //! ((bv-1) << 4) | (dv-1) & 0xf (binning/decimation vertical  , 1..16 for each)
/*24-25*/ unsigned long meta_index;     //! index of the linked meta page

   union {
/*28-31*/ unsigned long  timestamp_sec ; //! number of seconds since 1970 till the start of the frame exposure
/*28-31*/ unsigned long frame_length;    //! JPEG frame length in circular buffer, bytes
   };
/*32-35*/ unsigned long  timestamp_usec; //! number of microseconds to add
	union {
	union {
		unsigned long len32;             //! should be 0xffxxyyzz - it will be a signature that JPEG data was not overwritten,
		unsigned long len32;             //! should be 0xffxxyyzz - it will be a signature that JPEG data was not overwritten,
	                                     //! xxyyzz here is the length in 32 double words;
	                                     //! xxyyzz here is the length in 32 double words;
@@ -1679,7 +1659,7 @@ struct interframe_params_t {
			unsigned char pad0;          // pad double word with 3 bytes and use only most significant byte as 0xff marker
			unsigned char pad0;          // pad double word with 3 bytes and use only most significant byte as 0xff marker
			unsigned char pad1;
			unsigned char pad1;
			unsigned char pad2;
			unsigned char pad2;
			unsigned char signffff;
			unsigned char signff;
		};
		};
	};
	};
};
};