Commit 1769750d authored by Andrey Filippov's avatar Andrey Filippov
Browse files

debugging initialization

parent b2b0813b
Loading
Loading
Loading
Loading
+269 −45
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@
#include "framepars.h"
#include "sensor_common.h"
#include "jpeghead.h"
#include "circbuf.h"
//#include "circbuf.h"
#include "exif.h"
#include "x393_macro.h"
#include "x393_helpers.h"
@@ -59,6 +59,12 @@ static struct device *g_dev_ptr;
static const struct of_device_id elphel393_circbuf_of_match[];
unsigned long *ccam_dma_buf_ptr[SENSOR_PORTS] = {NULL};

/** Get structure describing selected circbuf channel (start virtual and physical, buffer size) */
struct  circbuf_priv_t *get_circbuf(int chn)                      ///< compressor channel
                                                                  ///< @return pointer to requested structure
{
    return &circbuf_priv[chn];
}
/**
 * @brief Set up pointers to memory where circular buffers are located. The memory
 * for circular buffers is reserved using CMA mechanism.
@@ -91,9 +97,12 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev)
	for (i = 0; i < SENSOR_PORTS; i++) {
		circbuf_priv[i].buf_ptr = dma_buf_ptr + BYTE2DW(CIRCBUF_START_OFFSET + i * CCAM_DMA_SIZE);
		circbuf_priv[i].phys_addr = dma_handle + CIRCBUF_START_OFFSET + i * CCAM_DMA_SIZE;
		circbuf_priv[i].buf_size = CCAM_DMA_SIZE;

		circbuf_priv[i].buf_size32 = circbuf_priv[i].buf_size; // used in many places
		ccam_dma_buf_ptr[i] = circbuf_priv[i].buf_ptr;
		// set circular buffer size in bytes
		set_globalParam(i, G_CIRCBUFSIZE, CCAM_DMA_SIZE);
		set_globalParam(i, G_CIRCBUFSIZE, circbuf_priv[i].buf_size);
	}

	return 0;
@@ -184,7 +193,7 @@ loff_t circbuf_all_lseek(struct file *file, loff_t offset, int orig)
		return  circbuf_lseek(file, offset, orig);
	case DEV393_MINOR(DEV393_JPEGHEAD0):
		if (orig == SEEK_END && offset > 0) {
			rp = BYTE2DW(X393_BUFFSUB(offset, CHUNK_SIZE)) & (~7); // convert to index to long, align to 32-bytes
			rp = BYTE2DW(X393_BUFFSUB_CHN(offset, CHUNK_SIZE, chn)) & (~7); // convert to index to long, align to 32-bytes
			fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[rp];
		}
		return  jpeghead_lseek(file, offset, orig, fp);
@@ -307,7 +316,8 @@ unsigned int circbuf_all_poll(struct file *file, poll_table *wait)
 */
