@@ -25,10 +25,10 @@ int exif_enable_chn(int sensor_port, int en); // enable/disable Exif process
...
@@ -25,10 +25,10 @@ int exif_enable_chn(int sensor_port, int en); // enable/disable Exif process
intexif_enable(inten);// For all sensor ports
intexif_enable(inten);// For all sensor ports
intdir_find_tag(unsignedlongtag);//!find location of the tag field in meta page using long tag (Exif tag and tag group)
intdir_find_tag(unsignedlongtag);//!find location of the tag field in meta page using long tag (Exif tag and tag group)
inlinevoidwrite_meta_raw_irq(intsensor_port,char*data,intoffset,intlen);//write data to meta, called from IRQ
voidwrite_meta_raw_irq(intsensor_port,char*data,intoffset,intlen);//write data to meta, called from IRQ
inlineintwrite_meta_irq(intsensor_port,char*data,int*indx,unsignedlongltag,intlen);//write data to meta, called from IRQ(len==0 => use field length)
intwrite_meta_irq(intsensor_port,char*data,int*indx,unsignedlongltag,intlen);//write data to meta, called from IRQ(len==0 => use field length)
inlinevoidputlong_meta_raw_irq(intsensor_port,unsignedlongdata,intoffset);//write data to meta (4 bytes, big endian), called from IRQ
voidputlong_meta_raw_irq(intsensor_port,unsignedlongdata,intoffset);//write data to meta (4 bytes, big endian), called from IRQ
inlineintputlong_meta_irq(intsensor_port,unsignedlongdata,int*indx,unsignedlongltag);//write data to meta (4 bytes, big endian), from IRQ
intputlong_meta_irq(intsensor_port,unsignedlongdata,int*indx,unsignedlongltag);//write data to meta (4 bytes, big endian), from IRQ
//void write_meta_raw_irq(char * data, int offset, int len); //write data to meta, called from IRQ
//void write_meta_raw_irq(char * data, int offset, int len); //write data to meta, called from IRQ
//int write_meta_irq(char * data, int * indx, unsigned long ltag, int len); //write data to meta, called from IRQ(len==0 => use field length). Returns index of the written data, -1 if not written
//int write_meta_irq(char * data, int * indx, unsigned long ltag, int len); //write data to meta, called from IRQ(len==0 => use field length). Returns index of the written data, -1 if not written
...
@@ -37,7 +37,7 @@ int write_meta(int sensor_port, char * data, int * indx, unsigned long ltag, in
...
@@ -37,7 +37,7 @@ int write_meta(int sensor_port, char * data, int * indx, unsigned long ltag, in
voidputlong_meta_raw(intsensor_port,unsignedlongdata,intoffset);//write data to meta (4 bytes, big endian), called from outside IRQ (atomic)
voidputlong_meta_raw(intsensor_port,unsignedlongdata,intoffset);//write data to meta (4 bytes, big endian), called from outside IRQ (atomic)
intputlong_meta(intsensor_port,unsignedlongdata,int*indx,unsignedlongltag);//write data to meta (4 bytes, big endian), from outside IRQ (atomic). Returns index of the written data, -1 if not written
intputlong_meta(intsensor_port,unsignedlongdata,int*indx,unsignedlongltag);//write data to meta (4 bytes, big endian), from outside IRQ (atomic). Returns index of the written data, -1 if not written
#define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver"
#define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver"
staticstructframepars_all_tsFrameParsAll__attribute__((aligned(PAGE_SIZE)));///< Sensor Parameters, currently 8 pages all and 2048 pages some, static struct
/* 393: sFrameParsAll is an array of 4per-port structures */
staticstructframepars_all_tsFrameParsAll[SENSOR_PORTS]__attribute__((aligned(PAGE_SIZE)));///< Sensor Parameters, currently 16 pages all and 2048 pages some, static struct
unsignedlongframeParsInitialized;/// set to 0 at startup, 1 after initialization that is triggered by setParsAtomic()
unsignedlongframeParsInitialized;/// set to 0 at startup, 1 after initialization that is triggered by setParsAtomic()
#define thisFrameNumber GLOBALPARS(G_THIS_FRAME) // Current frame number (may lag from the hardware)
#define thisFrameNumber(p) GLOBALPARS(p,G_THIS_FRAME) // Current frame number (may lag from the hardware)
//#define THISFRAMENUMBER GLOBALPARS(G_THIS_FRAME) // Current frame number (may lag from the hardware)
#ifdef NC353
structframepars_all_t*frameparsall=NULL;/// - will be mmap-ed
structframepars_all_t*frameparsall=NULL;/// - will be mmap-ed
structframepars_t*framepars=NULL;///< getting rid of static to be able to use extern
structframepars_t*framepars=NULL;///< getting rid of static to be able to use extern
structframepars_past_t*pastpars=NULL;///< getting rid of static to be able to use extern
structframepars_past_t*pastpars=NULL;///< getting rid of static to be able to use extern
unsignedlong*funcs2call=NULL;/// sFrameParsAll.func2call.pars; - each parameter has a 32-bit mask of what pgm_function to call - other fields not used
unsignedlong*funcs2call=NULL;/// sFrameParsAll.func2call.pars; - each parameter has a 32-bit mask of what pgm_function to call - other fields not used
unsignedlong*globalPars=NULL;/// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both
unsignedlong*globalPars=NULL;/// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both
unsignedlong*multiSensIndex=NULL;/// index for per-sensor alternatives
unsignedlong*multiSensIndex=NULL;/// index for per-sensor alternatives
unsignedlong*multiSensRvrsIndex=NULL;/// reverse index (to parent) for the multiSensIndex
unsignedlong*multiSensRvrsIndex=NULL;/// reverse index (to parent) for the multiSensIndex
wait_queue_head_tframepars_wait_queue;/// used to wait for the frame to be acquired
wait_queue_head_tframepars_wait_queue;/// used to wait for the frame to be acquired
#endif
/* 393 : Changing to per-port */
structframepars_all_t*aframeparsall=NULL;/// - will be mmap-ed, in 393 points to an array of structures
structframepars_t*aframepars[SENSOR_PORTS];///< getting rid of static to be able to use extern
structframepars_past_t*apastpars[SENSOR_PORTS];///< getting rid of static to be able to use extern
unsignedlong*afuncs2call[SENSOR_PORTS];/// sFrameParsAll.func2call.pars; - each parameter has a 32-bit mask of what pgm_function to call - other fields not used
unsignedlong*aglobalPars[SENSOR_PORTS];/// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both
unsignedlong*amultiSensIndex[SENSOR_PORTS];/// index for per-sensor alternatives
unsignedlong*amultiSensRvrsIndex[SENSOR_PORTS];/// reverse index (to parent) for the multiSensIndex
wait_queue_head_taframepars_wait_queue[SENSOR_PORTS];/// used to wait for the frame to be acquired
globalPars=sFrameParsAll.globalPars;/// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both
afuncs2call[sensor_port]=sFrameParsAll[sensor_port].func2call.pars;/// each parameter has a 32-bit mask of what pgm_function to call - other fields not used
multiSensIndex=sFrameParsAll.multiSensIndex;/// indexes of individual sensor register shadows (first of 3) - now for all parameters, not just sensor ones
aglobalPars[sensor_port]=sFrameParsAll[sensor_port].globalPars;/// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both
multiSensRvrsIndex=sFrameParsAll.multiSensRvrsIndex;/// reverse index (to parent) for the multiSensIndex
amultiSensIndex[sensor_port]=sFrameParsAll[sensor_port].multiSensIndex;/// indexes of individual sensor register shadows (first of 3) - now for all parameters, not just sensor ones
amultiSensRvrsIndex[sensor_port]=sFrameParsAll[sensor_port].multiSensRvrsIndex;/// reverse index (to parent) for the multiSensIndex
for(i=0;i<P_SENSOR_NUMREGS;i++)funcs2call[P_SENSOR_REGS+i]=ONCHANGE_SENSORREGS;/// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
for(i=0;i<P_SENSOR_NUMREGS;i++)afuncs2call[sensor_port][P_SENSOR_REGS+i]=ONCHANGE_SENSORREGS;/// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
/// Same for 10359 registers - will not change anything if there is no 10359 - these registers will not be chnaged, and if will be it wil cause no action
/// Same for 10359 registers - will not change anything if there is no 10359 - these registers will not be changed, and if will be it wil cause no action
for(i=0;i<P_M10359_NUMREGS;i++)funcs2call[P_M10359_REGS+i]=ONCHANGE_SENSORREGS;/// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
for(i=0;i<P_M10359_NUMREGS;i++)afuncs2call[sensor_port][P_M10359_REGS+i]=ONCHANGE_SENSORREGS;/// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
initMultiPars();/// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection
initMultiPars(sensor_port);/// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection
frameParsInitialized=1;
frameParsInitialized=1;
}
}
/**
/**
* @brief reset all global parameters, set default for debug mask (if ELPHEL_DEBUG)
* @brief reset all global parameters, set default for debug mask (if ELPHEL_DEBUG)
* @brief initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection
* @brief initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection
* @param sensor_port sensor port number (0..3)
* @return number of multi-regs
* @return number of multi-regs
*/
*/
intinitMultiPars(void)
intinitMultiPars(intsensor_port)
{
{
inti,j,n;
inti,j,n;
intireg=P_MULTI_REGS;/// multi-reg shadows start index
intireg=P_MULTI_REGS;/// multi-reg shadows start index
// remark: the line below is called from initFramePars, consider removing it
// remark: the line below is called from initFramePars, consider removing it
for(i=0;i<P_SENSOR_NUMREGS;i++)funcs2call[P_SENSOR_REGS+i]=ONCHANGE_SENSORREGS;/// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
for(i=0;i<P_SENSOR_NUMREGS;i++)afuncs2call[sensor_port][P_SENSOR_REGS+i]=ONCHANGE_SENSORREGS;/// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
/// Now update interframe_pars (interframe area) used to create JPEG headers. Interframe area survives exactly as long as the frames themselves (not like pastpars)
/// Now update interframe_pars (interframe area) used to create JPEG headers. Interframe area survives exactly as long as the frames themselves (not like pastpars)
if(interframe_pars){/// frame was compressed, not just vsync
if(interframe_pars){/// frame was compressed, not just vsync
///TODO: get rid of *_prev, use it for the future.
///TODO: get rid of *_prev, use it for the future.
memcpy(interframe_pars,&framepars[findex_this].pars[P_GTAB_R],24);/// will leave some gaps, but copy [P_ACTUAL_WIDTH]
memcpy(interframe_pars,&framepars[findex_this].pars[P_GTAB_R],24);/// will leave some gaps, but copy [P_ACTUAL_WIDTH]
interframe_pars->height=framepars[findex_this].pars[P_ACTUAL_HEIGHT];/// NOTE: P_ACTUAL_WIDTH,P_QUALITY copied with memcpy
interframe_pars->height=framepars[findex_this].pars[P_ACTUAL_HEIGHT];/// NOTE: P_ACTUAL_WIDTH,P_QUALITY copied with memcpy
MDF7(printk("resubmitting past due functions = 0x%lx for frame=%ld (0x%x)\n",framepars[findex_this].functions,thisFrameNumber,findex_this));
MDF7(printk("resubmitting past due functions = 0x%lx for frame=%ld (0x%x)\n",framepars[findex_this].functions,thisFrameNumber(sensor_port),findex_this));
}else{
}else{
MDF(printk("Ignored past due functions = 0x%lx for frame=%ld (0x%x)\n",framepars[findex_this].functions,thisFrameNumber,findex_this));
MDF(printk("Ignored past due functions = 0x%lx for frame=%ld (0x%x)\n",framepars[findex_this].functions,thisFrameNumber(sensor_port),findex_this));
}
}
}
}
thisFrameNumber++;
thisFrameNumber(sensor_port)++;
}
}
}
}
voidupdate_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)
* Called twice from processPars - at the beginning and at the end to finish off any derivatives (needed?)
* Called twice from processPars - at the beginning and at the end to finish off any derivatives (needed?)
// processParsSeq (sensorproc, thisFrameNumber & PARS_FRAMES_MASK, 0); ///maxahead=0, the rest will be processed after frame sync, from the tasklet
// processParsSeq (sensorproc, thisFrameNumber & PARS_FRAMES_MASK, 0); ///maxahead=0, the rest will be processed after frame sync, from the tasklet
MDF5(printk("\n"));
MDF5(printk("\n"));
processPars(sensorproc,thisFrameNumber&PARS_FRAMES_MASK,0);///maxahead=0, the rest will be processed after frame sync, from the tasklet
processPars(sensor_port,sensorproc,thisFrameNumber(sensor_port)&PARS_FRAMES_MASK,0);///maxahead=0, the rest will be processed after frame sync, from the tasklet
}
}
PROFILE_NOW(7);
PROFILE_NOW(7);
D1I(local_irq_restore(flags));
D1I(local_irq_restore(flags));
...
@@ -764,24 +849,27 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc
...
@@ -764,24 +849,27 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc
// (like "single frame" - compressor, sensor) first write "stop", then - "single" with FRAMEPAIR_JUST_THIS
// (like "single frame" - compressor, sensor) first write "stop", then - "single" with FRAMEPAIR_JUST_THIS
/**
/**
* @brief set a single output (calculated) parameter for the frame referenced by this_framepars structure.
* @brief set a single output (calculated) parameter for the frame referenced by this_framepars structure.
* Shedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in mindex
* Schedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in mindex
* @param sensor_port sensor port number (0..3)
* @param this_framepars pointer to the current parameters structure
* @param this_framepars pointer to the current parameters structure
* @param mindex parameter number (with optional modifiers in high bits)
* @param mindex parameter number (with optional modifiers in high bits)
///TODO: init framepars (zero parameters) before initscripts (not when detecting the sensors) - then initscript will be able to overwrite some
///TODO: init framepars (zero parameters) before initscripts (not when detecting the sensors) - then initscript will be able to overwrite some
voidinit_framepars_ptr(void);
voidinit_framepars_ptr(intsensor_port);
voidinitSequencers(void);///Move to sensorcommon? currently it is used through frameparsall file (lseek)
voidinitSequencers(intsensor_port);///Move to sensorcommon? currently it is used through frameparsall file (lseek)
voidinitGlobalPars(void);/// resets all global parameters but debug mask (if ELPHEL_DEBUG)
voidinitGlobalPars(intsensor_port);/// resets all global parameters but debug mask (if ELPHEL_DEBUG)
intinitMultiPars(void);/// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called aftre/during sensor detection
intinitMultiPars(intsensor_port);/// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called aftre/during sensor detection
voidinitFramePars(void);///initialize all parameters, set thisFrameNumber to frame8 (read from hardware, usually 0 after resetting i2c and cmd_seq)
voidinitFramePars(intsensor_port);///initialize all parameters, set thisFrameNumber to frame8 (read from hardware, usually 0 after resetting i2c and cmd_seq)
voidresetFrameNumber(void);/// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow)
voidresetFrameNumber(intsensor_port);/// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow)
voidupdateFramePars(intsensor_port,intframe8,structinterframe_params_t*frame_pars);/// called from ISR - advance thisFrameNumber to match hardware frame8, copy parameters as needed.
voidupdateFramePars(intframe8,structinterframe_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
unsignedlonggetThisFrameNumber(void);/// just return current thisFrameNumber
unsignedlonggetThisFrameNumber(intsensor_port);/// just return current thisFrameNumber
/// set parameters for the frame number frameno, knowing that they should be set not less than maxLatency ahead (may be sensor - dependent)
/// set parameters for the frame number frameno, knowing that they should be set not less than maxLatency ahead (may be sensor - dependent)
/// Parameters (numPars of them) will be updated all at once, with interrupts disabled
/// Parameters (numPars of them) will be updated all at once, with interrupts disabled
/// Return - 0 if OK, -ERR_FRAMEPARS_TOOEARLY or -ERR_FRAMEPARS_TOOLATE if it is too early or too late to set parameters (numPars may be 0 to just test)
/// Return - 0 if OK, -ERR_FRAMEPARS_TOOEARLY or -ERR_FRAMEPARS_TOOLATE if it is too early or too late to set parameters (numPars may be 0 to just test)
...
@@ -42,27 +43,28 @@ unsigned long getThisFrameNumber(void); /// just return current thisFrameNumber
...
@@ -42,27 +43,28 @@ unsigned long getThisFrameNumber(void); /// just return current thisFrameNumber
/// TODO: Make (an "unlimited") future commands que based on lists and a tree frame index
/// TODO: Make (an "unlimited") future commands que based on lists and a tree frame index
///NOTE: If profiling is enabled (TASKLET_CTL_ENPROF is set in G_TASKLET_CTL) - save current time in 2 of the 32-bit locations that can be read as pastpars (i.e. from PHP)
///NOTE: If profiling is enabled (TASKLET_CTL_ENPROF is set in G_TASKLET_CTL) - save current time in 2 of the 32-bit locations that can be read as pastpars (i.e. from PHP)