Commit c96d81bb authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: imgsrv stops at reading frame params

parent 99dc26ff
...@@ -31,9 +31,9 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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) { ...@@ -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 ...@@ -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) ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) { ...@@ -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) ...@@ -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
......
...@@ -21,20 +21,21 @@ ...@@ -21,20 +21,21 @@
#include <linux/module.h> #include <linux/module.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/sched.h> //#include <linux/sched.h>
#include <linux/slab.h> #include <linux/slab.h>
#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/autoconf.h> //#include <linux/autoconf.h>
#include <linux/time.h> //#include <linux/time.h>
#include <linux/device.h>
//#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>
...@@ -43,11 +44,11 @@ ...@@ -43,11 +44,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/c313a.h> #include <elphel/c313a.h>
//#include "fpga_io.h"//fpga_table_write_nice //#include "fpga_io.h"//fpga_table_write_nice
...@@ -62,25 +63,11 @@ ...@@ -62,25 +63,11 @@
//#include "sensor_common.h" //#include "sensor_common.h"
#include "exif.h" #include "exif.h"
#include "x393_macro.h" #include "x393_macro.h"
#include "x393.h"
#if ELPHEL_DEBUG
#define MDF(x) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;}
#define D17(x) { if (GLOBALPARS(G_DEBUG) & (1 <<17)) {x; } ; }
#define MDF17(x) { if (GLOBALPARS(G_DEBUG) & (1 <<17)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;} }
#define D18(x) { if (GLOBALPARS(G_DEBUG) & (1 <<18)) {x; } ; }
#define MDF18(x) { if (GLOBALPARS(G_DEBUG) & (1 <<18)) {printk("%s:%d:%s ",__FILE__,__LINE__,__FUNCTION__ );x ;} }
#define ELPHEL_DEBUG_THIS 1
#else
#define MDF(x)
#define D17(x)
#define MDF17(x)
#define D18(x)
#define MDF18(x)
#define ELPHEL_DEBUG_THIS 0
#endif
#define JPEG_HEADER_MAX_SIZE 0x300 #define JPEG_HEADER_MAX_SIZE 0x300
static int huffman_fpga_programmed=0; static int huffman_fpga_programmed=0;
static struct device *g_dev_ptr = NULL;
/// All huffman tabels data to be read/written from the application /// All huffman tabels data to be read/written from the application
static struct huff_tables_t { static struct huff_tables_t {
...@@ -112,7 +99,7 @@ static struct huff_tables_t { ...@@ -112,7 +99,7 @@ static struct huff_tables_t {
* @return header length if successful, <0 - error * @return header length if successful, <0 - error
*/ */
int qtables_create(struct interframe_params_t * params, unsigned char * buf) { int qtables_create(struct interframe_params_t * params, unsigned char * buf) {
MDF18(printk("params->quality2=0x%x",params->quality2)); dev_dbg(g_dev_ptr, "params->quality2 = 0x%x\n", params->quality2);
int rslt=get_qtable(params->quality2, &buf[0], &buf[64]); /// will copy both quantization tables int rslt=get_qtable(params->quality2, &buf[0], &buf[64]); /// will copy both quantization tables
if (rslt <0) return rslt; /// bad quality table if (rslt <0) return rslt; /// bad quality table
return 128; return 128;
...@@ -193,8 +180,10 @@ int jpegheader_create(struct interframe_params_t * params, unsigned char * buf) ...@@ -193,8 +180,10 @@ int jpegheader_create(struct interframe_params_t * params, unsigned char * buf)
0x06, 0x11, 0x06, 0x11,
0x07, 0x11}; 0x07, 0x11};
if (buf==NULL) return -1; /// buffer is not provided if (buf==NULL) return -1; /// buffer is not provided
MDF17(printk("\n"));
MDF18(unsigned char * p= (char *) params; for (len=0;len<32;len++) {if ((len & 0x0f)==0) printk("\n%03x: ",len); printk(" %02x", (int) p[len]);} printk("\n");); unsigned char *p = (char *)params;
dev_dbg(g_dev_ptr, "list of parameters:\n");
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p, 32);
memcpy((void *) &buf[0], (void *) jfif1, sizeof (jfif1)); /// including DQT0 header memcpy((void *) &buf[0], (void *) jfif1, sizeof (jfif1)); /// including DQT0 header
memcpy((void *) &buf[header_cqtable_hd], (void *) jfif2, sizeof (jfif2)); /// DQT1 header memcpy((void *) &buf[header_cqtable_hd], (void *) jfif2, sizeof (jfif2)); /// DQT1 header
...@@ -305,12 +294,18 @@ int jpegheader_create(struct interframe_params_t * params, unsigned char * buf) ...@@ -305,12 +294,18 @@ int jpegheader_create(struct interframe_params_t * params, unsigned char * buf)
buf[bp++]=0x00; /// Spectral selection start buf[bp++]=0x00; /// Spectral selection start
buf[bp++]=0x3f; /// Spectral selection end buf[bp++]=0x3f; /// Spectral selection end
buf[bp++]=0x00; /// Successive approximation (2 values 0..13) buf[bp++]=0x00; /// Successive approximation (2 values 0..13)
MDF17(printk("JPEG header length=%d\n",bp));
MDF18(for (len=0;len<bp;len++) {if ((len & 0x0f)==0) printk("\n%03x: ",len); printk(" %02x",buf[len]);} printk("\n");); dev_dbg(g_dev_ptr, "JPEG header length = %d\n", bp);
dev_dbg(g_dev_ptr, "list of parameters:\n");
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, p, 32);
return bp; /// JPEG header length return bp; /// JPEG header length
} }
static int minor_to_chn(unsigned int minor)
{
return 0;
}
/*!================================================================= /*!=================================================================
*! JPEG header file support *! JPEG header file support
...@@ -352,7 +347,7 @@ loff_t jpeghead_lseek(struct file * file, loff_t offset, int orig, ...@@ -352,7 +347,7 @@ loff_t jpeghead_lseek(struct file * file, loff_t offset, int orig,
struct jpeghead_pd * privData; struct jpeghead_pd * privData;
//struct interframe_params_t * fp; //struct interframe_params_t * fp;
privData = (struct jpeghead_pd *) file->private_data; privData = (struct jpeghead_pd *) file->private_data;
MDF17(printk("orig=%d, offst=0x%x\n",orig,(int) offset)); dev_dbg(g_dev_ptr, "orig = %d, offset = 0x%x\n", orig, (int)offset);
switch (orig) switch (orig)
{ {
...@@ -372,7 +367,8 @@ loff_t jpeghead_lseek(struct file * file, loff_t offset, int orig, ...@@ -372,7 +367,8 @@ loff_t jpeghead_lseek(struct file * file, loff_t offset, int orig,
rp= (offset >>2) & (~7); // convert to index to long, align to 32-bytes rp= (offset >>2) & (~7); // convert to index to long, align to 32-bytes
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 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
*/ */
if ((fp->signffff != 0xffff) || //! signature is overwritten //if ((fp->signffff != 0xffff) || //! signature is overwritten
if ((fp->signff != 0xff) || //! signature is overwritten
((fp->timestamp_sec) & X313_LENGTH_MASK)) return -EINVAL; //! acquisition of this frame is not done yet - length word high byte is non-zero ((fp->timestamp_sec) & X313_LENGTH_MASK)) return -EINVAL; //! acquisition of this frame is not done yet - length word high byte is non-zero
...@@ -408,7 +404,7 @@ ssize_t jpeghead_read(struct file * file, char * buf, size_t count, loff_t *off) ...@@ -408,7 +404,7 @@ ssize_t jpeghead_read(struct file * file, char * buf, size_t count, loff_t *off)
unsigned long p; unsigned long p;
struct jpeghead_pd * privData; struct jpeghead_pd * privData;
privData = (struct jpeghead_pd *) file->private_data; privData = (struct jpeghead_pd *) file->private_data;
MDF17(printk("\n")); dev_dbg(g_dev_ptr, "reading from jpeghead\n");
p = *off; p = *off;
if(p >= privData->size) if(p >= privData->size)
p = privData->size; p = privData->size;
...@@ -460,6 +456,7 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){ ...@@ -460,6 +456,7 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){
// orig 0: position from begning // orig 0: position from begning
// orig 1: relative from current position // orig 1: relative from current position
// orig 2: position from last address // orig 2: position from last address
unsigned int minor = MINOR(file->f_inode->i_rdev);
switch (orig) switch (orig)
{ {
...@@ -483,7 +480,7 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){ ...@@ -483,7 +480,7 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){
case LSEEK_HUFFMAN_FPGACALC: case LSEEK_HUFFMAN_FPGACALC:
if (jpeg_htable_fpga_encode () <0) return -EINVAL; if (jpeg_htable_fpga_encode () <0) return -EINVAL;
break; break;
case LSEEK_HUFFMAN_FPGAPGM: jpeg_htable_fpga_pgm (); break; case LSEEK_HUFFMAN_FPGAPGM: jpeg_htable_fpga_pgm(minor_to_chn(minor)); break;
default: return -EINVAL; default: return -EINVAL;
} }
...@@ -506,7 +503,7 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){ ...@@ -506,7 +503,7 @@ loff_t huffman_lseek(struct file * file, loff_t offset, int orig){
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) {
unsigned long p; unsigned long p;
unsigned char * uc_huff_tables= (unsigned char *) &huff_tables; unsigned char * uc_huff_tables= (unsigned char *) &huff_tables;
MDF17(printk("\n")); dev_dbg(g_dev_ptr, "reading from huffman\n");
p = *off; p = *off;
if(p >= sizeof(huff_tables)) p = sizeof(huff_tables); if(p >= sizeof(huff_tables)) p = sizeof(huff_tables);
if((p + count) > sizeof(huff_tables)) count = sizeof(huff_tables) - p; /// truncate count if((p + count) > sizeof(huff_tables)) count = sizeof(huff_tables) - p; /// truncate count
...@@ -521,7 +518,7 @@ ssize_t huffman_read(struct file * file, char * buf, size_t count, loff_t *off) ...@@ -521,7 +518,7 @@ ssize_t huffman_read(struct file * file, char * buf, size_t count, loff_t *off)
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) {
unsigned long p; unsigned long p;
unsigned char * uc_huff_tables= (unsigned char *) &huff_tables; unsigned char * uc_huff_tables= (unsigned char *) &huff_tables;
MDF17(printk("\n")); dev_dbg(g_dev_ptr, "writing to huffman\n");
p = *off; p = *off;
if (p >= sizeof(huff_tables)) p = sizeof(huff_tables); if (p >= sizeof(huff_tables)) p = sizeof(huff_tables);
if( (p + count) > sizeof(huff_tables)) count = sizeof(huff_tables) - p; /// truncate count if( (p + count) > sizeof(huff_tables)) count = sizeof(huff_tables) - p; /// truncate count
...@@ -592,13 +589,13 @@ void jpeg_htable_init (void) { ...@@ -592,13 +589,13 @@ void jpeg_htable_init (void) {
0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
0xf9, 0xfa}; 0xf9, 0xfa};
MDF17(printk(" started\n")); dev_dbg(g_dev_ptr, "initialize Huffman table with default data\n");
memset ((void*) &huff_tables,0, sizeof(huff_tables)); memset ((void*) &huff_tables,0, sizeof(huff_tables));
memcpy ((void*) huff_tables.header_huffman_tables[0].bits,dc0, sizeof(dc0)); memcpy ((void*) huff_tables.header_huffman_tables[0].bits,dc0, sizeof(dc0));
memcpy ((void*) huff_tables.header_huffman_tables[1].bits,ac0, sizeof(ac0)); memcpy ((void*) huff_tables.header_huffman_tables[1].bits,ac0, sizeof(ac0));
memcpy ((void*) huff_tables.header_huffman_tables[2].bits,dc1, sizeof(dc1)); memcpy ((void*) huff_tables.header_huffman_tables[2].bits,dc1, sizeof(dc1));
memcpy ((void*) huff_tables.header_huffman_tables[3].bits,ac1, sizeof(ac1)); memcpy ((void*) huff_tables.header_huffman_tables[3].bits,ac1, sizeof(ac1));
MDF17(printk("jpeg_htable_fpga_encode ()\n"));
jpeg_htable_fpga_encode (); jpeg_htable_fpga_encode ();
} }
...@@ -618,11 +615,11 @@ int jpeg_htable_fpga_encode (void) { ...@@ -618,11 +615,11 @@ int jpeg_htable_fpga_encode (void) {
struct huffman_fpga_code_t codes[256]; struct huffman_fpga_code_t codes[256];
unsigned long * icodes = (unsigned long *) codes; unsigned long * icodes = (unsigned long *) codes;
huffman_fpga_programmed=0; /// mark FPGA table as needed to be programmed huffman_fpga_programmed=0; /// mark FPGA table as needed to be programmed
MDF17(printk(" started\n")); dev_dbg(g_dev_ptr, "encode all Huffman tables into FPGA format\n");
/// Fill in the table headers: /// Fill in the table headers:
memcpy ((void*) huff_tables.dht_all, (void*) dht_headers, sizeof(dht_headers)); /// all 4 headers (with zero length) memcpy ((void*) huff_tables.dht_all, (void*) dht_headers, sizeof(dht_headers)); /// all 4 headers (with zero length)
for (ntab=0; ntab<4; ntab++) { for (ntab=0; ntab<4; ntab++) {
MDF17(printk("ntab=%d\n", ntab)); dev_dbg(g_dev_ptr, "ntab = %d\n", ntab);
memset (codes,0,sizeof(codes)); memset (codes,0,sizeof(codes));
if ((rslt=jpeg_prep_htable (&(huff_tables.header_huffman_tables[ntab]), codes)) < 0 ) return rslt; if ((rslt=jpeg_prep_htable (&(huff_tables.header_huffman_tables[ntab]), codes)) < 0 ) return rslt;
if (ntab & 1) { if (ntab & 1) {
...@@ -645,7 +642,8 @@ int jpeg_htable_fpga_encode (void) { ...@@ -645,7 +642,8 @@ int jpeg_htable_fpga_encode (void) {
huff_tables.dht_all[(5*ntab)+3]=length& 0xff; /// low byte huff_tables.dht_all[(5*ntab)+3]=length& 0xff; /// low byte
} }
MDF17(printk("\nFPGA Huffman table\n");for (i=0;i<512;i++){printk (" %06x",(int)huff_tables.fpga_huffman_table[i]); if ((i & 0x0f)==0x0f) printk("\n");}); dev_dbg(g_dev_ptr, "FPGA Huffman table:\n");
print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, &huff_tables.fpga_huffman_table[0], sizeof(huff_tables.fpga_huffman_table));
return 0; return 0;
} }
...@@ -660,65 +658,75 @@ int jpeg_htable_is_programmed(void) { ...@@ -660,65 +658,75 @@ int jpeg_htable_is_programmed(void) {
/** /**
* @brief program FPGA Huffman table (fram static array) * @brief program FPGA Huffman table (fram static array)
* @param[in] chn compressor channle number
* return none
*/ */
void jpeg_htable_fpga_pgm (void) { void jpeg_htable_fpga_pgm(unsigned int chn)
#ifdef TEST_DISABLE_CODE {
fpga_table_write_nice (CX313_FPGA_TABLES_HUFF, 512, huff_tables.fpga_huffman_table); int i;
#endif x393_cmprs_table_addr_t table_addr;
huffman_fpga_programmed=1;
table_addr.addr32 = 0;
table_addr.type = 3;
x393_cmprs_tables_address(table_addr, chn);
for (i = 0; i < sizeof(huff_tables.fpga_huffman_table); i++) {
x393_cmprs_tables_data((u32)huff_tables.fpga_huffman_table[i], chn);
}
huffman_fpga_programmed=1;
} }
/// Code below is based on jdhuff.c (from libjpeg)
/** /**
* @brief Calculate huffman table (1 of 4) from the JPEG header to code lengh/value (for FPGA) * @brief Calculate huffman table (1 of 4) from the JPEG header to code length/value (for FPGA)
*
* The code of this function is based on jdhuff.c (from libjpeg)
* @param htable encoded Huffman table - 16 length bytes followed by up to 256 symbols * @param htable encoded Huffman table - 16 length bytes followed by up to 256 symbols
* @param hcodes combined (length<<16) | code table for each symbol * @param hcodes combined (length<<16) | code table for each symbol
* @return OK- 0, -1 - too many symbols, -2 bad table * @return OK- 0, -1 - too many symbols, -2 bad table
*/ */
///Does it depend on no missing symbols? ///Does it depend on no missing symbols?
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)
int p, i, l, si, numsymbols; {
unsigned int code; int p, i, l, si, numsymbols;
MDF17(printk(" started\n")); unsigned int code;
/// Figure C.1: make table of Huffman code length for each symbol dev_dbg(g_dev_ptr, "calculate Huffman table from JPEG header\n");
p = 0; /// Figure C.1: make table of Huffman code length for each symbol
for (l = 1; l <= 16; l++) { p = 0;
i = htable->bits[l-1]; for (l = 1; l <= 16; l++) {
if (i < 0 || p + i > 256) { i = htable->bits[l-1];
MDF17(printk("protect against table overrun\n")); if (i < 0 || p + i > 256) {
return -1 ; /// protect against table overrun dev_dbg(g_dev_ptr, "protect against table overrun\n");
} return -1 ; /// protect against table overrun
while (i--) hcodes[htable->huffval[p++]].length=l; }
} while (i--) hcodes[htable->huffval[p++]].length=l;
numsymbols = p; }
/// Figure C.2: generate the codes themselves numsymbols = p;
/// We also validate that the counts represent a legal Huffman code tree. /// Figure C.2: generate the codes themselves
code = 0; /// We also validate that the counts represent a legal Huffman code tree.
si = hcodes[htable->huffval[0]].length; code = 0;
p = 0; si = hcodes[htable->huffval[0]].length;
///htable->huffval[N] - N-th symbol value p = 0;
while (p < numsymbols) { ///htable->huffval[N] - N-th symbol value
if ((hcodes[htable->huffval[p]].length < si) || (si>16)) { while (p < numsymbols) {
ELP_KERR(printk("Bad table/bug\n")); if ((hcodes[htable->huffval[p]].length < si) || (si>16)) {
return -3; ///Bad table dev_err(g_dev_ptr, "bad table/bug\n");
} return -3; ///Bad table
while (hcodes[htable->huffval[p]].length == si) { }
hcodes[htable->huffval[p++]].value = code; while (hcodes[htable->huffval[p]].length == si) {
code++; hcodes[htable->huffval[p++]].value = code;
} code++;
}
/** code is now 1 more than the last code used for codelength si; but
* it must still fit in si bits, since no code is allowed to be all ones. /** code is now 1 more than the last code used for codelength si; but
*/ * it must still fit in si bits, since no code is allowed to be all ones.
if ( code >= (1 << si)) { */
ELP_KERR(printk("Bad code\n")); if ( code >= (1 << si)) {
return -2; ///Bad code dev_err(g_dev_ptr, "bad code\n");
} return -2; ///Bad code
code <<= 1; }
si++; code <<= 1;
} si++;
return 0; }
return 0;
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -38,7 +38,7 @@ struct huffman_pd { ...@@ -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 */
...@@ -283,7 +283,15 @@ inline void updateIRQFocus(struct jpeg_ptr_t *jptr) ...@@ -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) ...@@ -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) ...@@ -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) { ...@@ -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
......
...@@ -1641,37 +1641,17 @@ struct sensorproc_t { ...@@ -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 { ...@@ -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;
}; };
}; };
}; };
......
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