int circbuf_open(struct inode *inode, struct file *filp)
{
	inode->i_size = CCAM_DMA_SIZE;
    unsigned int minor = MINOR(inode->i_rdev);
	inode->i_size = circbuf_priv[minor_to_chn(minor, NULL)].buf_size; // CCAM__DMA_SIZE;
	dev_dbg(g_dev_ptr, "inode->i_size = 0x%lx\n", inode->i_size);

	return 0;
@@ -339,17 +349,17 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun
{
	unsigned int offset;
	unsigned long len32;
	int last_image_chunk = X393_BUFFSUB(byte_offset, OFFSET_X40);
	int last_image_chunk = X393_BUFFSUB_CHN(byte_offset, OFFSET_X40, chn);

	offset = X393_BUFFADD(last_image_chunk, CHUNK_SIZE - CCAM_MMAP_META_LENGTH);
	offset = X393_BUFFADD_CHN(last_image_chunk, CHUNK_SIZE - CCAM_MMAP_META_LENGTH, chn);
	len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(offset)];

	dev_dbg(g_dev_ptr, "[chn %d] byte_offset = 0x%x, calculated offset = 0x%x, len32 = 0x%lx\n", chn, byte_offset, offset, len32);

	if ((len32 & MARKER_FF) != MARKER_FF) {
		dev_dbg(g_dev_ptr, "[chn %u] failed to get 0xff marker at offset 0x%x\n", chn, offset);
		last_image_chunk = X393_BUFFSUB(byte_offset, OFFSET_X40 + CHUNK_SIZE);
		offset = X393_BUFFADD(last_image_chunk, CHUNK_SIZE - CCAM_MMAP_META_LENGTH);
		last_image_chunk = X393_BUFFSUB_CHN(byte_offset, OFFSET_X40 + CHUNK_SIZE, chn);
		offset = X393_BUFFADD_CHN(last_image_chunk, CHUNK_SIZE - CCAM_MMAP_META_LENGTH, chn);
		len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(offset)];
		if ((len32 & MARKER_FF) != MARKER_FF) {
			dev_dbg(g_dev_ptr, "[chn %u] failed to get 0xff marker at CORRECTED offset 0x%x\n", chn, offset);
@@ -376,6 +386,7 @@ unsigned long get_image_length(int byte_offset, unsigned int chn, int *last_chun
 * -1 if there is no frame at this index, -2 if the pointer is not 32-bytes aligned
 * sets *fpp to the frame header, including signature and length
 */
//#ifdef PRE_FRAMEPARS
int circbuf_valid_ptr(loff_t *rp_offset, struct interframe_params_t **fpp, unsigned int chn)
{
	int rp = *rp_offset;
@@ -391,10 +402,10 @@ int circbuf_valid_ptr(loff_t *rp_offset, struct interframe_params_t **fpp, unsig
		dev_dbg(g_dev_ptr, "misaligned pointer rp = 0x%x for channel %d\n", rp, chn);
		return -2;
	}
	fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[BYTE2DW(X393_BUFFSUB(rp, sizeof(struct interframe_params_t) - 4))];
	fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[BYTE2DW(X393_BUFFSUB_CHN(rp, sizeof(struct interframe_params_t) - 4, chn))];
	*fpp = fp;

	dump_interframe_params(fp, X393_BUFFSUB(rp, sizeof(struct interframe_params_t) - 4), chn);
	dump_interframe_params(fp, X393_BUFFSUB_CHN(rp, sizeof(struct interframe_params_t) - 4, chn), chn);

	if (BYTE2DW(rp) == wp)
		// read pointer and write pointer coincide, frame not yet acquired
@@ -409,26 +420,82 @@ int circbuf_valid_ptr(loff_t *rp_offset, struct interframe_params_t **fpp, unsig
		} else {
			dev_dbg(g_dev_ptr, "[chn %u] interframe pointer and file ponter is advanced by 0x20\n", chn);
			*fpp = fp_off;
			*rp_offset = X393_BUFFADD(*rp_offset, CHUNK_SIZE);
			*rp_offset = X393_BUFFADD_CHN(*rp_offset, CHUNK_SIZE, chn);
			dump_interframe_params(fp_off, rp, chn);
			return 2;
		}
	}
	return 1;
}
//#endif
/**
 *  returns 0 if rp is a valid read ponter
 *  returns 1 if there is a frame at this address
 *  returns 0 if the pointer is for the frame yet to be acquired
 *  returns -1 if there is no frame at this index
 *  returns -2 if the rp is not 32-bytes aligned
 *  sets *fpp to the frame header, including signature and length */
// ccam_dma_buf u32 array
//#define X313_LENGTH_MASK      0xff000000
#define X313_PADDED_FRAME(x)((((x)+67+CCAM_MMAP_META ) >>2) & 0xfffffff8)
//#define X313_BUFFSUB(x,y) (((x)>=(y))? ((x)-(y)) : ((x)+ (CCAM_DMA_SIZE-(y))))
//#define X313_BUFFADD(x,y) ((((x) + (y))<=CCAM_DMA_SIZE)? ((x) + (y)) : ((x) - (CCAM_DMA_SIZE-(y))))

int circbufValidPointer(int rp,
        struct interframe_params_t ** fpp,
        unsigned int chn)
{
    if (rp & 0x1f) {  //!rp is not 32-bytes aligned
        dev_dbg(g_dev_ptr, "circbufValidPointer: misaligned pointer\n");
        return -2;
    }
    int wp=camSeqGetJPEG_wp(chn);
    int p= rp >> 2; // index in ccam_dma_buf
    struct interframe_params_t * fp;
    fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[X393_BUFFSUB32(p, 8, chn)]; // 32 bytes before the frame pointer, may roll-over to the end of ccam_dma_buf

    dev_dbg(g_dev_ptr, "rp=0x%x (0x%x), offset=0x%x\n",
            rp, p, (int) &circbuf_priv[chn].buf_ptr[p]-(int)fp);
//    dumpFrameParams(fp, "in circbufValidPointer:");

    *fpp=fp;
    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 != 0xffff) { //! signature is overwritten
        dev_dbg(g_dev_ptr, "circbufValidPointer: signanure overwritten\n");
        return -1;
    }
    if ((fp->timestamp_sec) & X313_LENGTH_MASK) {
        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)
    }
    return 1;
}




