Commit 8e54e384 authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: update LSEEK_CIRC_LAST handler

parent e23e383a
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
* -----------------------------------------------------------------------------** * -----------------------------------------------------------------------------**
*/ */
#define DEBUG 1
#include <linux/device.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sched.h> #include <linux/sched.h>
...@@ -68,32 +71,19 @@ ...@@ -68,32 +71,19 @@
#include "x393_macro.h" #include "x393_macro.h"
#include "x393.h" #include "x393.h"
#if ELPHEL_DEBUG
#define MDF(x) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__);x ;}
#define D19(x) { if (GLOBALPARS(G_DEBUG) & (1 <<19)) {x; } ; }
#define MDF19(x) { if (GLOBALPARS(G_DEBUG) & (1 <<19)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;} }
#define D20(x) { if (GLOBALPARS(G_DEBUG) & (1 <<20)) {x; } ; }
#define MDF20(x) { if (GLOBALPARS(G_DEBUG) & (1 <<20)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;} }
#else
#define MDF(x)
#define D19(x)
#define MDF19(x)
#define D20(x)
#define MDF20(x)
#endif
#define MD12(x)
#define D(x)
//#define MD7(x) printk("%s:%d:",__FILE__,__LINE__);x
#define MD7(x)
//#define MD10(x) printk("%s:%d:",__FILE__,__LINE__);x //#define MD10(x) printk("%s:%d:",__FILE__,__LINE__);x
#define MD10(x) #define MD10(x)
//#define MD11(x) printk("%s:%d:",__FILE__,__LINE__);x //#define MD11(x) printk("%s:%d:",__FILE__,__LINE__);x
#define MD11(x) #define MD11(x)
// private data
struct circbuf_priv_t {
int minor;
unsigned long *buf_ptr;
dma_addr_t phys_addr;
};
static struct circbuf_priv_t circbuf_priv[IMAGE_CHN_NUM];
static const struct of_device_id elphel393_circbuf_of_match[]; static const struct of_device_id elphel393_circbuf_of_match[];
/* really huge static DMA buffer (1288+8)*1032/3=445824 long-s */ /* really huge static DMA buffer (1288+8)*1032/3=445824 long-s */
// DMA_SIZE - in 32-bit words, not bytes // DMA_SIZE - in 32-bit words, not bytes
...@@ -104,14 +94,16 @@ unsigned long * ccam_dma_buf_ptr = NULL; ...@@ -104,14 +94,16 @@ unsigned long * ccam_dma_buf_ptr = NULL;
//EXPORT_SYMBOL_GPL(ccam_dma_buf_ptr); //EXPORT_SYMBOL_GPL(ccam_dma_buf_ptr);
//unsigned long * ccam_dma = NULL; //! still used in autoexposure or something - why is in needed there? //unsigned long * ccam_dma = NULL; //! still used in autoexposure or something - why is in needed there?
int init_ccam_dma_buf_ptr(struct platform_device *pdev) { int init_ccam_dma_buf_ptr(struct platform_device *pdev)
{
int i;
dma_addr_t dma_handle; dma_addr_t dma_handle;
const size_t dma_size = (CCAM_DMA_SIZE + (PAGE_SIZE >> 2)) * sizeof(int); const size_t dma_size = (CCAM_DMA_SIZE + (PAGE_SIZE >> 2)) * sizeof(int);
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
//ccam_dma_buf_ptr = ccam_dma_buf; //ccam_dma_buf_ptr = ccam_dma_buf;
//ccam_dma = ccam_dma_buf; //&ccam_dma_buf[0]; Use in autoexposure //ccam_dma = ccam_dma_buf; //&ccam_dma_buf[0]; Use in autoexposure
// use Elphel_buf if it was allocated // use Elphel_buf if it was allocated
if (pElphel_buf != NULL) { if (pElphel_buf != NULL) {
ccam_dma_buf_ptr = pElphel_buf->vaddr; ccam_dma_buf_ptr = pElphel_buf->vaddr;
dma_handle = pElphel_buf->paddr; dma_handle = pElphel_buf->paddr;
...@@ -130,8 +122,20 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev) { ...@@ -130,8 +122,20 @@ int init_ccam_dma_buf_ptr(struct platform_device *pdev) {
// 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);
return 0; 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].phys_addr = dma_handle + CIRCBUF_START_OFFSET + i * CCAM_DMA_SIZE;
}
return 0;
} }
static inline unsigned int minor_to_chn(int minor)
{
//return minor - CIRCBUF_MINOR_CHN_OFFSET;
return 0;
}
//extern struct interframe_params_t frame_params; // cc353.c //extern struct interframe_params_t frame_params; // cc353.c
/*!====================================================================================== /*!======================================================================================
*! Wait queue for the processes waiting for a new frame to appear in the circular buffer *! Wait queue for the processes waiting for a new frame to appear in the circular buffer
...@@ -155,26 +159,32 @@ struct circbuf_pd { ...@@ -155,26 +159,32 @@ struct circbuf_pd {
struct wait_queue *circbuf_wait_queue; ///NOTE: not used at all? struct wait_queue *circbuf_wait_queue; ///NOTE: not used at all?
// something else to be added here? // something else to be added here?
}; };
// CMOSCAM_MINOR_HUFFMAN // huffman tables R/W // CMOSCAM_MINOR_HUFFMAN // huffman tables R/W
int circbuf_all_open(struct inode *inode, struct file *filp) { int circbuf_all_open(struct inode *inode, struct file *filp)
int res; {
MD10(printk("circbuf_all_open, minor=0x%x\n",MINOR(inode->i_rdev))); int res;
switch (MINOR(inode->i_rdev)) { int minor = MINOR(inode->i_rdev);
case CMOSCAM_MINOR_CIRCBUF : dev_dbg(NULL, "circbuf_all_open, minor = 0x%x\n", minor);
res=circbuf_open(inode,filp);
break; switch (MINOR(inode->i_rdev)) {
case CMOSCAM_MINOR_JPEAGHEAD : case CMOSCAM_MINOR_CIRCBUF :
res=jpeghead_open(inode,filp); res=circbuf_open(inode,filp);
break; break;
case CMOSCAM_MINOR_HUFFMAN : case CMOSCAM_MINOR_JPEAGHEAD :
res=huffman_open(inode,filp); res=jpeghead_open(inode,filp);
break; break;
default: case CMOSCAM_MINOR_HUFFMAN :
// kfree(filp->private_data); // already allocated res=huffman_open(inode,filp);
return -EINVAL; break;
} default:
return res; // kfree(filp->private_data); // already allocated
return -EINVAL;
}
return res;
} }
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);
...@@ -196,24 +206,30 @@ int circbuf_all_release(struct inode *inode, struct file *filp) { ...@@ -196,24 +206,30 @@ int circbuf_all_release(struct inode *inode, struct file *filp) {
return res; return res;
} }
loff_t circbuf_all_lseek(struct file * file, loff_t offset, int orig) { loff_t circbuf_all_lseek(struct file * file, loff_t offset, int orig)
struct circbuf_pd * privData; {
privData = (struct circbuf_pd *) file->private_data; struct circbuf_pd * privData;
struct interframe_params_t *fp = NULL; privData = (struct circbuf_pd *) file->private_data;
int rp; struct interframe_params_t *fp = NULL;
int rp;
MD10(printk("circbuf_all_lseek, minor=0x%x\n",privData-> minor)); int minor = privData->minor;
switch (privData->minor) {
case CMOSCAM_MINOR_CIRCBUF : return circbuf_lseek (file, offset, orig); dev_dbg(NULL, "circbuf_all_lseek, minor = 0x%x\n", minor);
case CMOSCAM_MINOR_JPEAGHEAD : switch (minor) {
if (orig == SEEK_END && offset > 0) { case CMOSCAM_MINOR_CIRCBUF :
rp= (offset >>2) & (~7); // convert to index to long, align to 32-bytes return circbuf_lseek(file, offset, orig);
fp = (struct interframe_params_t *) &ccam_dma_buf_ptr[X313_BUFFSUB(rp, 8)]; //! 32 bytes before the frame pointer, may roll-over to the end of ccam_dma_buf_ptr case CMOSCAM_MINOR_JPEAGHEAD :
} if (orig == SEEK_END && offset > 0) {
return jpeghead_lseek (file, offset, orig, fp); rp = BYTE2DW(offset) & (~7); // convert to index to long, align to 32-bytes
case CMOSCAM_MINOR_HUFFMAN : return huffman_lseek (file, offset, orig); //fp = (struct interframe_params_t *) &ccam_dma_buf_ptr[X313_BUFFSUB(rp, 8)]; //! 32 bytes before the frame pointer, may roll-over to the end of ccam_dma_buf_ptr
default: return -EINVAL; fp = (struct interframe_params_t *) &circbuf_priv[minor_to_chn(minor)].buf_ptr[X313_BUFFSUB(rp, 8)];
} }
return jpeghead_lseek(file, offset, orig, fp);
case CMOSCAM_MINOR_HUFFMAN :
return huffman_lseek(file, offset, orig);
default:
return -EINVAL;
}
} }
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) {
...@@ -331,36 +347,94 @@ int circbuf_open(struct inode *inode, struct file *filp) { // set filesize ...@@ -331,36 +347,94 @@ int circbuf_open(struct inode *inode, struct file *filp) { // set filesize
//! returns -1 if there is no frame at this index //! returns -1 if there is no frame at this index
//! returns -2 if the rp is not 32-bytes aligned //! returns -2 if the rp is not 32-bytes aligned
//!sets *fpp to the frame header, including signature and length //!sets *fpp to the frame header, including signature and length
int circbufValidPointer(int rp, struct interframe_params_t ** fpp) {
if (rp & 0x1f) { //!rp is not 32-bytes aligned
MD10(printk("circbufValidPointer: misaligned pointer\n"));
return -2;
}
int wp=camSeqGetJPEG_wp();
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:")); unsigned long get_image_length(int offset, unsigned int chn, int *last_chunk_offset)
{
unsigned long len32;
int last_image_chunk = DW2BYTE(offset) - OFFSET_X40;
if (last_image_chunk < 0)
last_image_chunk += CCAM_DMA_SIZE;
len32 = circbuf_priv[chn].buf_ptr[BYTE2DW(last_image_chunk + (CHUNK_SIZE - CCAM_MMAP_META_LENGTH))];
if (last_chunk_offset != NULL)
*last_chunk_offset = last_image_chunk;
*fpp=fp; return len32;
MD11(printk("p=0x%x , wp==0x%x\n",p,wp)); }
if (p == wp) {
return 0; // frame not yet acquired, fp - not valid int circbufValidPointer(int rp, struct interframe_params_t ** fpp, unsigned int chn)
} {
if (fp->signffff != 0xffff) { //! signature is overwritten int last_image_chunk;
MD10(printk("circbufValidPointer: signanure overwritten\n")); unsigned int sec;
return -1; unsigned int usec;
} int wp = camseq_get_jpeg_wp(chn);
if ((fp->timestamp_sec) & X313_LENGTH_MASK) { unsigned int len32 = get_image_length(wp, chn, &last_image_chunk);
MDF(printk ("Should not get here - fp->timestamp_sec=0x%x\n",(int) fp->timestamp_sec)); struct interframe_params_t *fp;
return 0; //! should not get here - should be caught by (p==wp) int p = BYTE2DW(rp);
}
return 1; if (rp & 0x1f) { //!rp is not 32-bytes aligned
//MD10(printk("circbufValidPointer: misaligned pointer\n"));
dev_dbg(NULL, "misaligned pointer rp = 0x%x for channel %d\n", rp, chn);
return -2;
}
fp = (struct interframe_params_t *) &circbuf_priv[chn].buf_ptr[X313_BUFFSUB(p, INTERFRAME_PARAMS_SZ)];
*fpp = 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(NULL, "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(NULL, "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(NULL, "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(NULL, "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)
// frame not yet acquired (?)
return 0;
dev_dbg(NULL, "checking end of frame marker len32 = 0x%x at offset = 0x%x\n", len32, DW2BYTE(wp));
if ((len32 >> 24) != MARKER_FF) {
wp -= CHUNK_SIZE;
len32 = get_image_length(wp, chn, &last_image_chunk);
if ((len32 >> 24) != MARKER_FF) {
dev_dbg(NULL, "failed to get marker 0xFF at CORRECTED offset\n");
return -1;
}
}
// check timestamp
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))];
dev_dbg(NULL, "reading time stamp: sec = 0x%x, usec = 0x%x\n", sec, usec);
return 1;
} }
loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) { loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
unsigned int len32;
int inserted_bytes;
int last_image_chunk;
int img_start, next_img;
const int ADJUSTMENT = 4; // this constant comes from python code x393_cmprs_afi.py
unsigned int minor = MINOR(file->f_inode->i_rdev);
unsigned int chn = minor_to_chn(minor);
// orig 0: position from begning // orig 0: position from begning
// orig 1: relative from current // orig 1: relative from current
// orig 2: position from last address // orig 2: position from last address
...@@ -371,7 +445,6 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) { ...@@ -371,7 +445,6 @@ loff_t circbuf_lseek(struct file * file, loff_t offset, int orig) {
int rp, bp, prev_p, preprev_p; //, p; int rp, bp, prev_p, preprev_p; //, p;
int nf; //! number of frames; int nf; //! number of frames;
int nz=1; //! number of crossing of start of the circular buffer (counter to prevent looping forever) int nz=1; //! number of crossing of start of the circular buffer (counter to prevent looping forever)
MD12(int dbg_i);
// int pf; // previous frame // int pf; // previous frame
MD11(printk("circbuf_lseek, offset=0x%x, orig=0x%x\n",(int) offset, (int) orig)); MD11(printk("circbuf_lseek, offset=0x%x, orig=0x%x\n",(int) offset, (int) orig));
switch(orig) { switch(orig) {
...@@ -380,7 +453,7 @@ MD12(int dbg_i); ...@@ -380,7 +453,7 @@ MD12(int dbg_i);
break; break;
case SEEK_CUR: case SEEK_CUR:
if (offset) file->f_pos += offset; if (offset) file->f_pos += offset;
else if (circbufValidPointer(file->f_pos, &fp) <0 ) return -EINVAL; //!no frames at the specified location or pointer is not 32-byte aligned 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; break;
case SEEK_END: case SEEK_END:
if (offset <= 0) { if (offset <= 0) {
...@@ -389,7 +462,8 @@ MD12(int dbg_i); ...@@ -389,7 +462,8 @@ MD12(int dbg_i);
//!verify the frame pointer //!verify the frame pointer
switch (offset) { switch (offset) {
case LSEEK_CIRC_TORP: case LSEEK_CIRC_TORP:
file->f_pos=camSeqGetJPEG_rp()<<2; //! set file pointer to global read pointer, and proceed //file->f_pos=camSeqGetJPEG_rp()<<2; //! set file pointer to global read pointer, and proceed
file->f_pos = camseq_get_jpeg_rp(chn) << 2;
case LSEEK_CIRC_PREV: case LSEEK_CIRC_PREV:
case LSEEK_CIRC_NEXT: case LSEEK_CIRC_NEXT:
case LSEEK_CIRC_SETP: case LSEEK_CIRC_SETP:
...@@ -397,43 +471,68 @@ MD12(int dbg_i); ...@@ -397,43 +471,68 @@ MD12(int dbg_i);
case LSEEK_CIRC_READY: case LSEEK_CIRC_READY:
case LSEEK_CIRC_FREE: case LSEEK_CIRC_FREE:
case LSEEK_CIRC_USED: case LSEEK_CIRC_USED:
if (((fvld=circbufValidPointer(file->f_pos, &fp))) <0 ) if (((fvld=circbufValidPointer(file->f_pos, &fp, chn))) <0 )
return -EINVAL; //!no frames at the specified location return -EINVAL; //!no frames at the specified location
} }
switch (offset) { switch (offset) {
case LSEEK_CIRC_FREE: case LSEEK_CIRC_FREE:
bp=(file->f_pos - (camSeqGetJPEG_wp()<<2)); //bp=(file->f_pos - (camSeqGetJPEG_wp()<<2));
bp = file->f_pos - (camseq_get_jpeg_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 (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! 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:
bp=((camSeqGetJPEG_wp()<<2) - file->f_pos); //bp=((camSeqGetJPEG_wp()<<2) - file->f_pos);
bp = (camseq_get_jpeg_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 (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! 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:
break; break;
case LSEEK_CIRC_TOWP: case LSEEK_CIRC_TOWP:
file->f_pos=camSeqGetJPEG_wp()<<2; // no checking if it is valid //file->f_pos=camSeqGetJPEG_wp()<<2; // no checking if it is valid
file->f_pos = camseq_get_jpeg_wp(chn) << 2;
break; break;
case LSEEK_CIRC_LAST: case LSEEK_CIRC_LAST:
file->f_pos=camSeqGetJPEG_wp()<<2; next_img = camseq_get_jpeg_wp(chn) << 2;
fvld=circbufValidPointer(file->f_pos, &fp); //!set fp fvld=circbufValidPointer(next_img, &fp, chn);
if (fvld < 0)
return -EOVERFLOW;
dev_dbg(NULL, "LSEEK_CIRC_LAST: next_img = 0x%x, fvld = %d\n", next_img, fvld);
dev_dbg(NULL, "0x40 bytes of mem dump\n");
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, &last_image_chunk);
if ((len32 >> 24) & 0xff != MARKER_FF) {
// we should not be here as the position was checked in circbufValidPointer
dev_dbg(NULL, "read pointer: 0x%x, len32: 0x%x\n", DW2BYTE(rp), len32);
return -EOVERFLOW;
}
len32 &= 0xffffff;
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;
dev_dbg(NULL, "calculated start address = 0x%x, length = 0x%x\n", img_start, len32);
file->f_pos = img_start;
break;
case LSEEK_CIRC_PREV: case LSEEK_CIRC_PREV:
rp= file->f_pos >> 2; rp= file->f_pos >> 2;
fl=ccam_dma_buf[X313_BUFFSUB(rp, 9)] ^ X313_LENGTH_MASK; fl=ccam_dma_buf[X313_BUFFSUB(rp, 9)] ^ X313_LENGTH_MASK;
MD11(printk("LSEEK_CIRC_PREV: rp=0x%x, fvld=%d, fl=0x%x\n", rp, fvld,fl)); //fl = circbuf_priv[minor_to_chn(minor)].buf_ptr[X313_BUFFSUB(rp, 9)] ^ X313_LENGTH_MASK;
if (fl & X313_LENGTH_MASK) { //MD11(printk("LSEEK_CIRC_PREV: rp=0x%x, fvld=%d, fl=0x%x\n", rp, fvld,fl));
if (offset==LSEEK_CIRC_LAST) break; // just don't move pointer, leave it at write pointer and return no error dev_dbg(NULL, "LSEEK_CIRC_PREV: rp=0x%x, fvld=%d, fl=0x%x\n", BYTE2DW(rp), fvld, fl);
return -EOVERFLOW; //! no frames before current 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
bp = (X313_BUFFSUB(rp, X313_PADDED_FRAME(fl))<<2); // in bytes return -EOVERFLOW; //! no frames before current
MD11(printk("LSEEK_CIRC_PREV: bp=0x%x (0x%x), circbufValidPointer=%d\n", bp, bp>>2,circbufValidPointer(rp>>2, &fp))); }
if (circbufValidPointer(bp, &fp) < 0 ) { //! no valid frames before current bp = (X313_BUFFSUB(rp, X313_PADDED_FRAME(fl))<<2); // in bytes
if (offset==LSEEK_CIRC_LAST) break; // just don't move pointer, leave it at write pointer and return no error //MD11(printk("LSEEK_CIRC_PREV: bp=0x%x (0x%x), circbufValidPointer=%d\n", bp, bp>>2,circbufValidPointer(rp>>2, &fp, chn)));
return -EOVERFLOW; //! no frames before current 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
//! move frame pointer only if there is a valid frame there return -EOVERFLOW; //! no frames before current
file->f_pos=bp; }
break;
//! move frame pointer only if there is a valid frame there
file->f_pos = bp;
break;
case LSEEK_CIRC_NEXT: case LSEEK_CIRC_NEXT:
MD11(printk("LSEEK_CIRC_NEXT: rp=0x%x, fvld=%d, fp->timestamp_sec=0x%x\n", file->f_pos >> 2, fvld, fp->timestamp_sec)); MD11(printk("LSEEK_CIRC_NEXT: rp=0x%x, fvld=%d, fp->timestamp_sec=0x%x\n", file->f_pos >> 2, fvld, fp->timestamp_sec));
if (fvld <=0) if (fvld <=0)
...@@ -443,13 +542,14 @@ MD12(int dbg_i); ...@@ -443,13 +542,14 @@ MD12(int dbg_i);
case LSEEK_CIRC_FIRST: case LSEEK_CIRC_FIRST:
case LSEEK_CIRC_SCND: case LSEEK_CIRC_SCND:
//! Starting from the write pointer do be able to count all the frames in the buffer //! Starting from the write pointer do be able to count all the frames in the buffer
rp=camSeqGetJPEG_wp(); //rp=camSeqGetJPEG_wp();
rp = camseq_get_jpeg_wp(chn);
prev_p=rp; prev_p=rp;
preprev_p=prev_p; // for second preprev_p=prev_p; // for second
nf=0; nf=0;
nz=1; nz=1;
file->f_pos=rp<<2; file->f_pos=rp<<2;
while ((((fvld=circbufValidPointer(rp<<2, &fp))) >= 0) & (nz>=0)) { while ((((fvld=circbufValidPointer(rp<<2, &fp, chn))) >= 0) & (nz>=0)) {
nf++; nf++;
// file->f_pos=rp<<2; // file->f_pos=rp<<2;
preprev_p=prev_p; //! second known good (at least first one) preprev_p=prev_p; //! second known good (at least first one)
...@@ -466,7 +566,8 @@ MD12(int dbg_i); ...@@ -466,7 +566,8 @@ MD12(int dbg_i);
file->f_pos=((offset==LSEEK_CIRC_SCND)?preprev_p:prev_p) << 2; file->f_pos=((offset==LSEEK_CIRC_SCND)?preprev_p:prev_p) << 2;
break; break;
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);
break; break;
case LSEEK_CIRC_VALID: case LSEEK_CIRC_VALID:
break; break;
...@@ -474,8 +575,9 @@ MD12(int dbg_i); ...@@ -474,8 +575,9 @@ MD12(int dbg_i);
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:
while (((fvld=circbufValidPointer(file->f_pos, &fp)))==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);
} }
if (fvld < 0) return -ESPIPE; //!invalid seek - have better code? if (fvld < 0) return -ESPIPE; //!invalid seek - have better code?
return file->f_pos ; //! data already available, return file pointer return file->f_pos ; //! data already available, return file pointer
...@@ -521,7 +623,7 @@ ssize_t circbuf_write(struct file * file, const char * buf, size_t count, loff_t ...@@ -521,7 +623,7 @@ ssize_t circbuf_write(struct file * file, const char * buf, size_t count, loff_t
} }
/* debug code end */ /* debug code end */
D(printk("circbuf_write\n")); //D(printk("circbuf_write\n"));
/// ************* NOTE: Never use file->f_pos in write() and read() !!! /// ************* NOTE: Never use file->f_pos in write() and read() !!!
p = *off; p = *off;
if(p >= (CCAM_DMA_SIZE << 2)) if(p >= (CCAM_DMA_SIZE << 2))
...@@ -550,9 +652,8 @@ ssize_t circbuf_read(struct file * file, char * buf, size_t count, loff_t *off) ...@@ -550,9 +652,8 @@ ssize_t circbuf_read(struct file * file, char * buf, size_t count, loff_t *off)
char * char_pb = (char *) ccam_dma_buf; char * char_pb = (char *) ccam_dma_buf;
struct circbuf_pd *priv = file->private_data; struct circbuf_pd *priv = file->private_data;
printk(KERN_DEBUG "%s\n", __func__);
p = *off; p = *off;
D(printk("circbuf_read pos=%d,count=%d, off=%d\r\n",p,count,off )); dev_dbg(NULL, "read from circbuf pos = %d, count = %d, off = %d\n", p, count, off);
if (p >= (CCAM_DMA_SIZE<<2)) p = (CCAM_DMA_SIZE<<2); if (p >= (CCAM_DMA_SIZE<<2)) p = (CCAM_DMA_SIZE<<2);
if( (p + count) > (CCAM_DMA_SIZE<<2)) { // truncate count if( (p + count) > (CCAM_DMA_SIZE<<2)) { // truncate count
count = (CCAM_DMA_SIZE<<2) - p; count = (CCAM_DMA_SIZE<<2) - p;
...@@ -565,28 +666,29 @@ ssize_t circbuf_read(struct file * file, char * buf, size_t count, loff_t *off) ...@@ -565,28 +666,29 @@ ssize_t circbuf_read(struct file * file, char * buf, size_t count, loff_t *off)
return count; return count;
} }
int circbuf_mmap (struct file *file, struct vm_area_struct *vma) { int circbuf_mmap(struct file *file, struct vm_area_struct *vma)
{
int rslt; int ret;
int chn = minor_to_chn(MINOR(file->f_inode->i_rdev));
MD7(printk("vm_start=%lx\r\n",vma->vm_start));
MD7(printk("vm_end=%lx\r\n",vma->vm_end)); dev_dbg(NULL, "vm_start = 0x%lx\n", vma->vm_start);
MD7(printk("vm_pgoff=%lx\r\n",vma->vm_pgoff)); dev_dbg(NULL, "vm_end = 0x%lx\n", vma->vm_end);
MD7(printk("vm_file=%lx\r\n",(unsigned long) (vma->vm_file))); dev_dbg(NULL, "vm_pgoff = 0x%lx\n", vma->vm_pgoff);
MD7(printk("ccam_dma_buf=%lx\r\n",(unsigned long) (virt_to_phys (&ccam_dma_buf[0])))); dev_dbg(NULL, "vm_file = 0x%lx\n", (unsigned long)vma->vm_file);
/* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ dev_dbg(NULL, "ccam_dma_buf = 0x%lx\n", (unsigned long)circbuf_priv[chn].phys_addr);
rslt=remap_pfn_range(vma,
vma->vm_start, /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */
// ((unsigned long)(&ccam_dma_buf[0])) >> PAGE_SHIFT, // Should be page-aligned ret = remap_pfn_range(vma,
((unsigned long) virt_to_phys(&ccam_dma_buf[0])) >> PAGE_SHIFT, // Should be page-aligned vma->vm_start,
vma->vm_end-vma->vm_start, //((unsigned long) virt_to_phys(&ccam_dma_buf[0])) >> PAGE_SHIFT, // Should be page-aligned
vma->vm_page_prot); circbuf_priv[chn].phys_addr >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
MD7(printk("remap_pfn_range returned=%x\r\n",rslt)); vma->vm_page_prot);
if (rslt) return -EAGAIN;
// vma->vm_ops = &simple_remap_vm_ops; dev_dbg(NULL, "remap_pfn_range returned 0x%x\n", ret);
// simple_vma_open(vma); if (ret) return -EAGAIN;
return 0;
return 0;
} }
/*!=========================================================================== /*!===========================================================================
*! If the current read pointer is invalid, circbuf_poll returns POLLHUP *! If the current read pointer is invalid, circbuf_poll returns POLLHUP
...@@ -594,25 +696,33 @@ int circbuf_mmap (struct file *file, struct vm_area_struct *vma) { ...@@ -594,25 +696,33 @@ int circbuf_mmap (struct file *file, struct vm_area_struct *vma) {
*! if it is valid, wait is setup and the blocking condition occurs *! if it is valid, wait is setup and the blocking condition occurs
*! ifthe current file pointer is equal to the FPGA write pointer *! ifthe current file pointer is equal to the FPGA write pointer
*!===========================================================================*/ *!===========================================================================*/
unsigned int circbuf_poll (struct file *file, poll_table *wait) { unsigned int circbuf_poll (struct file *file, poll_table *wait)
struct interframe_params_t * fp; {
struct circbuf_pd * privData; int w_ptr;
privData = (struct circbuf_pd *) file->private_data; unsigned int minor = MINOR(file->f_inode->i_rdev);
int rslt; //!result of testing read poinetr unsigned int chn = minor_to_chn(minor);
MD10(printk("circbuf_poll\n"));
rslt= circbufValidPointer(file->f_pos, &fp); struct interframe_params_t * fp;
if (rslt < 0) { //! not a valid read pointer, probable buffer overrun struct circbuf_pd * privData;
MD10(printk("circbuf_poll:invalid pointer\n")); privData = (struct circbuf_pd *) file->private_data;
return POLLHUP ; int rslt; //!result of testing read poinetr
} else if (rslt > 0) { MD10(printk("circbuf_poll\n"));
return POLLIN | POLLRDNORM; //! there was frame already available rslt= circbufValidPointer(file->f_pos, &fp, chn);
} else { //! pointer valid, no frame yet if (rslt < 0) { //! not a valid read pointer, probable buffer overrun
poll_wait(file, &circbuf_wait_queue, wait); MD10(printk("circbuf_poll:invalid pointer\n"));
//! Frame might become available during call to poll_wait so nobody will wake us up. return POLLHUP ;
//! Let's see if there is stillno frame } else if (rslt > 0) {
if ((camSeqGetJPEG_wp()<<2)!=file->f_pos) return POLLIN | POLLRDNORM; //! we are lucky - got it return POLLIN | POLLRDNORM; //! there was frame already available
} } else { //! pointer valid, no frame yet
return 0; // nothing ready poll_wait(file, &circbuf_wait_queue, wait);
//! Frame might become available during call to poll_wait so nobody will wake us up.
//! Let's see if there is stillno frame
//if ((camSeqGetJPEG_wp()<<2)!=file->f_pos) return POLLIN | POLLRDNORM; //! we are lucky - got it
w_ptr = camseq_get_jpeg_wp(chn) << 2;
if (w_ptr != file->f_pos)
return POLLIN | POLLRDNORM; //! we are lucky - got it
}
return 0; // nothing ready
} }
static struct file_operations circbuf_fops = { static struct file_operations circbuf_fops = {
...@@ -643,7 +753,7 @@ static int circbuf_all_init(struct platform_device *pdev) ...@@ -643,7 +753,7 @@ static int circbuf_all_init(struct platform_device *pdev)
if (!match) if (!match)
return -EINVAL; return -EINVAL;
MDF19(printk("\n")); dev_dbg(dev, "registering character device with name 'circbuf_operations'");
res = register_chrdev(CIRCBUF_MAJOR, "circbuf_operations", &circbuf_fops); res = register_chrdev(CIRCBUF_MAJOR, "circbuf_operations", &circbuf_fops);
if(res < 0) { if(res < 0) {
dev_err(dev, "couldn't get a major number %d.\n", CIRCBUF_MAJOR); dev_err(dev, "couldn't get a major number %d.\n", CIRCBUF_MAJOR);
...@@ -656,12 +766,12 @@ static int circbuf_all_init(struct platform_device *pdev) ...@@ -656,12 +766,12 @@ static int circbuf_all_init(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
MDF19(printk("init_waitqueue_head()\n")); dev_dbg(dev, "initialize circbuf wait queue\n");
init_waitqueue_head(&circbuf_wait_queue); init_waitqueue_head(&circbuf_wait_queue);
MDF19(printk("jpeg_htable_init()\n")); dev_dbg(dev, "initialize Huffman tables with default data\n");
jpeg_htable_init (); /// set default Huffman table, encode it for the FPGA jpeg_htable_init (); /// set default Huffman table, encode it for the FPGA
dev_info(dev, "registered MAJOR: %d\n", CIRCBUF_MAJOR);
dev_info(dev, "registered MAJOR: %d\n", CIRCBUF_MAJOR);
res = image_acq_init(pdev); res = image_acq_init(pdev);
if (res < 0) { if (res < 0) {
dev_err(dev, "unable to initialize sensor_common module\n"); dev_err(dev, "unable to initialize sensor_common module\n");
......
...@@ -1209,7 +1209,7 @@ loff_t framepars_lseek (struct file * file, loff_t offset, int orig) { ...@@ -1209,7 +1209,7 @@ loff_t framepars_lseek (struct file * file, loff_t offset, int orig) {
break; break;
case LSEEK_COMPRESSOR_RESET: /// reset compressor and buffer pointers case LSEEK_COMPRESSOR_RESET: /// reset compressor and buffer pointers
MDF2(printk("LSEEK_COMPRESSOR_RESET\n")); MDF2(printk("LSEEK_COMPRESSOR_RESET\n"));
reset_compressor(); //reset_compressor();
break; break;
case LSEEK_INTERRUPT_OFF: /// disable camera interrupts case LSEEK_INTERRUPT_OFF: /// disable camera interrupts
MDF2(printk ("LSEEK_INTERRUPT_OFF\n")); MDF2(printk ("LSEEK_INTERRUPT_OFF\n"));
......
...@@ -329,7 +329,6 @@ int jpeghead_open(struct inode *inode, struct file *filp) { // set filesize ...@@ -329,7 +329,6 @@ int jpeghead_open(struct inode *inode, struct file *filp) { // set filesize
inode->i_size=JPEG_HEADER_MAXSIZE; /// not the actual size inode->i_size=JPEG_HEADER_MAXSIZE; /// not the actual size
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(jpeghead_open);
/*!================================================================= /*!=================================================================
*! Overloading lseek with additional functionality (to avoid ioctls) *! Overloading lseek with additional functionality (to avoid ioctls)
...@@ -404,7 +403,6 @@ loff_t jpeghead_lseek(struct file * file, loff_t offset, int orig, ...@@ -404,7 +403,6 @@ loff_t jpeghead_lseek(struct file * file, loff_t offset, int orig,
} }
return ( file->f_pos ); return ( file->f_pos );
} }
EXPORT_SYMBOL_GPL(jpeghead_lseek);
ssize_t jpeghead_read(struct file * file, char * buf, size_t count, loff_t *off) { ssize_t jpeghead_read(struct file * file, char * buf, size_t count, loff_t *off) {
unsigned long p; unsigned long p;
...@@ -423,7 +421,6 @@ ssize_t jpeghead_read(struct file * file, char * buf, size_t count, loff_t *off) ...@@ -423,7 +421,6 @@ ssize_t jpeghead_read(struct file * file, char * buf, size_t count, loff_t *off)
} }
return count; return count;
} }
EXPORT_SYMBOL_GPL(jpeghead_read);
/**huffman_* file operations /**huffman_* file operations
...@@ -444,7 +441,6 @@ int huffman_open(struct inode *inode, struct file *filp) { // set filesize ...@@ -444,7 +441,6 @@ int huffman_open(struct inode *inode, struct file *filp) { // set filesize
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(huffman_open);
/*!================================================================= /*!=================================================================
*! Overloading lseek with additional functionality *! Overloading lseek with additional functionality
...@@ -505,7 +501,6 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){ ...@@ -505,7 +501,6 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){
if (file->f_pos > sizeof(huff_tables)) file->f_pos = sizeof(huff_tables); if (file->f_pos > sizeof(huff_tables)) file->f_pos = sizeof(huff_tables);
return ( file->f_pos ); return ( file->f_pos );
} }
EXPORT_SYMBOL_GPL(huffman_lseek);
ssize_t huffman_read(struct file * file, char * buf, size_t count, loff_t *off) { ssize_t huffman_read(struct file * file, char * buf, size_t count, loff_t *off) {
...@@ -521,7 +516,6 @@ ssize_t huffman_read(struct file * file, char * buf, size_t count, loff_t *off) ...@@ -521,7 +516,6 @@ ssize_t huffman_read(struct file * file, char * buf, size_t count, loff_t *off)
} }
return count; return count;
} }
EXPORT_SYMBOL_GPL(huffman_read);
ssize_t huffman_write(struct file * file, const char * buf, size_t count, loff_t *off) { ssize_t huffman_write(struct file * file, const char * buf, size_t count, loff_t *off) {
...@@ -537,7 +531,6 @@ ssize_t huffman_write(struct file * file, const char * buf, size_t count, loff_t ...@@ -537,7 +531,6 @@ ssize_t huffman_write(struct file * file, const char * buf, size_t count, loff_t
return count; return count;
} }
EXPORT_SYMBOL_GPL(huffman_write);
/** /**
* @brief Initialize Huffman tables with default data * @brief Initialize Huffman tables with default data
...@@ -608,7 +601,6 @@ void jpeg_htable_init (void) { ...@@ -608,7 +601,6 @@ void jpeg_htable_init (void) {
MDF17(printk("jpeg_htable_fpga_encode ()\n")); MDF17(printk("jpeg_htable_fpga_encode ()\n"));
jpeg_htable_fpga_encode (); jpeg_htable_fpga_encode ();
} }
EXPORT_SYMBOL_GPL(jpeg_htable_init);
/** /**
* @brief encode all 4 Huffman tables into FPGA format * @brief encode all 4 Huffman tables into FPGA format
......
...@@ -75,28 +75,6 @@ ...@@ -75,28 +75,6 @@
#include "x393_macro.h" #include "x393_macro.h"
#include "x393.h" #include "x393.h"
#if ELPHEL_DEBUG
#define ELPHEL_DEBUG_THIS 0
#else
#define ELPHEL_DEBUG_THIS 0
#endif
#if ELPHEL_DEBUG_THIS
#define MDF2(x) printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__); x
#define MDD1(x) printk("%s:%d:",__FILE__,__LINE__); x ; udelay (ELPHEL_DEBUG_DELAY)
#define MD1(x) printk("%s:%d:",__FILE__,__LINE__);x
//#define MD1(x)
#define MD12(x) printk("%s:%d:",__FILE__,__LINE__);x
//#define MD12(x)
#define MD13(x) printk("%s:%d:",__FILE__,__LINE__);x
//#define MD13(x)
#else
#define MDF2(x)
#define MD1(x)
#define MDD1(x)
#define MD12(x)
#define MD13(x)
#endif
/** /**
* @brief driver name to display in log messages * @brief driver name to display in log messages
*/ */
...@@ -106,9 +84,9 @@ ...@@ -106,9 +84,9 @@
* @brief \e jpeg_ptr_t structure contains read and write pointers along with * @brief \e jpeg_ptr_t structure contains read and write pointers along with
* IRQ number for a single channel * IRQ number for a single channel
* @var jpeg_ptr_t::jpeg_wr * @var jpeg_ptr_t::jpeg_wr
* JPEG write pointer * JPEG write pointer in 32 bit words
* @var jpeg_ptr_t::jpeg_rp * @var jpeg_ptr_t::jpeg_rp
* JPEG read pointer * JPEG read pointer in 32 bit words
* @var jpeg_ptr_t::fpga_cntr_prev * @var jpeg_ptr_t::fpga_cntr_prev
* This field contains previous value of the FPGA transfer counter which is used * This field contains previous value of the FPGA transfer counter which is used
* to find out if it has changed * to find out if it has changed
...@@ -151,6 +129,7 @@ static int fpga_counter_prev=0; /// Previous value of the FPGA transfer counter ...@@ -151,6 +129,7 @@ static int fpga_counter_prev=0; /// Previous value of the FPGA transfer counter
int Photo_MakerNote; int Photo_MakerNote;
} meta_offsets; } meta_offsets;
#ifdef TEST_DISABLE_CODE
int camSeqGetJPEG_wp(void) {return JPEG_wp;} int camSeqGetJPEG_wp(void) {return JPEG_wp;}
int camSeqGetJPEG_rp(void) {return JPEG_rp;} int camSeqGetJPEG_rp(void) {return JPEG_rp;}
void camSeqSetJPEG_rp(int p) { void camSeqSetJPEG_rp(int p) {
...@@ -161,6 +140,24 @@ void camSeqSetJPEG_rp(int p) { ...@@ -161,6 +140,24 @@ void camSeqSetJPEG_rp(int p) {
get_globalParam(G_CIRCBUFSIZE):0)+ get_globalParam(G_CIRCBUFRP)) get_globalParam(G_CIRCBUFSIZE):0)+ get_globalParam(G_CIRCBUFRP))
- get_globalParam(G_CIRCBUFWP)); - get_globalParam(G_CIRCBUFWP));
} }
#endif /* TEST_DISABLE_CODE */
int camseq_get_jpeg_wp(unsigned int chn)
{
return (chn < IMAGE_CHN_NUM) ? image_acq_priv.jpeg_ptr[chn].jpeg_wp : 0;
}
int camseq_get_jpeg_rp(unsigned int chn)
{
return (chn < IMAGE_CHN_NUM) ? image_acq_priv.jpeg_ptr[chn].jpeg_rp : 0;
}
void camseq_set_jpeg_rp(unsigned int chn, int ptr)
{
if (chn < IMAGE_CHN_NUM) {
image_acq_priv.jpeg_ptr[chn].jpeg_rp = ptr;
}
}
/*! /*!
End of compressor-related code - TODO: move to a separate file? End of compressor-related code - TODO: move to a separate file?
...@@ -171,12 +168,13 @@ static void dump_priv_data(int chn) ...@@ -171,12 +168,13 @@ static void dump_priv_data(int chn)
int i; int i;
if (chn < IMAGE_CHN_NUM) { if (chn < IMAGE_CHN_NUM) {
printk(KERN_DEBUG "jpeg_wp: 0x%x\n", image_acq_priv.jpeg_ptr[chn].jpeg_wp); printk(KERN_DEBUG "jpeg_wp (in bytes): 0x%x\n", image_acq_priv.jpeg_ptr[chn].jpeg_wp << 2);
printk(KERN_DEBUG "jpeg_rp: 0x%x\n", image_acq_priv.jpeg_ptr[chn].jpeg_rp); printk(KERN_DEBUG "jpeg_rp (in bytes): 0x%x\n", image_acq_priv.jpeg_ptr[chn].jpeg_rp << 2);
printk(KERN_DEBUG "fpga_cntr_prev: 0x%x\n", image_acq_priv.jpeg_ptr[chn].fpga_cntr_prev); printk(KERN_DEBUG "fpga_cntr_prev: 0x%x\n", image_acq_priv.jpeg_ptr[chn].fpga_cntr_prev);
printk(KERN_DEBUG "irq_num_comp: 0x%x\n", image_acq_priv.jpeg_ptr[chn].irq_num_comp); printk(KERN_DEBUG "irq_num_comp: 0x%x\n", image_acq_priv.jpeg_ptr[chn].irq_num_comp);
printk(KERN_DEBUG "irq_num_sens: 0x%x\n", image_acq_priv.jpeg_ptr[chn].irq_num_sens); printk(KERN_DEBUG "irq_num_sens: 0x%x\n", image_acq_priv.jpeg_ptr[chn].irq_num_sens);
printk(KERN_DEBUG "chn_num: 0x%x\n", image_acq_priv.jpeg_ptr[chn].chn_num); printk(KERN_DEBUG "chn_num: 0x%x\n", image_acq_priv.jpeg_ptr[chn].chn_num);
printk(KERN_DEBUG "flags: 0x%x\n", image_acq_priv.jpeg_ptr[chn].flags);
} else { } else {
for (i = 0; i < IMAGE_CHN_NUM; i++) { for (i = 0; i < IMAGE_CHN_NUM; i++) {
printk(KERN_DEBUG "jpeg_wp: 0x%x\n", image_acq_priv.jpeg_ptr[i].jpeg_wp); printk(KERN_DEBUG "jpeg_wp: 0x%x\n", image_acq_priv.jpeg_ptr[i].jpeg_wp);
...@@ -185,6 +183,7 @@ static void dump_priv_data(int chn) ...@@ -185,6 +183,7 @@ static void dump_priv_data(int chn)
printk(KERN_DEBUG "irq_num_comp: 0x%x\n", image_acq_priv.jpeg_ptr[i].irq_num_comp); printk(KERN_DEBUG "irq_num_comp: 0x%x\n", image_acq_priv.jpeg_ptr[i].irq_num_comp);
printk(KERN_DEBUG "irq_num_sens: 0x%x\n", image_acq_priv.jpeg_ptr[i].irq_num_sens); printk(KERN_DEBUG "irq_num_sens: 0x%x\n", image_acq_priv.jpeg_ptr[i].irq_num_sens);
printk(KERN_DEBUG "chn_num: 0x%x\n", image_acq_priv.jpeg_ptr[i].chn_num); printk(KERN_DEBUG "chn_num: 0x%x\n", image_acq_priv.jpeg_ptr[i].chn_num);
printk(KERN_DEBUG "flags: 0x%x\n", image_acq_priv.jpeg_ptr[i].flags);
} }
} }
} }
...@@ -254,13 +253,8 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr) ...@@ -254,13 +253,8 @@ static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
jptr->flags |= SENS_FLAG_IRQ; jptr->flags |= SENS_FLAG_IRQ;
jptr->fpga_cntr_prev = stat.offset256; jptr->fpga_cntr_prev = stat.offset256;
/*if (xferred < 0) // increment in 32 bit words
// 26 bit hardware counter rolled over jptr->jpeg_wp += (xferred << 3);
xferred += (1 << OFFSET256_CNTR_RES);*/
jptr->jpeg_wp += xferred * CHUNK_SIZE;
//JPEG_wp+= (xferred << 3); //! counts in 32-byte ( 8 of 32bit words) chunks
/*if (jptr->jpeg_wp > circbuf_size)
jptr->jpeg_wp -= circbuf_size;*/
return 1; return 1;
} }
...@@ -286,7 +280,7 @@ inline void updateIRQFocus(struct jpeg_ptr_t *jptr) ...@@ -286,7 +280,7 @@ inline void updateIRQFocus(struct jpeg_ptr_t *jptr)
{ {
//set_globalParam (G_GFOCUS_VALUE, X313_HIGHFREQ); //set_globalParam (G_GFOCUS_VALUE, X313_HIGHFREQ);
//set_imageParamsThis (P_FOCUS_VALUE, X313_HIGHFREQ); //set_imageParamsThis (P_FOCUS_VALUE, X313_HIGHFREQ);
u32 high_freq = x393_cmprs_highfreq(jptr->chn_num); u32 high_freq = x393_cmprs_hifreq(jptr->chn_num);
} }
...@@ -511,28 +505,6 @@ void tasklet_fpga_function(unsigned long arg) { ...@@ -511,28 +505,6 @@ void tasklet_fpga_function(unsigned long arg) {
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", __func__, circbuf_size);
//dump_priv_data(0);
for (i = 0; i< IMAGE_CHN_NUM; i++) {
printk(KERN_DEBUG "%s: checking channel %d \n", __func__, i);
if (image_acq_priv.jpeg_ptr[i].flags & SENS_FLAG_IRQ) {
dump_priv_data(i);
last_image_chunk = image_acq_priv.jpeg_ptr[i].jpeg_wp - OFFSET_X40;
if (last_image_chunk < 0)
last_image_chunk += circbuf_size;
len32 = ccam_dma_buf_ptr[(last_image_chunk + (0x20 - CCAM_MMAP_META_LENGTH) + 0x100000) >> 2];
buf_ptr = &ccam_dma_buf_ptr[(last_image_chunk + 0x100000) >> 2];
for (j = 0; j < (OFFSET_X40 >> 2); j++) {
printk(KERN_DEBUG "0x%x: 0x%x\n", last_image_chunk + j, buf_ptr[j]);
}
printk(KERN_DEBUG "circbuffer start address: 0x%x", ccam_dma_buf_ptr);
printk(KERN_DEBUG "last_image_chunk: 0x%x\n", last_image_chunk);
dev_dbg(NULL, "0x40 bytes of mem dump from last image chunk:\n");
print_hex_dump_bytes("", DUMP_PREFIX_NONE, (void *)buf_ptr, OFFSET_X40);
printk(KERN_DEBUG "%s: reading image length, channel %d; len32 0x%x\n",__func__, i, len32);
image_acq_priv.jpeg_ptr[i].flags &= (~SENS_FLAG_IRQ) & 0xffffffff;
}
}
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
/// Time is out? /// Time is out?
...@@ -637,22 +609,25 @@ GLOBALPARS(0x1044)=thisFrameNumber; ...@@ -637,22 +609,25 @@ GLOBALPARS(0x1044)=thisFrameNumber;
/** /**
* @brief resets compressor and buffer pointers * @brief resets compressor and buffer pointers
*/ */
void reset_compressor(void) { void reset_compressor(unsigned int chn)
unsigned long flags; {
local_irq_save(flags); int i;
unsigned long flags;
local_irq_save(flags);
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
port_csp0_addr[X313_WA_COMP_CMD]= COMPCMD_RESET; /// bypasses command sequencer port_csp0_addr[X313_WA_COMP_CMD]= COMPCMD_RESET; /// bypasses command sequencer
if (framepars) set_imageParamsR_all( P_COMPRESSOR_RUN, COMPRESSOR_RUN_STOP ); if (framepars) set_imageParamsR_all( P_COMPRESSOR_RUN, COMPRESSOR_RUN_STOP );
else printk ("framepars is not initialized\n"); else printk ("framepars is not initialized\n");
/// TODO: There still is a possibility, that there are compressor commands in the hardware que. Should we stop the hardware sequencer here (and restart it later)? /// TODO: There still is a possibility, that there are compressor commands in the hardware que. Should we stop the hardware sequencer here (and restart it later)?
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
JPEG_wp=0; image_acq_priv.jpeg_ptr[chn].jpeg_wp = 0;
JPEG_rp=0; image_acq_priv.jpeg_ptr[chn].jpeg_rp = 0;
//updateIRQCircbuf(); /// initialize G_CIRCBUFWP, G_FREECIRCBUF image_acq_priv.jpeg_ptr[chn].fpga_cntr_prev = 0;
fpga_counter_prev=0; image_acq_priv.jpeg_ptr[chn].flags = 0;
local_irq_restore(flags); //update_irq_circbuf(jptr);
local_irq_restore(flags);
} }
//EXPORT_SYMBOL_GPL(reset_compressor);
/** /**
* @brief Camera interrupts on/off (currently both in the FPGA and in the CPU) * @brief Camera interrupts on/off (currently both in the FPGA and in the CPU)
...@@ -662,7 +637,8 @@ void camera_interrupts (int on) { ...@@ -662,7 +637,8 @@ void camera_interrupts (int on) {
int i; int i;
x393_cmprs_interrupts_t irq_ctrl; x393_cmprs_interrupts_t irq_ctrl;
MDF2(printk ("camera_interrupts(%d)\n",on)); //MDF2(printk ("camera_interrupts(%d)\n",on));
dev_dbg(NULL, "set camera interrupts status: %d\n", on);
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
if (on) { if (on) {
EN_INTERRUPT(SMART); EN_INTERRUPT(SMART);
...@@ -683,7 +659,6 @@ void camera_interrupts (int on) { ...@@ -683,7 +659,6 @@ void camera_interrupts (int on) {
x393_cmprs_interrupts(irq_ctrl, i); x393_cmprs_interrupts(irq_ctrl, i);
} }
} }
//EXPORT_SYMBOL_GPL(camera_interrupts);
/** /**
* @brief sensor_common driver probing function * @brief sensor_common driver probing function
...@@ -709,7 +684,8 @@ int image_acq_init(struct platform_device *pdev) ...@@ -709,7 +684,8 @@ int image_acq_init(struct platform_device *pdev)
return -EINVAL;*/ return -EINVAL;*/
sensorproc= &s_sensorproc; sensorproc= &s_sensorproc;
MDD1(printk("sensorproc=0x%x\n",(int) sensorproc)); //MDD1(printk("sensorproc=0x%x\n",(int) sensorproc));
dev_dbg(dev, "sensorproc address: 0x%x\n", (int)sensorproc);
for (i = 0; i < IMAGE_CHN_NUM; i++) { for (i = 0; i < IMAGE_CHN_NUM; i++) {
irq = platform_get_irq_byname(pdev, frame_sync_irq_names[i]); irq = platform_get_irq_byname(pdev, frame_sync_irq_names[i]);
...@@ -755,16 +731,18 @@ int image_acq_init(struct platform_device *pdev) ...@@ -755,16 +731,18 @@ int image_acq_init(struct platform_device *pdev)
#endif #endif
printk("Elphel FPGA interrupts initialized\n"); dev_dbg(dev, "Elphel FPGA interrupts initialized\n");
// init_waitqueue_head(&image_acq_wait_queue); dev_dbg(dev, "reset all compressors\n");
// DMA_buf_start=x313_dma_init(); for (i = 0; i < IMAGE_CHN_NUM; i++) {
MDD1(printk("reset_compressor()\n")); reset_compressor(i);
reset_compressor(); /// reset compressor and buffer pointers }
MDD1(printk("x313_dma_init()\n")); //reset_compressor(); /// reset compressor and buffer pointers
//MDD1(printk("x313_dma_init()\n"));
//x313_dma_init(); /// initialize ETRAX FS DMA //x313_dma_init(); /// initialize ETRAX FS DMA
MDD1(printk("init_pgm_proc ()\n")); //MDD1(printk("init_pgm_proc ()\n"));
//init_pgm_proc (); /// setup pointers to functions (not sensor-specific) //init_pgm_proc (); /// setup pointers to functions (not sensor-specific)
MDD1(printk("reset_qtables()\n")); //MDD1(printk("reset_qtables()\n"));
dev_dbg(dev, "reset quantization tables\n");
reset_qtables(); /// force initialization at next access reset_qtables(); /// force initialization at next access
return 0; return 0;
......
...@@ -12,9 +12,13 @@ extern struct sensorproc_t * sensorproc; ...@@ -12,9 +12,13 @@ extern struct sensorproc_t * sensorproc;
#include "mt9x001.h" #include "mt9x001.h"
#endif #endif
//#include "multisensor.h" //#include "multisensor.h"
int camSeqGetJPEG_wp(void); //int camSeqGetJPEG_wp(void);
int camSeqGetJPEG_rp(void); //int camSeqGetJPEG_rp(void);
void camSeqSetJPEG_rp(int p); //void camSeqSetJPEG_rp(int p);
int camseq_get_jpeg_wp(unsigned int chn);
int camseq_get_jpeg_rp(unsigned int chn);
void camseq_set_jpeg_rp(unsigned int chn, int ptr);
///CIRCBUF macros ///CIRCBUF macros
extern unsigned long * ccam_dma_buf_ptr; extern unsigned long * ccam_dma_buf_ptr;
...@@ -27,7 +31,7 @@ extern unsigned long * ccam_dma_buf_ptr; ...@@ -27,7 +31,7 @@ extern unsigned long * ccam_dma_buf_ptr;
//int init_FPGA(void); /// can be initialized only after FPGA is configured, not at module init (NOTE was static??) //int init_FPGA(void); /// can be initialized only after FPGA is configured, not at module init (NOTE was static??)
///can be verified with if (!X313_IS_SDRAM_ON) ///can be verified with if (!X313_IS_SDRAM_ON)
void reset_compressor(void); void reset_compressor(unsigned int chn);
void camera_interrupts (int on); void camera_interrupts (int on);
struct sensorproc_t * copy_sensorproc (struct sensorproc_t * copy); struct sensorproc_t * copy_sensorproc (struct sensorproc_t * copy);
......
...@@ -13,11 +13,19 @@ ...@@ -13,11 +13,19 @@
#define CHUNK_SIZE 32 #define CHUNK_SIZE 32
/** @brief The size of #interframe_params_t structure in double words */
#define INTERFRAME_PARAMS_SZ 8
#define MARKER_FF 0xff
#define IRQ_NOP 0 #define IRQ_NOP 0
#define IRQ_CLEAR 1 #define IRQ_CLEAR 1
#define IRQ_DISABLE 2 #define IRQ_DISABLE 2
#define IRQ_ENABLE 3 #define IRQ_ENABLE 3
#define BYTE2DW(x) ((x) >> 2)
#define DW2BYTE(x) ((x) << 2)
/* These macro were removed from sensor_common.h*/ /* These macro were removed from sensor_common.h*/
#define X313_LENGTH_MASK 0xff000000 #define X313_LENGTH_MASK 0xff000000
#define X313_PADDED_FRAME(x)((((x)+67+CCAM_MMAP_META ) >>2) & 0xfffffff8) #define X313_PADDED_FRAME(x)((((x)+67+CCAM_MMAP_META ) >>2) & 0xfffffff8)
......
...@@ -9,8 +9,8 @@ ...@@ -9,8 +9,8 @@
//#define ELPHEL_DEBUG 0 //global debug on/off in multiple files //#define ELPHEL_DEBUG 0 //global debug on/off in multiple files
//#define ELPHEL_DEBUG_STARTUP 000a4c00 ; //#define ELPHEL_DEBUG_STARTUP 000a4c00 ;
//#define ELPHEL_DEBUG_STARTUP 0 ; // removed - add write to fpga init script //#define ELPHEL_DEBUG_STARTUP 0 ; // removed - add write to fpga init script
#define ELPHEL_DEBUG 0 //global debug on/off in multiple files //#define ELPHEL_DEBUG 0 //global debug on/off in multiple files
//#define ELPHEL_DEBUG 1 //global debug on/off in multiple files #define ELPHEL_DEBUG 1 //global debug on/off in multiple files
#define ELPHEL_DEBUG_DELAY 100000 //delay after some printk-s #define ELPHEL_DEBUG_DELAY 100000 //delay after some printk-s
#define ELP_KERR(x) printk("%s:%d:%s: ERROR ",__FILE__,__LINE__,__FUNCTION__);x #define ELP_KERR(x) printk("%s:%d:%s: ERROR ",__FILE__,__LINE__,__FUNCTION__);x
#define ELP_FERR(x) fprintf(stderr,"%s:%d:%s: ERROR ",__FILE__,__LINE__,__FUNCTION__);x #define ELP_FERR(x) fprintf(stderr,"%s:%d:%s: ERROR ",__FILE__,__LINE__,__FUNCTION__);x
...@@ -1498,7 +1498,9 @@ struct p_names_t { ...@@ -1498,7 +1498,9 @@ struct p_names_t {
#define CCAM_BYTES_PER_DMABUF (CCAM_CHUNK_PER_DMABUF<<16) #define CCAM_BYTES_PER_DMABUF (CCAM_CHUNK_PER_DMABUF<<16)
/* For past compatibility, CCMA_DMA_SIZE... /* For past compatibility, CCMA_DMA_SIZE...
*/ */
#define CCAM_DMA_SIZE CCAM_WORDS_PER_DMABUF //#define CCAM_DMA_SIZE CCAM_WORDS_PER_DMABUF
#define CCAM_DMA_SIZE 0x1000000
#define CIRCBUF_START_OFFSET 0x100000
/* /*
* CCAM_MMAP_OFFSET... -- offsets in bytes in memory mapped region. * CCAM_MMAP_OFFSET... -- offsets in bytes in memory mapped region.
......
...@@ -27,6 +27,12 @@ ...@@ -27,6 +27,12 @@
#define IMAGERAW_MINOR_FPN 2 #define IMAGERAW_MINOR_FPN 2
#define IMAGERAW_MINOR_UNLOCK 3 #define IMAGERAW_MINOR_UNLOCK 3
#define CIRCBUF_MINOR_CHN_OFFSET 30
#define CIRCBUF_MINOR_CHN_0 30
#define CIRCBUF_MINOR_CHN_1 31
#define CIRCBUF_MINOR_CHN_2 32
#define CIRCBUF_MINOR_CHN_3 33
#define CMOSCAM_MINOR_RWTABLES 9 #define CMOSCAM_MINOR_RWTABLES 9
#define CMOSCAM_MINOR_CIRCBUF 11 #define CMOSCAM_MINOR_CIRCBUF 11
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment