Commit fd58a7d1 authored by Mikhail Karpenko's avatar Mikhail Karpenko

WIP: update jpeg_wr from IRQ

parent f632965f
...@@ -139,17 +139,6 @@ wait_queue_head_t circbuf_wait_queue; ...@@ -139,17 +139,6 @@ wait_queue_head_t circbuf_wait_queue;
*! CMOSCAM_MINOR_CIRCBUF, CMOSCAM_MINOR_JPEAGHEAD - just a new major *! CMOSCAM_MINOR_CIRCBUF, CMOSCAM_MINOR_JPEAGHEAD - just a new major
*!========================================================================================================*/ *!========================================================================================================*/
#define CIRCBUF_DRIVER_NAME "Elphel (R) Model 353 video buffer device driver" #define CIRCBUF_DRIVER_NAME "Elphel (R) Model 353 video buffer device driver"
static struct file_operations circbuf_fops = {
owner: THIS_MODULE,
llseek: circbuf_all_lseek,
read: circbuf_all_read,
write: circbuf_all_write,
//ioctl: circbuf_all_ioctl,
open: circbuf_all_open,
mmap: circbuf_all_mmap,
poll: circbuf_all_poll,
release: circbuf_all_release
};
// Read/write to circular buffer. Needed to find out what Axis DMA is doing // Read/write to circular buffer. Needed to find out what Axis DMA is doing
// also - jpeg header // also - jpeg header
...@@ -514,38 +503,20 @@ MD12(int dbg_i); ...@@ -514,38 +503,20 @@ MD12(int dbg_i);
* @return number of bytes read form \e buf * @return number of bytes read form \e buf
*/ */
ssize_t circbuf_write(struct file * file, const char * buf, size_t count, loff_t *off) { ssize_t circbuf_write(struct file * file, const char * buf, size_t count, loff_t *off) {
void __iomem *mmio;
x393_afimux_status_t val;
int port;
unsigned long p; unsigned long p;
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;
// convert char to number /* debug code follows*/
port = buf[0] - 0x30; switch (buf[0] - 0x30) {
/*mmio = ioremap(0x40002060, 16); case 0:
if (!mmio) { camera_interrupts(0);
printk(KERN_DEBUG "ERROR: can not ioremap region"); break;
return count; case 1:
}*/ camera_interrupts(1);
if (init_mmio_ptr() < 0) { break;
printk(KERN_DEBUG "ERROR: can not remap IO region\n");
} }
if (port >= 0 && port < 4) { /* debug code end */
val = x393_afimux0_status(port);
//val.d32 = readl((void*) (0x40002060 + 0x4 * port));
//val.d32 = ioread32(mmio + 0x4 * port);
} else {
printk(KERN_DEBUG "Unrecognized port number\n");
}
printk(KERN_DEBUG "AFI MUX0 port: %d, AFI MUX0 offset: 0x%x, AFI MUX0 sequence number: %d\n", port, val.offset256 * 32, val.seq_num);
printk(KERN_DEBUG "AFI MUX0 raw value: 0x%x\n", val.d32);
printk(KERN_DEBUG "AFI MUX0 offset265: 0x%x, seq_num: 0x%x\n", val.offset256, val.seq_num);
iounmap(mmio);
mmio = NULL;
return count;
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() !!!
...@@ -641,6 +612,18 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait) { ...@@ -641,6 +612,18 @@ unsigned int circbuf_poll (struct file *file, poll_table *wait) {
return 0; // nothing ready return 0; // nothing ready
} }
static struct file_operations circbuf_fops = {
.owner = THIS_MODULE,
.llseek = circbuf_all_lseek,
.read = circbuf_all_read,
.write = circbuf_all_write,
//ioctl: circbuf_all_ioctl,
.open = circbuf_all_open,
.mmap = circbuf_all_mmap,
.poll = circbuf_all_poll,
.release = circbuf_all_release
};
/** /**
* @brief cirbuf driver probing function * @brief cirbuf driver probing function
* @param[in] pdev pointer to \b platform_device structure * @param[in] pdev pointer to \b platform_device structure
...@@ -660,8 +643,8 @@ static int circbuf_all_init(struct platform_device *pdev) ...@@ -660,8 +643,8 @@ static int circbuf_all_init(struct platform_device *pdev)
MDF19(printk("\n")); MDF19(printk("\n"));
res = register_chrdev(CIRCBUF_MAJOR, "circbuf_operations", &circbuf_fops); res = register_chrdev(CIRCBUF_MAJOR, "circbuf_operations", &circbuf_fops);
if(res < 0) { if(res < 0) {
printk(KERN_ERR "\ncircbuf_all_init: couldn't get a major number %d.\n",CIRCBUF_MAJOR); dev_err(dev, "couldn't get a major number %d.\n", CIRCBUF_MAJOR);
return res; return res;
} }
res = init_ccam_dma_buf_ptr(pdev); res = init_ccam_dma_buf_ptr(pdev);
...@@ -676,6 +659,12 @@ static int circbuf_all_init(struct platform_device *pdev) ...@@ -676,6 +659,12 @@ static int circbuf_all_init(struct platform_device *pdev)
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);
if (res < 0) {
dev_err(dev, "unable to initialize sensor_common module\n");
return res;
}
return 0; return 0;
} }
......
...@@ -577,6 +577,10 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars) { ...@@ -577,6 +577,10 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars) {
} }
} }
void update_frame_pars(void)
{
printk(KERN_DEBUG "%s stub\n", __func__);
}
/** /**
* @brief process parameters that are overdue or due in ASAP mode (not through the sequencer) * @brief process parameters that are overdue or due in ASAP mode (not through the sequencer)
......
...@@ -25,6 +25,7 @@ unsigned long get_globalParam (int n); ...@@ -25,6 +25,7 @@ unsigned long get_globalParam (int n);
void set_globalParam (int n, unsigned long d); void set_globalParam (int n, unsigned long d);
void set_imageParamsR_all(int n, unsigned long d); void set_imageParamsR_all(int n, unsigned long d);
void update_frame_pars(void);
void updateFramePars(int frame8, struct interframe_params_t * frame_pars); /// called from ISR - advance thisFrameNumber to match hardware frame8, copy parameters as needed. void updateFramePars(int frame8, struct interframe_params_t * frame_pars); /// called from ISR - advance thisFrameNumber to match hardware frame8, copy parameters as needed.
/// frame8 usually is just next after thisFrameNumber /// frame8 usually is just next after thisFrameNumber
/// frame_pars - pointer to structure (between frames in the frame buffer) to save a pointer to past parameters /// frame_pars - pointer to structure (between frames in the frame buffer) to save a pointer to past parameters
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include <linux/of.h> #include <linux/of.h>
#include <linux/of_device.h> #include <linux/of_device.h>
//#include <asm/system.h> //#include <asm/system.h>
#include <asm/byteorder.h> // endians #include <asm/byteorder.h> // endians
#include <asm/io.h> #include <asm/io.h>
...@@ -57,7 +58,6 @@ ...@@ -57,7 +58,6 @@
//#include <asm/elphel/fpgaconfa.h> //#include <asm/elphel/fpgaconfa.h>
#include <elphel/exifa.h> #include <elphel/exifa.h>
//#include <elphel/x393_types.h> //#include <elphel/x393_types.h>
#include "x393.h"
//#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr //#include "fpgactrl.h" // defines port_csp0_addr, port_csp4_addr
//#include "fpga_sdram.h" // use a single fpga_initSDRAM(void) //#include "fpga_sdram.h" // use a single fpga_initSDRAM(void)
...@@ -74,6 +74,7 @@ ...@@ -74,6 +74,7 @@
//#include "gamma_tables.h" //#include "gamma_tables.h"
#include "quantization_tables.h" #include "quantization_tables.h"
#include "x393_macro.h" #include "x393_macro.h"
#include "x393.h"
#if ELPHEL_DEBUG #if ELPHEL_DEBUG
#define ELPHEL_DEBUG_THIS 0 #define ELPHEL_DEBUG_THIS 0
...@@ -97,6 +98,11 @@ ...@@ -97,6 +98,11 @@
#define MD13(x) #define MD13(x)
#endif #endif
/**
* @brief driver name to display in log messages
*/
#define IMAGEACQ_DRIVER_NAME "Elphel (R) Model 393 Image Acquisition device driver"
/**@struct jpeg_ptr_t /**@struct jpeg_ptr_t
* @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
...@@ -111,6 +117,8 @@ ...@@ -111,6 +117,8 @@
* IRQ number associated with compressor * IRQ number associated with compressor
* @var jpeg_ptr_t::irq_num_sens * @var jpeg_ptr_t::irq_num_sens
* IRQ number associated with sensor * IRQ number associated with sensor
* @var jpeg_ptr_t::chn_num
* Current channel number
*/ */
struct jpeg_ptr_t { struct jpeg_ptr_t {
volatile int jpeg_wp; volatile int jpeg_wp;
...@@ -118,6 +126,7 @@ struct jpeg_ptr_t { ...@@ -118,6 +126,7 @@ struct jpeg_ptr_t {
int fpga_cntr_prev; int fpga_cntr_prev;
unsigned int irq_num_comp; unsigned int irq_num_comp;
unsigned int irq_num_sens; unsigned int irq_num_sens;
unsigned int chn_num;
}; };
/**@struct image_acq_pd_t /**@struct image_acq_pd_t
...@@ -157,10 +166,29 @@ void camSeqSetJPEG_rp(int p) { ...@@ -157,10 +166,29 @@ void camSeqSetJPEG_rp(int p) {
End of compressor-related code - TODO: move to a separate file? End of compressor-related code - TODO: move to a separate file?
*/ */
/** static void dump_priv_data(int chn)
* @brief driver name to display in log messages {
*/ int i;
#define IMAGEACQ_DRIVER_NAME "Elphel (R) Model 393 Image Acquisition device driver"
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_rp: 0x%x\n", image_acq_priv.jpeg_ptr[chn].jpeg_rp);
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_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);
} else {
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_rp: 0x%x\n", image_acq_priv.jpeg_ptr[i].jpeg_rp);
printk(KERN_DEBUG "fpga_cntr_prev: 0x%x\n", image_acq_priv.jpeg_ptr[i].fpga_cntr_prev);
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 "chn_num: 0x%x\n", image_acq_priv.jpeg_ptr[i].chn_num);
}
}
}
static const struct of_device_id elphel393_sensor_of_match[]; static const struct of_device_id elphel393_sensor_of_match[];
static struct sensorproc_t s_sensorproc; // sensor parameters and functions to call static struct sensorproc_t s_sensorproc; // sensor parameters and functions to call
...@@ -186,36 +214,6 @@ struct sensorproc_t * copy_sensorproc (struct sensorproc_t * copy) ...@@ -186,36 +214,6 @@ struct sensorproc_t * copy_sensorproc (struct sensorproc_t * copy)
//#ifdef TEST_DISABLE_CODE //#ifdef TEST_DISABLE_CODE
/// When should it be called?
//int init_sensor(void);
/// Not yet used??
/**
* @brief Check FPGA version and initialize SDRAM (if not done yet)
* TODO: when should it be called?
* @return <0 error, 0 - just checked, nothing done,1 - needs sensor initialization
*/
int init_FPGA(void) { //will check FPGA version, init SDRAM (if needed) and sensor
int i;
// int f1,f2;
// Should be initial
if ((fpga_state & FPGA_STATE_LOADED) == 0) return -1; /// fpga is not configured
if ((i=port_csp0_addr[X313__RA__MODEL]) < X313_MINMODREV) {
printk ("too old fpga rev - found %x, software wants >= %x\n",i,X313_MINMODREV);
return -1; // too old FPGA
}
if (i > X313_MAXMODREV) {
printk ("too new fpga rev - found %x, software wants <= %x\n",i,X313_MAXMODREV);
return -1; // too new FPGA
}
fpga_state |= FPGA_STATE_INITIALIZED; /// what this initialization really mean?
if (!X313_IS_SDRAM_ON) fpga_initSDRAM();
// Was sensor initialized? (What if SDRAM was initialized by some application?)
MD1(printk("init_FPGA, fpga_state=0x%x\n",fpga_state));
if (X313_CHN0_USED!=0) return 0;
return 1;
}
/// ///
/// initializes structures for the image acquisition parameter /// initializes structures for the image acquisition parameter
...@@ -235,36 +233,40 @@ DECLARE_TASKLET(tasklet_fpga, tasklet_fpga_function, 0); /// 0 - no arguments fo ...@@ -235,36 +233,40 @@ DECLARE_TASKLET(tasklet_fpga, tasklet_fpga_function, 0); /// 0 - no arguments fo
/** /**
* @brief reads FPGA transfer pointer to update JPEG_wp * @brief Reads FPGA data pointer from the channel given and updates its JPEG_wp
* NOTE: should be called before compressor is reset - that would zero out that hardware register *
* @return 0 if compressor was off (no advance), 1 if write pointer did actually advance * This function gets current pointer inside frame buffer and compares it with the previous
* value. It returns immediately if pointer has not advanced or updates \e jpeg_wr field in #jpeg_ptr_t for
* current channel. It also tracks the situation when the pointer rolls over.
* @param[in] jptr pointer to #jpeg_ptr_t structure for the channel which data is to be modified
* @return 0 if compressor was off (no advance) or 1 if write pointer did actually advance
*/ */
inline int updateIRQJPEG_wp(void) { static inline int updateIRQJPEG_wp(struct jpeg_ptr_t *jptr)
int xferred; /// number of 32-byte chunks transferred since compressor was reset {
int fpga_cntr= X313_XFERCNTR; /// using macro defined in x353.h that makes a dummy read (reads after writes can be wrong) int xferred; /// number of 32-byte chunks transferred since compressor was reset
xferred= fpga_cntr-fpga_counter_prev; /// Transferred since last JPEG_wp update (or counter reset) x393_afimux_status_t stat = x393_afimux0_status(jptr->chn_num);
#if 0 /// ELPHEL_DEBUG_THIS- address changed !!! int circbuf_size = get_globalParam(G_CIRCBUFSIZE) >> 2;
set_globalParam (0x300,get_globalParam (0x300)+1);
set_globalParam (0x302,fpga_cntr); xferred = stat.offset256 - jptr->fpga_cntr_prev;
if (xferred==0) set_globalParam (0x305,get_globalParam (0x305)+1); if (xferred == 0)
#endif return 0; /// no advance (compressor was off?)
if (xferred==0) return 0; /// no advance (compressor was off?)
fpga_counter_prev= fpga_cntr; jptr->fpga_cntr_prev = stat.offset256;
if (xferred <0) xferred+= (1 <<24) ; /// Hardware counter is 24 bits - rolled over if (xferred < 0)
JPEG_wp+= (xferred << 3); //! counts in 32-byte ( 8 of 32bit words) chunks // 26 bit hardware counter rolled over
int circbuf_size=get_globalParam (G_CIRCBUFSIZE)>>2; //G_CIRCBUFSIZE G_CIRCBUFRP xferred += (1 << OFFSET256_CNTR_RES);
if (JPEG_wp > circbuf_size) JPEG_wp-=circbuf_size; jptr->jpeg_wp += xferred * CHUNK_SIZE;
#if 0 ///ELPHEL_DEBUG_THIS - address changed !!! //JPEG_wp+= (xferred << 3); //! counts in 32-byte ( 8 of 32bit words) chunks
set_globalParam (0x301,get_globalParam (0x301)+1); if (jptr->jpeg_wp > circbuf_size)
set_globalParam (0x303,xferred); jptr->jpeg_wp -= circbuf_size;
set_globalParam (0x304,JPEG_wp);
#endif return 1;
return 1;
} }
/** /**
* @brief Calculate/update CIRCBUF parameters available after compressor interrupt * @brief Calculate/update CIRCBUF parameters available after compressor interrupt
*/ */
inline void updateIRQCircbuf(void) { inline void update_irq_circbuf(struct jpeg_ptr_t *jptr) {
set_globalParam (G_CIRCBUFWP, JPEG_wp<<2); set_globalParam (G_CIRCBUFWP, JPEG_wp<<2);
set_globalParam (G_FREECIRCBUF, (((get_globalParam (G_CIRCBUFRP) <= get_globalParam (G_CIRCBUFWP))? get_globalParam (G_CIRCBUFSIZE):0)+ set_globalParam (G_FREECIRCBUF, (((get_globalParam (G_CIRCBUFRP) <= get_globalParam (G_CIRCBUFWP))? get_globalParam (G_CIRCBUFSIZE):0)+
get_globalParam (G_CIRCBUFRP)) - get_globalParam (G_CIRCBUFWP)); get_globalParam (G_CIRCBUFRP)) - get_globalParam (G_CIRCBUFWP));
...@@ -275,8 +277,8 @@ inline void updateIRQCircbuf(void) { ...@@ -275,8 +277,8 @@ inline void updateIRQCircbuf(void) {
* NOTE: currently global (latest), not per-frame * NOTE: currently global (latest), not per-frame
*/ */
inline void updateIRQFocus(void) { inline void updateIRQFocus(void) {
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);
} }
...@@ -311,6 +313,7 @@ inline struct interframe_params_t* updateIRQ_interframe(void) { ...@@ -311,6 +313,7 @@ inline struct interframe_params_t* updateIRQ_interframe(void) {
*/ */
inline void updateIRQ_Exif(struct interframe_params_t* interframe) { inline void updateIRQ_Exif(struct interframe_params_t* interframe) {
int index_time = JPEG_wp-11; if (index_time<0) index_time+=get_globalParam (G_CIRCBUFSIZE)>>2; int index_time = JPEG_wp-11; if (index_time<0) index_time+=get_globalParam (G_CIRCBUFSIZE)>>2;
#ifdef TES_DISABLE_CODE
/// calculates datetime([20] and subsec[7], returns pointer to char[27] /// calculates datetime([20] and subsec[7], returns pointer to char[27]
char * exif_meta_time_string=encode_time(ccam_dma_buf_ptr[index_time], ccam_dma_buf_ptr[index_time+1]); char * exif_meta_time_string=encode_time(ccam_dma_buf_ptr[index_time], ccam_dma_buf_ptr[index_time+1]);
/// may be split in datetime/subsec - now it will not notice missing subseq field in template /// may be split in datetime/subsec - now it will not notice missing subseq field in template
...@@ -369,6 +372,8 @@ inline void updateIRQ_Exif(struct interframe_params_t* interframe) { ...@@ -369,6 +372,8 @@ inline void updateIRQ_Exif(struct interframe_params_t* interframe) {
// left 1 long spare (+44) // left 1 long spare (+44)
} }
interframe->meta_index=store_meta(); interframe->meta_index=store_meta();
#endif /* TES_DISABLE_CODE */
} }
...@@ -379,7 +384,7 @@ inline void updateIRQ_Exif(struct interframe_params_t* interframe) { ...@@ -379,7 +384,7 @@ inline void updateIRQ_Exif(struct interframe_params_t* interframe) {
* @param dev_id * @param dev_id
* @return * @return
*/ */
static irqreturn_t elphel_FPGA_interrupt(int irq, void *dev_id) { /*static irqreturn_t elphel_FPGA_interrupt(int irq, void *dev_id) {
unsigned long irq_state; unsigned long irq_state;
irq_state = X313_IRQSTATE; //!making dummy read - see c353.h irq_state = X313_IRQSTATE; //!making dummy read - see c353.h
...@@ -407,7 +412,7 @@ static irqreturn_t elphel_FPGA_interrupt(int irq, void *dev_id) { ...@@ -407,7 +412,7 @@ static irqreturn_t elphel_FPGA_interrupt(int irq, void *dev_id) {
EN_INTERRUPT(SMART); EN_INTERRUPT(SMART);
return IRQ_HANDLED; return IRQ_HANDLED;
} }*/
/** /**
* @brief Handle interrupts from sensor channels. This handler is installed without SA_INTERRUPT * @brief Handle interrupts from sensor channels. This handler is installed without SA_INTERRUPT
...@@ -419,7 +424,12 @@ static irqreturn_t elphel_FPGA_interrupt(int irq, void *dev_id) { ...@@ -419,7 +424,12 @@ static irqreturn_t elphel_FPGA_interrupt(int irq, void *dev_id) {
*/ */
static irqreturn_t frame_sync_irq_handler(int irq, void *dev_id) static irqreturn_t frame_sync_irq_handler(int irq, void *dev_id)
{ {
struct jpeg_ptr_t *priv = dev_id;
update_frame_pars(); update_frame_pars();
wake_up_interruptible(&framepars_wait_queue);
tasklet_schedule(&tasklet_fpga);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -433,6 +443,23 @@ static irqreturn_t frame_sync_irq_handler(int irq, void *dev_id) ...@@ -433,6 +443,23 @@ static irqreturn_t frame_sync_irq_handler(int irq, void *dev_id)
*/ */
static irqreturn_t compressor_irq_handler(int irq, void *dev_id) static irqreturn_t compressor_irq_handler(int irq, void *dev_id)
{ {
struct jpeg_ptr_t *priv = dev_id;
struct interframe_params_t *interframe;
x393_cmprs_interrupts_t irq_ctrl;
if (updateIRQJPEG_wp(priv)) {
/*update_irq_circbuf(priv);
updateIRQFocus();
interframe = updateIRQ_interframe();
updateIRQ_Exif(interframe);
wake_up_interruptible(&circbuf_wait_queue);*/
}
//wake_up_interruptible(&framepars_wait_queue);
tasklet_schedule(&tasklet_fpga);
irq_ctrl.interrupt_cmd = IRQ_CLEAR;
x393_cmprs_interrupts(irq_ctrl, priv->chn_num);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
...@@ -468,8 +495,13 @@ void tasklet_fpga_function(unsigned long arg) { ...@@ -468,8 +495,13 @@ void tasklet_fpga_function(unsigned long arg) {
unsigned long prevFrameNumber=thisFrameNumber-1; unsigned long prevFrameNumber=thisFrameNumber-1;
unsigned long * hash32p=&(framepars[(thisFrameNumber-1) & PARS_FRAMES_MASK].pars[P_GTAB_R]); unsigned long * hash32p=&(framepars[(thisFrameNumber-1) & PARS_FRAMES_MASK].pars[P_GTAB_R]);
unsigned long * framep= &(framepars[(thisFrameNumber-1) & PARS_FRAMES_MASK].pars[P_FRAME]); unsigned long * framep= &(framepars[(thisFrameNumber-1) & PARS_FRAMES_MASK].pars[P_FRAME]);
dump_priv_data(0);
#ifdef TEST_DISABLE_CODE
/// Time is out? /// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
#endif /* TEST_DISABLE_CODE */
/// Histograms are available for the previous frame (that is already in circbuf if compressor was running) /// Histograms are available for the previous frame (that is already in circbuf if compressor was running)
/// Is Y histogram needed? /// Is Y histogram needed?
PROFILE_NOW(2); PROFILE_NOW(2);
...@@ -493,6 +525,7 @@ void tasklet_fpga_function(unsigned long arg) { ...@@ -493,6 +525,7 @@ void tasklet_fpga_function(unsigned long arg) {
default: /// calculate always (safer) default: /// calculate always (safer)
hist_en=1; hist_en=1;
} }
#ifdef TEST_DISABLE_CODE
if (hist_en) { if (hist_en) {
/// after updateFramePars gammaHash are from framepars[this-1] /// after updateFramePars gammaHash are from framepars[this-1]
set_histograms (prevFrameNumber, (1 << COLOR_Y_NUMBER), hash32p, framep); /// 0x2 Green1 set_histograms (prevFrameNumber, (1 << COLOR_Y_NUMBER), hash32p, framep); /// 0x2 Green1
...@@ -507,14 +540,17 @@ void tasklet_fpga_function(unsigned long arg) { ...@@ -507,14 +540,17 @@ void tasklet_fpga_function(unsigned long arg) {
wake_up_interruptible(&hist_y_wait_queue); /// wait queue for the G1 histogram (used as Y) wake_up_interruptible(&hist_y_wait_queue); /// wait queue for the G1 histogram (used as Y)
} }
#endif #endif
#endif /* TEST_DISABLE_CODE */
/// Process parameters /// Process parameters
if ((tasklet_disable & (1 << TASKLET_CTL_PGM)) == 0) { if ((tasklet_disable & (1 << TASKLET_CTL_PGM)) == 0) {
processPars (sensorproc, getThisFrameNumber(), get_globalParam(G_MAXAHEAD)); /// program parameters processPars (sensorproc, getThisFrameNumber(), get_globalParam(G_MAXAHEAD)); /// program parameters
PROFILE_NOW(4); PROFILE_NOW(4);
} }
#ifdef TEST_DISABLE_CODE
/// Time is out? /// Time is out?
if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame if ((getThisFrameNumber() ^ X3X3_I2C_FRAME) & PARS_FRAMES_MASK) return; /// already next frame
/// Are C histograms needed? /// Are C histograms needed?
#endif /* TEST_DISABLE_CODE */
switch ((tasklet_disable >> TASKLET_CTL_HISTC_BIT) & 7) { switch ((tasklet_disable >> TASKLET_CTL_HISTC_BIT) & 7) {
case TASKLET_HIST_NEVER: /// never calculate case TASKLET_HIST_NEVER: /// never calculate
hist_en=0; hist_en=0;
...@@ -542,6 +578,7 @@ GLOBALPARS(0x1042)=((thisFrameNumber & 7) ==0); ...@@ -542,6 +578,7 @@ GLOBALPARS(0x1042)=((thisFrameNumber & 7) ==0);
GLOBALPARS(0x1043)=hist_en; GLOBALPARS(0x1043)=hist_en;
GLOBALPARS(0x1044)=thisFrameNumber; GLOBALPARS(0x1044)=thisFrameNumber;
*/ */
#ifdef TEST_DISABLE_CODE
if (hist_en) { if (hist_en) {
/// after updateFramePars gammaHash are from framepars[this-1] /// after updateFramePars gammaHash are from framepars[this-1]
set_histograms (prevFrameNumber, 0xf, hash32p, framep); /// all 4 colors, including Y (it will be skipped) set_histograms (prevFrameNumber, 0xf, hash32p, framep); /// all 4 colors, including Y (it will be skipped)
...@@ -556,6 +593,7 @@ GLOBALPARS(0x1044)=thisFrameNumber; ...@@ -556,6 +593,7 @@ GLOBALPARS(0x1044)=thisFrameNumber;
wake_up_interruptible(&hist_c_wait_queue); /// wait queue for all the other (R,G2,B) histograms (color) wake_up_interruptible(&hist_c_wait_queue); /// wait queue for all the other (R,G2,B) histograms (color)
} }
#endif #endif
#endif /* TEST_DISABLE_CODE */
} }
//#endif /* TEST_DISABLE_CODE */ //#endif /* TEST_DISABLE_CODE */
...@@ -585,29 +623,29 @@ void reset_compressor(void) { ...@@ -585,29 +623,29 @@ void reset_compressor(void) {
* @param on 1 - enable, 0 - disable interrupts * @param on 1 - enable, 0 - disable interrupts
*/ */
void camera_interrupts (int on) { void camera_interrupts (int on) {
MDF2(printk ("camera_interrupts(%d)\n",on)); int i;
x393_cmprs_interrupts_t irq_ctrl;
MDF2(printk ("camera_interrupts(%d)\n",on));
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
if (on) { if (on) {
EN_INTERRUPT(SMART); EN_INTERRUPT(SMART);
} else { } else {
DIS_INTERRUPTS; DIS_INTERRUPTS;
} }
/// clear smart interrupt circuitry in any case /// clear smart interrupt circuitry in any case
port_csp0_addr[X313_WA_SMART_IRQ]=0x8000; port_csp0_addr[X313_WA_SMART_IRQ]=0x8000;
reg_intr_vect_rw_mask intr_mask; reg_intr_vect_rw_mask intr_mask;
intr_mask = REG_RD(intr_vect, regi_irq, rw_mask); intr_mask = REG_RD(intr_vect, regi_irq, rw_mask);
intr_mask.ext = on ? 1 : 0; intr_mask.ext = on ? 1 : 0;
REG_WR(intr_vect, regi_irq, rw_mask, intr_mask); REG_WR(intr_vect, regi_irq, rw_mask, intr_mask);
#endif /* TEST_DISABLE_CODE */ #endif /* TEST_DISABLE_CODE */
x393_arbite_pri_t val; irq_ctrl.interrupt_cmd = on ? IRQ_ENABLE : IRQ_DISABLE;
for (i = 0; i < IMAGE_CHN_NUM; i++) {
val = get_x393_mcntrl_arbiter_priority(0); x393_cmprs_interrupts(irq_ctrl, i);
if (val.d32 == 1) }
printk("1");
else
printk("2");
} }
//EXPORT_SYMBOL_GPL(camera_interrupts); //EXPORT_SYMBOL_GPL(camera_interrupts);
...@@ -616,23 +654,23 @@ void camera_interrupts (int on) { ...@@ -616,23 +654,23 @@ void camera_interrupts (int on) {
* @param[in] pdev pointer to \b platform_device structure * @param[in] pdev pointer to \b platform_device structure
* @return 0 on success or negative error code otherwise * @return 0 on success or negative error code otherwise
*/ */
static int image_acq_init(struct platform_device *pdev) //static int image_acq_init(struct platform_device *pdev)
int image_acq_init(struct platform_device *pdev)
{ {
int i; int i;
int res; int res;
unsigned int irq; unsigned int irq;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
const struct of_device_id *match; const struct of_device_id *match;
const char **frame_sync_irq_names = { "frame_sync_irq_0", "frame_sync_irq_1", const char *frame_sync_irq_names[4] = {"frame_sync_irq_0", "frame_sync_irq_1",
"frame_sync_irq_2", "frame_sync_irq_3" }; "frame_sync_irq_2", "frame_sync_irq_3"};
const char **compressor_irq_names = { "compr_irq_0", "compr_irq_1", const char *compressor_irq_names[4] = {"compr_irq_0", "compr_irq_1",
"compr_irq_2", "compr_irq_3" "compr_irq_2", "compr_irq_3"};
};
/* sanity check */ /* sanity check */
match = of_match_device(elphel393_sensor_of_match, dev); /*match = of_match_device(elphel393_sensor_of_match, dev);
if (!match) if (!match)
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));
...@@ -644,24 +682,30 @@ static int image_acq_init(struct platform_device *pdev) ...@@ -644,24 +682,30 @@ static int image_acq_init(struct platform_device *pdev)
0, // no flags 0, // no flags
frame_sync_irq_names[i], frame_sync_irq_names[i],
&image_acq_priv.jpeg_ptr[i])) { &image_acq_priv.jpeg_ptr[i])) {
printk(KERN_ERR "Can not allocate Elphel FPGA interrupts"); dev_err(dev, "can not allocate Elphel FPGA interrupts\n");
return -EBUSY; return -EBUSY;
} }
image_acq_priv.jpeg_ptr[i].irq_num_sens = irq;
}
for (i = 0; i < IMAGE_CHN_NUM; i++) {
irq = platform_get_irq_byname(pdev, compressor_irq_names[i]); irq = platform_get_irq_byname(pdev, compressor_irq_names[i]);
if (request_irq(irq, if (request_irq(irq,
compressor_irq_handler, compressor_irq_handler,
0, // no flags 0, // no flags
compressor_irq_names[i], compressor_irq_names[i],
&image_acq_priv.jpeg_ptr[i])) { &image_acq_priv.jpeg_ptr[i])) {
printk(KERN_ERR "Can not allocate Elphel FPGA interrupts"); dev_err(dev, "can not allocate Elphel FPGA interrupts\n");
return -EBUSY; return -EBUSY;
} }
image_acq_priv.jpeg_ptr[i].irq_num_sens = irq;
image_acq_priv.jpeg_ptr[i].irq_num_comp = irq; image_acq_priv.jpeg_ptr[i].irq_num_comp = irq;
image_acq_priv.jpeg_ptr[i].chn_num = i;
} }
if (init_mmio_ptr() < 0) {
dev_err(dev, "unable to remap FPGA registers to memory region\n");
return -EINVAL;
}
#ifdef TEST_DISABLE_CODE #ifdef TEST_DISABLE_CODE
if(request_irq(EXT_INTR_VECT, if(request_irq(EXT_INTR_VECT,
...@@ -690,7 +734,7 @@ static int image_acq_init(struct platform_device *pdev) ...@@ -690,7 +734,7 @@ static int image_acq_init(struct platform_device *pdev)
return 0; return 0;
} }
static int image_acq_stop(struct platform_device *pdev) int image_acq_stop(struct platform_device *pdev)
{ {
return 0; return 0;
} }
...@@ -701,16 +745,16 @@ static const struct of_device_id elphel393_sensor_of_match[] = { ...@@ -701,16 +745,16 @@ static const struct of_device_id elphel393_sensor_of_match[] = {
}; };
MODULE_DEVICE_TABLE(of, elphel393_sensor_of_match); MODULE_DEVICE_TABLE(of, elphel393_sensor_of_match);
static struct platform_driver elphel393_sensor_common = { /*static struct platform_driver elphel393_sensor_common = {
.probe = image_acq_init, .probe = image_acq_init,
.remove = image_acq_stop, .remove = image_acq_stop,
.driver = { .driver = {
.name = IMAGEACQ_DRIVER_NAME, .name = IMAGEACQ_DRIVER_NAME,
.of_match_table = elphel393_sensor_of_match, .of_match_table = elphel393_sensor_of_match,
} }
}; };*/
module_platform_driver(elphel393_sensor_common); //module_platform_driver(elphel393_sensor_common);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>."); MODULE_AUTHOR("Andrey Filippov <andrey@elphel.com>.");
......
...@@ -45,4 +45,6 @@ struct sensorproc_t * copy_sensorproc (struct sensorproc_t * copy); ...@@ -45,4 +45,6 @@ struct sensorproc_t * copy_sensorproc (struct sensorproc_t * copy);
#define PROFILE_NEXT(x) {} #define PROFILE_NEXT(x) {}
#endif #endif
int image_acq_init(struct platform_device *pdev);
#endif #endif
...@@ -5,8 +5,18 @@ ...@@ -5,8 +5,18 @@
#ifndef _X393_MACRO #ifndef _X393_MACRO
#define _X393_MACRO #define _X393_MACRO
/** @brief Number of image channels*/ /** @brief Number of image channels */
#define IMAGE_CHN_NUM 4 #define IMAGE_CHN_NUM 4
/** @brief Resolution of current/OEF pointer in bits */
#define OFFSET256_CNTR_RES 26
#define CHUNK_SIZE 32
#define IRQ_NOP 0
#define IRQ_CLEAR 1
#define IRQ_DISABLE 2
#define IRQ_ENABLE 3
/* 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
......
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