/**
 * @brief Get image start offset pointed by its last data chunk
 * @param[in]   last_chunk_offset   offset of the last image data chunk
 * @param[in]   len32               length of image
 * @return      Image start offset
 */
#if 0
inline int get_image_start(int last_chunk_offset, unsigned int len32)
{
	return X393_BUFFSUB(last_chunk_offset + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
	return X393_BUFFSUB_(last_chunk_offset + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
}
#endif

inline int get_image_start_chn(int last_chunk_offset, unsigned int len32, int chn)
{
    return X393_BUFFSUB_CHN(last_chunk_offset + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32, chn);
}


/* debug code follows */
void stop_compressor(unsigned int chn)
{
@@ -458,8 +525,8 @@ void dump_state(unsigned int chn)
		return;
	}
	len32 &= FRAME_LENGTH_MASK;
	//img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
	img_start = get_image_start(last_image_chunk, len32);
	//img_start = X393__BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
	img_start = get_image_start_chn(last_image_chunk, len32, chn);
	read_ptr = img_start;
	// move back in history
	while ((circbuf_valid_ptr(&read_ptr, &fp, chn) >= 0) && (nz >= 0)) {
@@ -476,8 +543,8 @@ void dump_state(unsigned int chn)
		}
		len32 &= FRAME_LENGTH_MASK;
		//printk(KERN_DEBUG "\t\tgot len32 = 0x%x", len32);
		//img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
		img_start = get_image_start(last_image_chunk, len32);
		//img_start = X393__BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
		img_start = get_image_start_chn(last_image_chunk, len32, chn);
		read_ptr = img_start;
		if (read_ptr > prev_ptr)
			nz--;
@@ -524,7 +591,9 @@ void dump_state(unsigned int chn)
 * @param[in]   orig   where the @e offset should start
 * @return      Current file pointer position if operation was successful and error code otherwise
 */
loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
#ifdef PRE_FRAMEPARS

loff_t circbuf_lseek_0(struct file *file, loff_t offset, int orig)
{
	unsigned int len32 = 0;
	int last_image_chunk;
@@ -541,15 +610,20 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
		file->f_pos = offset;
		break;
	case SEEK_CUR:
	    // New in NC393
//        if (offset == 0) return get_compressor_frame(chn);   // do not modify frame number

        if (offset) file->f_pos += offset;
		else if (circbuf_valid_ptr(&file->f_pos, &fp, chn) < 0 ) return -EINVAL; // no frames at the specified location or pointer is not 32-byte aligned
		break;
	case SEEK_END:
		if (offset <= 0) {
			file->f_pos = CCAM_DMA_SIZE + offset;
			file->f_pos = circbuf_priv[chn].buf_size + offset; // CCAM__DMA_SIZE
		} else {
			// verify current frame pointer
			switch (offset) {
			case LSEEK_CIRC_GETFRAME:
			    return get_compressor_frame(chn);   // New in NC393
			case LSEEK_CIRC_TORP:
				file->f_pos = camseq_get_jpeg_rp(chn) << 2;
			case LSEEK_CIRC_PREV:
@@ -578,11 +652,11 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
			case LSEEK_CIRC_FREE:
				dev_dbg(g_dev_ptr, "[chn %u] LSEEK_CIRC_FREE: checking remaining memory in circbuf\n", chn);
				bp = file->f_pos - (camseq_get_jpeg_wp(chn) << 2);
				return (file->f_pos = (bp > 0) ? bp : (bp + CCAM_DMA_SIZE)); // Has a side effect of moving a file pointer!
				return (file->f_pos = (bp > 0) ? bp : (bp + circbuf_priv[chn].buf_size)); //CCAM__DMA_SIZE)); // Has a side effect of moving a file pointer!
			case LSEEK_CIRC_USED:
				dev_dbg(g_dev_ptr, "[chn %u] LSEEK_CIRC_USED: checking used memory in circbuf\n", chn);
				bp = (camseq_get_jpeg_wp(chn) << 2) - file->f_pos;
				return (file->f_pos = (bp > 0) ? bp : (bp + CCAM_DMA_SIZE)); // Has a side effect of moving a file pointer!
				return (file->f_pos = (bp > 0) ? bp : (bp + circbuf_priv[chn].buf_size)); // CCAM__DMA_SIZE)); // Has a side effect of moving a file pointer!
			case LSEEK_CIRC_TORP:
				// no actions to be done here, the pointer was set on previous step
				break;
@@ -603,8 +677,8 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
					return -EOVERFLOW;
				}
				len32 &= FRAME_LENGTH_MASK;
				//img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
				img_start = get_image_start(last_image_chunk, len32);
				//img_start = X393__BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
				img_start = get_image_start_chn(last_image_chunk, len32,chn);
				dev_dbg(g_dev_ptr, "[chn %u] calculated start address = 0x%x, length = 0x%x\n", chn, img_start, len32);
				if (circbuf_valid_ptr(&img_start, &fp, chn) < 0)
					return -EOVERFLOW;
@@ -626,8 +700,8 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
					return -EOVERFLOW;
				}
				len32 &= FRAME_LENGTH_MASK;
				//img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
				img_start = get_image_start(last_image_chunk, len32);
				//img_start = X393__BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
				img_start = get_image_start_chn(last_image_chunk, len32, chn);
				dev_dbg(g_dev_ptr, "[chn %u] LSEEK_CIRC_PREV: calculated start address = 0x%x, length = 0x%x\n", chn, img_start, len32);

				// move file pointer only if previous frame valid
@@ -647,7 +721,7 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
				}
				// calculate the full length of current frame and advance file pointer by this value
				padded_frame = fp->frame_length + INSERTED_BYTES(fp->frame_length) + CHUNK_SIZE + CCAM_MMAP_META;
				file->f_pos = X393_BUFFADD(file->f_pos, padded_frame); // do it even if the next frame does not yet exist
				file->f_pos = X393_BUFFADD_CHN(file->f_pos, padded_frame, chn); // do it even if the next frame does not yet exist
				dev_dbg(g_dev_ptr, "[chn %u] LSEEK_CIRC_NEXT: padded_frame = %d; moving file->f_pos to 0x%llx\n", chn, padded_frame, file->f_pos);
				break;
			case LSEEK_CIRC_FIRST:
@@ -672,8 +746,8 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
					if ((len32 & MARKER_FF) != MARKER_FF ) break;  // no frames before rp (==prev_p)
					// move rp to the previous frame
					len32 &= FRAME_LENGTH_MASK;
					//img_start = X393_BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
					img_start = get_image_start(last_image_chunk, len32);
					//img_start = X393__BUFFSUB(last_image_chunk + CHUNK_SIZE - INSERTED_BYTES(len32) - CCAM_MMAP_META, len32);
					img_start = get_image_start_chn(last_image_chunk, len32, chn);
					dev_dbg(g_dev_ptr, "[chn %u] LSEEK_CIRC_FIRST or LSEEK_CIRC_SCND: calculated start address = 0x%x, length = 0x%x\n", chn,
							img_start, len32);
					rp_b = img_start;
@@ -730,17 +804,166 @@ loff_t circbuf_lseek(struct file *file, loff_t offset, int orig)
		return -EINVAL;
	}
	// roll-over position
	while (file->f_pos < 0) file->f_pos += CCAM_DMA_SIZE;
	while (file->f_pos > CCAM_DMA_SIZE) file->f_pos -= CCAM_DMA_SIZE;
	if ((orig !=SEEK_END) && (file->f_pos == CCAM_DMA_SIZE)) file->f_pos=0; // only for lseek(fd,0,SEEK_END) the result will be file size, others will roll to 0
	while (file->f_pos < 0) file->f_pos += circbuf_priv[chn].buf_size; // CCAM__DMA_SIZE;
	while (file->f_pos > circbuf_priv[chn].buf_size) file->f_pos -= circbuf_priv[chn].buf_size; // CCAM__DMA_SIZE;
	if ((orig !=SEEK_END) && (file->f_pos == circbuf_priv[chn].buf_size)) file->f_pos=0; // only for lseek(fd,0,SEEK_END) the result will be file size, others will roll to 0
	dev_dbg(g_dev_ptr, "[chn %u] return file->f_pos = %lld\n", chn, file->f_pos);
	return  file->f_pos ;
}
#endif
//Restoring from NC353

loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
 //  orig 0: position from begning
 //  orig 1: relative from current
 //  orig 2: position from last  address
   int l = (CCAM_DMA_SIZE << 2);
   int fl=0;// frame length
   struct interframe_params_t * fp;
   int fvld=-1;
   int rp, bp, prev_p, preprev_p; //, p;
   int nf;   //! number of frames;
   int nz=1; //! number of crossing of start of the circular buffer (counter to prevent looping forever)
   unsigned int minor = MINOR(file->f_inode->i_rdev);
   unsigned int chn = minor_to_chn(minor, NULL);
//MD12(int dbg_i);
//   int pf; // previous frame
   dev_dbg(g_dev_ptr, "circbuf_lseek, offset=0x%x, orig=0x%x\n",(int) offset, (int) orig);
   switch(orig) {
   case SEEK_SET:
     file->f_pos = offset;
     break;
   case SEEK_CUR:
     if (offset) file->f_pos += offset;
     else if (circbufValidPointer(file->f_pos, &fp, chn) <0 ) return -EINVAL; //!no frames at the specified location or pointer is not 32-byte aligned
     break;
   case SEEK_END:
     if (offset <= 0) {
        file->f_pos = l + offset;
     } else { //! New functionality
//!verify the frame pointer
        switch (offset) {
          case LSEEK_CIRC_TORP:
              file->f_pos=camSeqGetJPEG_rp(chn)<<2; //! set file pointer to global read pointer, and precoeed
          case LSEEK_CIRC_PREV:
          case LSEEK_CIRC_NEXT:
          case LSEEK_CIRC_SETP:
          case LSEEK_CIRC_VALID:
          case LSEEK_CIRC_READY:
          case LSEEK_CIRC_FREE:
          case LSEEK_CIRC_USED:
             if (((fvld=circbufValidPointer(file->f_pos, &fp, chn))) <0 )
                return -EINVAL; //!no frames at the specified location
        }
        switch (offset) {
        case LSEEK_CIRC_GETFRAME:
            return get_compressor_frame(chn);   // New in NC393
          case LSEEK_CIRC_FREE:
             bp=(file->f_pos - (camSeqGetJPEG_wp(chn)<<2));
//             return (bp>0)?bp:(bp+l); //!will return full buffer size if current pointer is a write pointer (waiting for the next frame)
             return (file->f_pos=(bp>0)?bp:(bp+l)); //!Has a side effect of moving a file pointer!
          case LSEEK_CIRC_USED:
             bp=((camSeqGetJPEG_wp(chn)<<2) - file->f_pos);
//             return (bp>=0)?bp:(bp+l); //!will return 0 if current pointer is a write pointer (waiting for the next frame)
             return (file->f_pos=(bp>0)?bp:(bp+l)); //!Has a side effect of moving a file pointer!
          case LSEEK_CIRC_TORP:
             break;
          case LSEEK_CIRC_TOWP:
             file->f_pos=camSeqGetJPEG_wp(chn)<<2; // no checking if it is valid
             break;
          case LSEEK_CIRC_LAST:
             file->f_pos=camSeqGetJPEG_wp(chn)<<2;
             fvld=circbufValidPointer(file->f_pos, &fp, chn); //!set fp
          case LSEEK_CIRC_PREV:
             rp= file->f_pos >> 2;
             fl=circbuf_priv[chn].buf_ptr[X393_BUFFSUB32(rp, 9, chn)] ^ X313_LENGTH_MASK;
             dev_dbg(g_dev_ptr, "LSEEK_CIRC_PREV: rp=0x%x, fvld=%d, fl=0x%x\n", rp, fvld,fl);
             if (fl & X313_LENGTH_MASK) {
                if (offset==LSEEK_CIRC_LAST) break; // just don't move pointer, leave it at write pointer and return no error
                return -EOVERFLOW; //! no frames before current
             }
             bp = (X393_BUFFSUB32(rp, X313_PADDED_FRAME(fl),chn)<<2); // in bytes
             dev_dbg(g_dev_ptr, "LSEEK_CIRC_PREV: bp=0x%x (0x%x), circbufValidPointer=%d\n", bp, bp>>2,circbufValidPointer(rp>>2, &fp,chn));
             if (circbufValidPointer(bp, &fp, chn) < 0 ) { //! no valid frames before current
                if (offset==LSEEK_CIRC_LAST) break; // just don't move pointer, leave it at write pointer and return no error
                return -EOVERFLOW; //! no frames before current
             }
 //! move frame pointer only if there is a valid frame there
             file->f_pos=bp;
             break;
          case LSEEK_CIRC_NEXT:
              dev_dbg(g_dev_ptr, "LSEEK_CIRC_NEXT: rp=0x%llx, fvld=%d, fp->timestamp_sec=0x%lx\n", file->f_pos >> 2, fvld, fp->timestamp_sec);
             if (fvld <=0)
                return -EOVERFLOW; //! no frames after current
             file->f_pos = X393_BUFFADD32(file->f_pos >> 2, X313_PADDED_FRAME(fp->timestamp_sec),chn) <<2 ;// do it even if the next frame does not yet exist
             break;
          case LSEEK_CIRC_FIRST:
          case LSEEK_CIRC_SCND:
//! Starting from the write pointer do be able to count all the frames in the buffer
             rp=camSeqGetJPEG_wp(chn);
             prev_p=rp;
             preprev_p=prev_p; // for second
             nf=0;
             nz=1;
             file->f_pos=rp<<2;
             while ((((fvld=circbufValidPointer(rp<<2, &fp, chn))) >= 0) & (nz>=0)) {
               nf++;
//               file->f_pos=rp<<2;
               preprev_p=prev_p; //! second known good (at least first one)
               prev_p=rp;        //!now - current, known good
               fl=circbuf_priv[chn].buf_ptr[X393_BUFFSUB32(rp, 9, chn)] ^ X313_LENGTH_MASK;
               dev_dbg(g_dev_ptr, "\nf=%d, rp=0x%x, fvld=%d, fl=0x%x\n",nf, rp, fvld, fl);
               if (fl & X313_LENGTH_MASK) break;  //! no frames before rp (==prev_p)
//! move rp to the previous frame
               rp= X393_BUFFSUB32(rp, X313_PADDED_FRAME(fl),chn);
               if (rp > prev_p) nz-- ; // rolled through zero - make sure we'll not stuck in this loop forever
             }

             dev_dbg(g_dev_ptr, "after while{}: nf=%d, rp=0x%x, fvld=%d, fl=0x%x\n",nf, rp, fvld, fl);
             file->f_pos=((offset==LSEEK_CIRC_SCND)?preprev_p:prev_p) << 2;
             break;
          case LSEEK_CIRC_SETP:
              camSeqSetJPEG_rp(chn, file->f_pos>>2);
             break;
          case LSEEK_CIRC_VALID:
             break;
          case LSEEK_CIRC_READY:
             if (fvld <=0) return -EINVAL; //! no frame is available better code?
             break;
          case LSEEK_CIRC_WAIT:
              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(chn)<<2)!=file->f_pos);
              }
              if (fvld < 0) return -ESPIPE;      //!invalid seek - have better code?
              return file->f_pos ; //! data already available, return file pointer
          default:
            if ((offset & ~0x1f)==LSEEK_DAEMON_CIRCBUF) {
              wait_event_interruptible (circbuf_wait_queue, get_imageParamsThis(chn, P_DAEMON_EN) & (1<<(offset & 0x1f)));
            }
        }
        dev_dbg(g_dev_ptr, "return SEEK_END file->f_pos =0x%08llx\n",file->f_pos);
        return ( file->f_pos ); //! file position >=0
     }
     break;
   default:
      return -EINVAL;
   }
   // roll-over position
   while (file->f_pos < 0) file->f_pos+=l;
   while (file->f_pos > l) file->f_pos-=l;
   if ((orig !=SEEK_END) && (file->f_pos == l)) file->f_pos=0; //!only for lseek (fd,0,SEEK_END) the result will be file size, others will roll to 0
   dev_dbg(g_dev_ptr, "return file->f_pos =0x%08llx\n",file->f_pos);
   return  file->f_pos ;
}



#ifdef PRE_FRAMEPARS
    unsigned short circbuf_quality = 100;
    unsigned short circbuf_height = 1936;
    unsigned short circbuf_width = 2592;
    unsigned char circbuf_byrshift = 3;
#endif
/**
 * @brief This function handles write operations for circbuf files.
 * @note Never use @e file->f_pos in this function.
@@ -762,6 +985,7 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
	dev_dbg(g_dev_ptr, "minor = 0x%x, count = 0x%x, off = 0x%llx", minor, count, off);

	/* debug code follows*/
#ifdef PRE_FRAMEPARS
	switch (buf[0] - 0x30) {
	case 0:
		compressor_interrupts(0,chn);
@@ -831,12 +1055,12 @@ ssize_t circbuf_write(struct file *file, const char *buf, size_t count, loff_t *
		break;
	}
	/* debug code end */

#endif
	p = *off;
	if (p >= CCAM_DMA_SIZE)
		p = CCAM_DMA_SIZE;
	if ((p + count) > CCAM_DMA_SIZE)
		count = CCAM_DMA_SIZE - p;
	if (p >= circbuf_priv[chn].buf_size) //CCAM__DMA_SIZE)
		p = circbuf_priv[chn].buf_size; // CCAM__DMA_SIZE;
	if ((p + count) > circbuf_priv[chn].buf_size) // CCAM_-MA_SIZE)
		count = circbuf_priv[chn].buf_size-p; // CCAM__DMA_SIZE - p;
	if (count) {
		if (copy_from_user(&circbuf_priv[chn].buf_ptr[BYTE2DW(p)], buf, count))
			return -EFAULT;
@@ -862,10 +1086,10 @@ ssize_t circbuf_read(struct file *file, char *buf, size_t count, loff_t *off)
	dev_dbg(g_dev_ptr, "minor = 0x%x, count = 0x%x, off = 0x%llx", minor, count, off);

	p = *off;
	if (p >= CCAM_DMA_SIZE)
		p = CCAM_DMA_SIZE;
	if ((p + count) > CCAM_DMA_SIZE)
		count = CCAM_DMA_SIZE - p;
	if (p >= circbuf_priv[chn].buf_size) // CCAM__DMA_SIZE)
		p = circbuf_priv[chn].buf_size; // CCAM__DMA_SIZE;
	if ((p + count) > circbuf_priv[chn].buf_size) // CCAM__DMA_SIZE)
		count = circbuf_priv[chn].buf_size - p; // CCAM__DMA_SIZE - p;
	if (count) {
		if (copy_to_user(buf, &circbuf_priv[chn].buf_ptr[BYTE2DW(p)], count))
			return -EFAULT;
+3 −0
Original line number Diff line number Diff line
@@ -28,8 +28,11 @@
struct circbuf_priv_t {
	int                 minor;                             ///< device file minor number
	unsigned long       *buf_ptr;                          ///< pointer to circular buffer memory region
	unsigned long       buf_size;                          ///< circular region size in bytes
    unsigned long       buf_size32;                        ///< circular region size in dwords
	dma_addr_t          phys_addr;                         ///< physical address of memory region reported by memory driver
};
struct  circbuf_priv_t *get_circbuf(int chn); // alternative to use of extern struct circbuf_priv_ptr;
extern struct circbuf_priv_t *circbuf_priv_ptr;
extern wait_queue_head_t circbuf_wait_queue;

Loading