Commit 2a82cec0 authored by Andrey Filippov's avatar Andrey Filippov

merged with framepars, most changes about triggering and initialization

parents 0d8ea7fc bb96d648
...@@ -190,7 +190,25 @@ static DEFINE_SPINLOCK(framepars_lock_3); ///< ...@@ -190,7 +190,25 @@ static DEFINE_SPINLOCK(framepars_lock_3); ///<
/** Define array of pointers to locks - hardware allows concurrent writes to different ports tables */ /** Define array of pointers to locks - hardware allows concurrent writes to different ports tables */
spinlock_t * framepars_locks[4] = {&framepars_lock_0, &framepars_lock_1, &framepars_lock_2, &framepars_lock_3}; spinlock_t * framepars_locks[4] = {&framepars_lock_0, &framepars_lock_1, &framepars_lock_2, &framepars_lock_3};
static struct common_pars_t scommon_pars = {
.master_chn = 0,
.sensors= {0,0,0,0}, // maybe not needed (it is whom to notify of
.updated = {0,0,0,0}, // set by master, cleared by other channels
.trig_period = 0,
.trig_bitlength = 0,
.extern_timestamp = 0,
.xmit_timestamp = 0,
.trig_condition = 0,
.trig_out = 0,
.trig_mode = TRIGMODE_FREERUN
};
/*
#define TRIGMODE_FREERUN 0
#define TRIGMODE_SNAPSHOT 4
#define TRIGMODE_GRR 20
*/
struct common_pars_t *common_pars = NULL;
/* Remove after compilation OK */ /* Remove after compilation OK */
//struct sensorproc_t * sensorproc = NULL; //struct sensorproc_t * sensorproc = NULL;
//void compressor_interrupts (int on) {} //void compressor_interrupts (int on) {}
...@@ -244,7 +262,7 @@ void init_framepars_ptr(int sensor_port) ...@@ -244,7 +262,7 @@ void init_framepars_ptr(int sensor_port)
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 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
amultiSensIndex[sensor_port] = sFrameParsAll[sensor_port].multiSensIndex; // indexes of individual sensor register shadows (first of 3) - now for all parameters, not just sensor ones 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 amultiSensRvrsIndex[sensor_port] = sFrameParsAll[sensor_port].multiSensRvrsIndex; // reverse index (to parent) for the multiSensIndex
common_pars = &scommon_pars;
} }
int framepars_open(struct inode *inode, struct file *filp); int framepars_open(struct inode *inode, struct file *filp);
...@@ -252,9 +270,11 @@ int framepars_release(struct inode *inode, struct file *filp); ...@@ -252,9 +270,11 @@ int framepars_release(struct inode *inode, struct file *filp);
loff_t framepars_lseek(struct file * file, loff_t offset, int orig); loff_t framepars_lseek(struct file * file, loff_t offset, int orig);
ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff_t *off); ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff_t *off);
int framepars_mmap(struct file *file, struct vm_area_struct *vma); int framepars_mmap(struct file *file, struct vm_area_struct *vma);
void trigSlaveUpdate(int sensor_port);
/** /**
* @brief Reset hardware sequencers (i2c, command) and initialize framepars structure * @brief Reset hardware sequencers (i2c, command) and initialize framepars structure
* Does not seem to do anything with the sequencers
*/ */
int initSequencers(int sensor_port) int initSequencers(int sensor_port)
{ {
...@@ -268,7 +288,7 @@ int initSequencers(int sensor_port) ...@@ -268,7 +288,7 @@ int initSequencers(int sensor_port)
if (!hardware_initialized) { if (!hardware_initialized) {
dev_dbg(g_devfp_ptr,"Configuring compressor DMA channels\n"); dev_dbg(g_devfp_ptr,"Configuring compressor DMA channels\n");
dev_info(g_devfp_ptr,"Configuring compressor DMA channels\n"); dev_info(g_devfp_ptr,"Configuring compressor DMA channels\n");
init_compressor_dma(0xf, // all channels (TODO: NC393 - select channels in DT or use existing for sesnors? init_compressor_dma(0xf, // all channels (TODO: NC393 - select channels in DT or use existing for sensors?
0); // not to interfere with python setting the same 0); // not to interfere with python setting the same
// Start RTC by writing 0 to seconds if it was not already set, otherwise preserve current time // Start RTC by writing 0 to seconds if it was not already set, otherwise preserve current time
get_fpga_rtc(&sec_usec); get_fpga_rtc(&sec_usec);
...@@ -287,6 +307,31 @@ int initSequencers(int sensor_port) ...@@ -287,6 +307,31 @@ int initSequencers(int sensor_port)
initFramePars(sensor_port); initFramePars(sensor_port);
return 0; return 0;
} }
/** Enable/disable sesnor channel (will not generate SoF/EoF pulses and interrupts if disabled). Used to turn off missing channels */
void enDisSensorChn(int sensor_port, ///< sensor_port sensor port number (0..3)
int en) ///< enable channel
{
x393_sens_mode_t sens_mode = {.d32=0};
sens_mode.chn_en = en;
sens_mode.chn_en_set = 1;
x393_sens_mode(sens_mode,sensor_port);
dev_dbg(g_devfp_ptr,"enDisSensorChn(%d,%d)\n", sensor_port, en);
}
/** Stop frame sequencer, optionally disable interrupts also */
void stopFrameSequencer(int sensor_port, ///< sensor_port sensor port number (0..3)
int dis_int) ///< disable interrupts
{
x393_cmdframeseq_mode_t cmdframeseq_mode = {.d32=0};
// TODO: Add locking for sequence reset?
cmdframeseq_mode.run_cmd = 2; // Stop
if (dis_int) cmdframeseq_mode.interrupt_cmd = 2; // disable
x393_cmdframeseq_ctrl(cmdframeseq_mode, sensor_port);
dev_dbg(g_devfp_ptr,"Stop command sequencer for port= %d, dis_int = %d\n", sensor_port, dis_int);
}
/** Reset absolute frame number \b thisFrameNumber to \b frame16, optionally reset/restart sequencer */ /** Reset absolute frame number \b thisFrameNumber to \b frame16, optionally reset/restart sequencer */
void resetFrameNumber(int sensor_port, ///< sensor_port sensor port number (0..3) void resetFrameNumber(int sensor_port, ///< sensor_port sensor port number (0..3)
...@@ -807,7 +852,7 @@ inline void _processParsASAP(int sensor_port, ///< sensor port ...@@ -807,7 +852,7 @@ inline void _processParsASAP(int sensor_port, ///< sensor port
MDP(DBGB_FASAP,sensor_port,"Calling SENSOR-SPECIFIC pgm_func[%d] ASAP, now frame = 0x%x\n",i,thisFrameNumber(sensor_port)) MDP(DBGB_FASAP,sensor_port,"Calling SENSOR-SPECIFIC pgm_func[%d] ASAP, now frame = 0x%x\n",i,thisFrameNumber(sensor_port))
rslt = sensorproc->pgm_func[i + 32] (sensor_port, &(sensorproc->sensor), procpars, prevpars, -1); rslt = sensorproc->pgm_func[i + 32] (sensor_port, &(sensorproc->sensor), procpars, prevpars, -1);
} }
if (rslt < 0) dev_warn(g_devfp_ptr,"%s:%d:%s - error=%d", __FILE__, __LINE__, __FUNCTION__, rslt);// Nothing to do with errors here - just report? if (rslt < 0) dev_warn(g_devfp_ptr,"port %d: %s:%d:%s - error=%d",sensor_port, __FILE__, __LINE__, __FUNCTION__, rslt);// Nothing to do with errors here - just report?
procpars->functions &= ~mask; procpars->functions &= ~mask;
dev_dbg(g_devfp_ptr,"%s : port= %d, .functions=0x%08lx)\n",__func__, sensor_port, procpars->functions); dev_dbg(g_devfp_ptr,"%s : port= %d, .functions=0x%08lx)\n",__func__, sensor_port, procpars->functions);
i++; i++;
...@@ -937,10 +982,14 @@ void _processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16 ...@@ -937,10 +982,14 @@ void _processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16
dev_err(g_devfp_ptr,"port=%d frame16=%d sensorproc==NULL !!!! \n", sensor_port, frame16); dev_err(g_devfp_ptr,"port=%d frame16=%d sensorproc==NULL !!!! \n", sensor_port, frame16);
return; return;
} }
// Check if master channel updated trigger parameters, schedule them to be updated
trigSlaveUpdate(sensor_port); // that will possible schedule more parameters
// int spin_trylock(spinlock_t *lock); // int spin_trylock(spinlock_t *lock);
// first - do all ASAP tasks (they should not be done ahead of the corresponding interrupt!) // first - do all ASAP tasks (they should not be done ahead of the corresponding interrupt!)
// dev_dbg(g_devfp_ptr,"%s before first _processParsASAP\n",__func__); // dev_dbg(g_devfp_ptr,"%s before first _processParsASAP\n",__func__);
_processParsASAP(sensor_port, sensorproc, frame16); // NC393: never gets here ? Only after _processParsSeq? _processParsASAP(sensor_port, sensorproc, frame16); // NC393: never gets here ? Only after _processParsSeq?
if (debug_flags) { if (debug_flags) {
MDP(DBGB_FPPI,sensor_port,"(after first _processParsASAP), frame16=%d, maxahead=%d\n", MDP(DBGB_FPPI,sensor_port,"(after first _processParsASAP), frame16=%d, maxahead=%d\n",
frame16, maxahead) frame16, maxahead)
...@@ -1075,30 +1124,54 @@ unsigned long getThisFrameNumber(int sensor_port) ...@@ -1075,30 +1124,54 @@ unsigned long getThisFrameNumber(int sensor_port)
/** /**
* @brief Set parameters that will never change (usually after sensor discovery) * @brief Set a single parameter to all frames (during sensor detection)
* @param sensor_port sensor port number (0..3) * @param sensor_port sensor port number (0..3)
* @param numPars number of parameters to set * @param numPars number of parameters to set
* @param pars array of parameters (number/value pairs) * @param pars array of parameters (number/value pairs)
* @return always 0 * @return always 0
*/ */
int setFrameParsStatic(int sensor_port, int numPars, struct frameparspair_t * pars) int setFrameParStatic(int sensor_port, ///< sensor port number (0..3)
unsigned long index, ///< parameter number
unsigned long val) ///< parameter value to set
///< @return 0 - OK, -ERR_FRAMEPARS_BADINDEX
{ {
int npar, nframe, index; struct framepars_t *framepars = aframepars[sensor_port];
struct framepars_t *framepars = aframepars[sensor_port]; int nframe;
for (npar = 0; npar < numPars; npar++) { index &= 0xffff; // get rid of any modifier (not applicable here)
index = pars[npar].num; if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX;
if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX; for (nframe = 0; nframe < PARS_FRAMES; nframe++) {
for (nframe = 0; nframe < PARS_FRAMES; nframe++) { framepars[nframe].pars[index] = val;
framepars[nframe].pars[index] = pars[npar].val;
}
} }
return 0; return 0;
} }
/**
* @brief Set parameters that will never change (usually after sensor discovery), other fields are supposed to be cleared
*/
int setFrameParsStatic(int sensor_port, ///< sensor_port sensor port number (0..3)
int numPars, ///< numPars number of parameters to set
struct frameparspair_t * pars) ///< pars array of parameters (number/value pairs)
///< @return always 0
{
int npar, nframe, index;
struct framepars_t *framepars = aframepars[sensor_port];
for (npar = 0; npar < numPars; npar++) {
index = pars[npar].num & 0xffff; // get rid of any modifier (not applicable here)
if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX;
for (nframe = 0; nframe < PARS_FRAMES; nframe++) {
framepars[nframe].pars[index] = pars[npar].val;
}
}
return 0;
}
/** Set parameters for the specified frame (atomic, with interrupts off). Used from applications through driver write */ /** Set parameters for the specified frame (atomic, with interrupts off). Used from applications through driver write */
//TODO: Check that writes never to the future or past frame (only 6 of 8 are allowed -> 14 of 16). Have seen just_this to flood all //TODO: Check that writes never to the future or past frame (only 6 of 8 are allowed -> 14 of 16). Have seen just_this to flood all
int setFrameParsAtomic(int sensor_port, ///< sensor port number (0..3) int setFrameParsAtomic(int sensor_port, ///< sensor port number (0..3)
unsigned long frameno, ///< absolute (full) frame number parameters should be applied to unsigned long frameno, ///< absolute (full) frame number parameters should be applied to
///< frameno = 0xffffffff => use maxlatency -1, frame = 0
int maxLatency, ///< maximal command latency (parameters should be set not less than maxLatency ahead of the current frame) int maxLatency, ///< maximal command latency (parameters should be set not less than maxLatency ahead of the current frame)
///< maxLatency < 0 - don't check latency (i.e. only commands that are not releted to particular frames), ///< maxLatency < 0 - don't check latency (i.e. only commands that are not releted to particular frames),
///< with negative and frameno< current frame will make it current, to use with ASAP ///< with negative and frameno< current frame will make it current, to use with ASAP
...@@ -1113,6 +1186,12 @@ int setFrameParsAtomic(int sensor_port, ///< sensor port number (0 ...@@ -1113,6 +1186,12 @@ int setFrameParsAtomic(int sensor_port, ///< sensor port number (0
struct framepars_t *framepars = aframepars[sensor_port]; struct framepars_t *framepars = aframepars[sensor_port];
unsigned long *funcs2call =afuncs2call[sensor_port]; unsigned long *funcs2call =afuncs2call[sensor_port];
int findex_this, findex_prev, findex_future, frame16; int findex_this, findex_prev, findex_future, frame16;
if (frameno == 0xffffffff){
maxLatency = -1;
frameno = 0;
dev_dbg(g_devfp_ptr,"port= %d, frameno was 0xffffffff, modifying maxLatency=0x%x, frameno = 0x%08lx\n",sensor_port, maxLatency, frameno);
}
findex_this = thisFrameNumber(sensor_port) & PARS_FRAMES_MASK; findex_this = thisFrameNumber(sensor_port) & PARS_FRAMES_MASK;
findex_prev = (findex_this - 1) & PARS_FRAMES_MASK; findex_prev = (findex_this - 1) & PARS_FRAMES_MASK;
findex_future = (findex_this - 2) & PARS_FRAMES_MASK; // actually - fartherst in the future?? findex_future = (findex_this - 2) & PARS_FRAMES_MASK; // actually - fartherst in the future??
...@@ -1228,6 +1307,9 @@ int setFrameParsAtomic(int sensor_port, ///< sensor port number (0 ...@@ -1228,6 +1307,9 @@ int setFrameParsAtomic(int sensor_port, ///< sensor port number (0
} }
// Try to process parameters immediately after written. If 0, only non-ASAP will be processed to prevent // Try to process parameters immediately after written. If 0, only non-ASAP will be processed to prevent
// effects of uncertainty of when was it called relative to frame sync // effects of uncertainty of when was it called relative to frame sync
// ASAP - needed to set with sequencer is stopped!
// Changed to all (don't care about uncertainty - they will trigger only if it is too late or during sensor detection/initialization) // Changed to all (don't care about uncertainty - they will trigger only if it is too late or during sensor detection/initialization)
debug_flags = 20; // enable debug print several times debug_flags = 20; // enable debug print several times
if (!(get_globalParam(sensor_port, G_TASKLET_CTL) & (1 << TASKLET_CTL_NOSAME))) { if (!(get_globalParam(sensor_port, G_TASKLET_CTL) & (1 << TASKLET_CTL_NOSAME))) {
...@@ -1371,6 +1453,33 @@ int setFrameParLocked(int sensor_port, ///< sensor port numb ...@@ -1371,6 +1453,33 @@ int setFrameParLocked(int sensor_port, ///< sensor port numb
return rslt; return rslt;
} }
void trigSlaveUpdate(int sensor_port) ///< sensor port number (0..3)
{
struct framepars_t *framepars = aframepars[sensor_port];
struct frameparspair_t pars_to_update[8];
int nupdate = 0;
int updated_period = 0;
while (common_pars->updated[sensor_port]) {
dev_dbg(g_devfp_ptr,"port= %d, thisFrameNumber[%d] = %d\n", sensor_port, sensor_port, (int) thisFrameNumber(sensor_port));
common_pars->updated[sensor_port] = 0;
if (pars_to_update[nupdate ].num != P_TRIG_PERIOD){ //???
updated_period = FRAMEPAIR_FORCE_PROC;
}
pars_to_update[nupdate ].num= P_TRIG_MASTER ; pars_to_update[nupdate++].val = common_pars->master_chn;
pars_to_update[nupdate ].num= P_TRIG_PERIOD | updated_period ; pars_to_update[nupdate++].val = common_pars->trig_period;
pars_to_update[nupdate ].num= P_TRIG_BITLENGTH ; pars_to_update[nupdate++].val = common_pars->trig_bitlength;
pars_to_update[nupdate ].num= P_EXTERN_TIMESTAMP ; pars_to_update[nupdate++].val = common_pars->extern_timestamp;
pars_to_update[nupdate ].num= P_XMIT_TIMESTAMP ; pars_to_update[nupdate++].val = common_pars->xmit_timestamp;
pars_to_update[nupdate ].num= P_TRIG_CONDITION ; pars_to_update[nupdate++].val = common_pars->trig_condition;
pars_to_update[nupdate ].num= P_TRIG_OUT ; pars_to_update[nupdate++].val = common_pars->trig_out;
pars_to_update[nupdate ].num= P_TRIG ; pars_to_update[nupdate++].val = common_pars->trig_mode;
// if (nupdate) setFramePars(sensor_port, &framepars[frame16], nupdate, pars_to_update); // save changes, schedule functions
if (nupdate) setFramePars(sensor_port, &framepars[thisFrameNumber(sensor_port)], nupdate, pars_to_update); // save changes, schedule functions
}
}
/** Set multiple output (calculated) parameters for the frame referenced by this_framepars structure. /** Set multiple output (calculated) parameters for the frame referenced by this_framepars structure.
* Schedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in the particular parameter index * Schedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in the particular parameter index
* Called from tasklets (while executing (*_)pgm_* functions * Called from tasklets (while executing (*_)pgm_* functions
...@@ -1383,7 +1492,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0 ...@@ -1383,7 +1492,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
///< @return 0 - OK, -ERR_FRAMEPARS_BADINDEX ///< @return 0 - OK, -ERR_FRAMEPARS_BADINDEX
{ {
int frame16; int frame16;
// unsigned long flags; should only be called when interruypts disabled and lock obtained // unsigned long flags; should only be called when interrupts disabled and lock obtained
int npar, nframe; int npar, nframe;
unsigned long val, bmask, bmask32; unsigned long val, bmask, bmask32;
int index, bindex; int index, bindex;
...@@ -1400,7 +1509,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0 ...@@ -1400,7 +1509,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
frame16 = (this_framepars->pars[P_FRAME]) & PARS_FRAMES_MASK; frame16 = (this_framepars->pars[P_FRAME]) & PARS_FRAMES_MASK;
val = pars[npar].val; val = pars[npar].val;
index = pars[npar].num & 0xffff; index = pars[npar].num & 0xffff;
dev_dbg(g_devfp_ptr, ": --- frame16=%d index=%d (0x%x) val=0x%x\n", frame16, index, (int)pars[npar].num, (int)val); dev_dbg(g_devfp_ptr, ": --- frame16=%d index=%d (0x%x) val=0x%x, findex_future = 0x%x\n", frame16, index, (int)pars[npar].num, (int)val, findex_future);
MDP(DBGB_FSFV,sensor_port," --- frame16=%d index=%d (0x%x) val=0x%x\n", frame16, index, (int)pars[npar].num, (int)val) MDP(DBGB_FSFV,sensor_port," --- frame16=%d index=%d (0x%x) val=0x%x\n", frame16, index, (int)pars[npar].num, (int)val)
// remark: code below looks similar to setFramePar function, call it instead // remark: code below looks similar to setFramePar function, call it instead
if (index > ((index >= FRAMEPAR_GLOBALS) ? (P_MAX_GPAR + FRAMEPAR_GLOBALS) : P_MAX_PAR)) { if (index > ((index >= FRAMEPAR_GLOBALS) ? (P_MAX_GPAR + FRAMEPAR_GLOBALS) : P_MAX_PAR)) {
...@@ -1419,6 +1528,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0 ...@@ -1419,6 +1528,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
val = FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, framepars[frame16].pars[index], val); val = FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, framepars[frame16].pars[index], val);
} }
//TODO: optimize to use mask several parameters together //TODO: optimize to use mask several parameters together
dev_dbg(g_devfp_ptr, "{%d}: framepars[%d].pars[0x%x] = 0x%x, val=0x%x\n", sensor_port, frame16, index, (int) framepars[frame16].pars[index], (int)val);
if ((framepars[frame16].pars[index] != val) || (pars[npar].num & (FRAMEPAIR_FORCE_NEW | FRAMEPAIR_FORCE_PROC))) { if ((framepars[frame16].pars[index] != val) || (pars[npar].num & (FRAMEPAIR_FORCE_NEW | FRAMEPAIR_FORCE_PROC))) {
bmask = 1 << (index & 31); bmask = 1 << (index & 31);
bindex = index >> 5; bindex = index >> 5;
...@@ -1430,6 +1540,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0 ...@@ -1430,6 +1540,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
if (pars[npar].num & FRAMEPAIR_FORCE_PROC) { if (pars[npar].num & FRAMEPAIR_FORCE_PROC) {
framepars[frame16].functions |= funcs2call[index]; //Mark which functions will be needed to process the parameters framepars[frame16].functions |= funcs2call[index]; //Mark which functions will be needed to process the parameters
} }
dev_dbg(g_devfp_ptr, "{%d}: framepars[%d].functions=0x%x\n", sensor_port, frame16, (int) framepars[frame16].functions);
// Write parameter to the next frames up to the one that have the same parameter already modified (only if not FRAMEPAIR_JUST_THIS) // Write parameter to the next frames up to the one that have the same parameter already modified (only if not FRAMEPAIR_JUST_THIS)
if ((pars[npar].num & FRAMEPAIR_JUST_THIS) == 0) { if ((pars[npar].num & FRAMEPAIR_JUST_THIS) == 0) {
// MDF8(printk(": --- setting next frames")); // MDF8(printk(": --- setting next frames"));
...@@ -1683,7 +1794,9 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1683,7 +1794,9 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff
int latency = -1; int latency = -1;
int first = 0; int first = 0;
int last; int last;
int result; int result = 0;
int port_mask=0; // to apply to several channels simultaneously
unsigned long frames[SENSOR_PORTS];
sec_usec_t sec_usec; sec_usec_t sec_usec;
// dev_dbg(g_devfp_ptr,"%s : file->f_pos=0x%x, *off=0x%x, count=0x%x\n",__func__, (int)file->f_pos, (int)*off, (int)count); // dev_dbg(g_devfp_ptr,"%s : file->f_pos=0x%x, *off=0x%x, count=0x%x\n",__func__, (int)file->f_pos, (int)*off, (int)count);
dev_dbg(g_devfp_ptr, "file->f_pos=0x%x, *off=0x%x, count=0x%x, minor=0x%x\n", dev_dbg(g_devfp_ptr, "file->f_pos=0x%x, *off=0x%x, count=0x%x, minor=0x%x\n",
...@@ -1709,12 +1822,53 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1709,12 +1822,53 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff
} }
while (first < count) { while (first < count) {
while ((first < count) && ((pars[first].num & 0xff00) == 0xff00)) { // process special instructions while ((first < count) && ((pars[first].num & 0xff00) == 0xff00)) { // process special instructions
switch (pars[first].num & 0xffff) { dev_dbg(g_devfp_ptr, "pars[%d].num = 0x%lx pars[%d].val = 0x%lx\n",first,pars[first].num, first,pars[first].val);
switch (pars[first].num & 0xff0f) {
#if 0
case FRAMEPARS_SETFRAME: case FRAMEPARS_SETFRAME:
frame = pars[first].val; frame = pars[first].val;
port_mask = (pars[first].num >> 4) & ((1 << SENSOR_PORTS) - 1);
if (port_mask){
// Retry if got different results - mostly for in-sync running sensors and just swicthed
// TODO: What to do: triggered sensors have frame sync delayed by exposure time from the common trigger
int frames_diff=1;
int ii;
for (ii =0; ii < SENSOR_PORTS; ii++) frames[ii] = 0xffffffff;
while (frames_diff) {
frames_diff = 0;
frame = pars[first].val;
//TODO: Disable interrupts here to freeze frame difference
for (ii =0; ii < SENSOR_PORTS; ii++){
frame = pars[first].val + getThisFrameNumber(ii) - getThisFrameNumber(sensor_port);
if (frame != frames[ii]) frames_diff = 1;
frames[ii] = frame;
}
}
}
break; break;
#endif
case FRAMEPARS_SETFRAME:
frame = pars[first].val;
port_mask = (pars[first].num >> 4) & ((1 << SENSOR_PORTS) - 1);
// No correction - frames should be exctly synchronized to work this way, otherwise use relative
if (port_mask){
int ii;
for (ii =0; ii < SENSOR_PORTS; ii++) if (port_mask & (1 << ii)){
frames[ii] = frame;
}
}
dev_dbg(g_devfp_ptr, "port_mask=0x%x frames[0]=0x%lx frames[1]=0x%lx frames[2]=0x%lx frames[3]=0x%lx\n",
port_mask, frames[0], frames[1], frames[2], frames[3]);
break;
case FRAMEPARS_SETFRAMEREL: case FRAMEPARS_SETFRAMEREL:
frame = pars[first].val + getThisFrameNumber(sensor_port); frame = pars[first].val + getThisFrameNumber(sensor_port);
port_mask = (pars[first].num >> 4) & ((1 << SENSOR_PORTS) - 1);
if (port_mask){
int ii;
for (ii =0; ii < SENSOR_PORTS; ii++) if (port_mask & (1 << ii)){
frames[ii] = pars[first].val + getThisFrameNumber(ii);
}
}
break; break;
case FRAMEPARS_SETLATENCY: case FRAMEPARS_SETLATENCY:
latency = (pars[first].val & 0x80000000) ? -1 : pars[first].val; latency = (pars[first].val & 0x80000000) ? -1 : pars[first].val;
...@@ -1742,11 +1896,23 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1742,11 +1896,23 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff
} }
last = first + 1; last = first + 1;
while ((last < count) && ((pars[last].num & 0xff00) != 0xff00)) last++; // skip to the end or next special instructions while ((last < count) && ((pars[last].num & 0xff00) != 0xff00)) last++; // skip to the end or next special instructions
dev_dbg(g_devfp_ptr, "0x%x: setFrameParsAtomic(%ld, %d, %d)\n", if (port_mask) {
(int) privData->minor, frame, latency, last - first); int ii;
MDP(DBGB_FFOP, sensor_port, "0x%x: setFrameParsAtomic(%ld, %d, %d)\n", dev_dbg(g_devfp_ptr, "0x%x: port_mask=0x%x\n", (int) privData->minor, port_mask);
(int) privData->minor, frame, latency, last - first) for (ii =0; ii < SENSOR_PORTS; ii++) if (port_mask & (1 << ii)){
result = setFrameParsAtomic(sensor_port,frame, latency, last - first, &pars[first]); dev_dbg(g_devfp_ptr, "0x%x: setFrameParsAtomic(%d, %ld, %d, %d)\n",
(int) privData->minor, ii, frame, latency, last - first);
MDP(DBGB_FFOP, sensor_port, "0x%x: setFrameParsAtomic(%d, %ld, %d, %d)\n",
(int) privData->minor, ii, frame, latency, last - first)
result |= setFrameParsAtomic(ii, frames[ii], latency, last - first, &pars[first]);
}
} else {
dev_dbg(g_devfp_ptr, "0x%x: setFrameParsAtomic(%ld, %d, %d)\n",
(int) privData->minor, frame, latency, last - first);
MDP(DBGB_FFOP, sensor_port, "0x%x: setFrameParsAtomic(%ld, %d, %d)\n",
(int) privData->minor, frame, latency, last - first)
result = setFrameParsAtomic(sensor_port,frame, latency, last - first, &pars[first]);
}
if (result < 0) { if (result < 0) {
if (count > sizeof(pars_static)) kfree(pars); if (count > sizeof(pars_static)) kfree(pars);
return -EFAULT; return -EFAULT;
...@@ -1818,11 +1984,25 @@ static ssize_t store_this_frame(struct device *dev, struct device_attribute *att ...@@ -1818,11 +1984,25 @@ static ssize_t store_this_frame(struct device *dev, struct device_attribute *att
resetFrameNumber(get_channel_from_name(attr), resetFrameNumber(get_channel_from_name(attr),
aframe, aframe,
(aframe < PARS_FRAMES)?1:0); // reset hardware if aframe is small (aframe < PARS_FRAMES)?1:0); // reset hardware if aframe is small
} else {
stopFrameSequencer(get_channel_from_name(attr), 1); // 0); // do not disable interrupts here?
// return - EINVAL;
}
return count;
}
static ssize_t store_endis_chn(struct device *dev, struct device_attribute *attr, const char *buf, size_t count)
{
u32 en;
if (sscanf(buf, "%u", &en)>0) {
enDisSensorChn(get_channel_from_name(attr),en);
} else { } else {
return - EINVAL; return - EINVAL;
} }
return count; return count;
} }
// sscanf(buf, "%i", &buffer_settings.frame_start[get_channel_from_name(attr)], &len); // sscanf(buf, "%i", &buffer_settings.frame_start[get_channel_from_name(attr)], &len);
static ssize_t show_fpga_time(struct device *dev, struct device_attribute *attr, char *buf) static ssize_t show_fpga_time(struct device *dev, struct device_attribute *attr, char *buf)
...@@ -1894,6 +2074,15 @@ static DEVICE_ATTR(this_frame0, SYSFS_PERMISSIONS, show_this_f ...@@ -1894,6 +2074,15 @@ static DEVICE_ATTR(this_frame0, SYSFS_PERMISSIONS, show_this_f
static DEVICE_ATTR(this_frame1, SYSFS_PERMISSIONS, show_this_frame, store_this_frame); static DEVICE_ATTR(this_frame1, SYSFS_PERMISSIONS, show_this_frame, store_this_frame);
static DEVICE_ATTR(this_frame2, SYSFS_PERMISSIONS, show_this_frame, store_this_frame); static DEVICE_ATTR(this_frame2, SYSFS_PERMISSIONS, show_this_frame, store_this_frame);
static DEVICE_ATTR(this_frame3, SYSFS_PERMISSIONS, show_this_frame, store_this_frame); static DEVICE_ATTR(this_frame3, SYSFS_PERMISSIONS, show_this_frame, store_this_frame);
static DEVICE_ATTR(chn_en0, SYSFS_PERMISSIONS, NULL, store_endis_chn);
static DEVICE_ATTR(chn_en1, SYSFS_PERMISSIONS, NULL, store_endis_chn);
static DEVICE_ATTR(chn_en2, SYSFS_PERMISSIONS, NULL, store_endis_chn);
static DEVICE_ATTR(chn_en3, SYSFS_PERMISSIONS, NULL, store_endis_chn);
//static DEVICE_ATTR(chn_en0, SYSFS_WRITEONLY, NULL, store_endis_chn);
//static DEVICE_ATTR(chn_en1, SYSFS_WRITEONLY, NULL, store_endis_chn);
//static DEVICE_ATTR(chn_en2, SYSFS_WRITEONLY, NULL, store_endis_chn);
//static DEVICE_ATTR(chn_en3, SYSFS_WRITEONLY, NULL, store_endis_chn);
static DEVICE_ATTR(all_frames, SYSFS_READONLY, show_all_frames, NULL); static DEVICE_ATTR(all_frames, SYSFS_READONLY, show_all_frames, NULL);
static DEVICE_ATTR(fpga_time, SYSFS_PERMISSIONS, show_fpga_time, store_fpga_time); static DEVICE_ATTR(fpga_time, SYSFS_PERMISSIONS, show_fpga_time, store_fpga_time);
...@@ -1904,6 +2093,10 @@ static struct attribute *root_dev_attrs[] = { ...@@ -1904,6 +2093,10 @@ static struct attribute *root_dev_attrs[] = {
&dev_attr_this_frame3.attr, &dev_attr_this_frame3.attr,
&dev_attr_all_frames.attr, &dev_attr_all_frames.attr,
&dev_attr_fpga_time.attr, &dev_attr_fpga_time.attr,
&dev_attr_chn_en0.attr,
&dev_attr_chn_en1.attr,
&dev_attr_chn_en2.attr,
&dev_attr_chn_en3.attr,
NULL NULL
}; };
......
...@@ -6,17 +6,18 @@ ...@@ -6,17 +6,18 @@
//extern struct framepars_t (*framepars)[PARS_FRAMES]; //extern struct framepars_t (*framepars)[PARS_FRAMES];
extern struct framepars_t *aframepars[SENSOR_PORTS]; extern struct framepars_t *aframepars[SENSOR_PORTS];
extern struct framepars_past_t *apastpars[SENSOR_PORTS]; extern struct framepars_past_t *apastpars[SENSOR_PORTS];
extern struct common_pars_t *common_pars;
extern unsigned long *aglobalPars[SENSOR_PORTS]; extern unsigned long *aglobalPars[SENSOR_PORTS];
extern unsigned long *amultiSensIndex[SENSOR_PORTS]; extern unsigned long *amultiSensIndex[SENSOR_PORTS];
extern unsigned long *amultiSensRvrsIndex[SENSOR_PORTS]; extern unsigned long *amultiSensRvrsIndex[SENSOR_PORTS];
extern wait_queue_head_t aframepars_wait_queue[SENSOR_PORTS]; extern wait_queue_head_t aframepars_wait_queue[SENSOR_PORTS];
///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
void init_framepars_ptr(int sensor_port); void init_framepars_ptr(int sensor_port);
int initSequencers (int sensor_port); ///Move to sensorcommon? currently it is used through frameparsall file (lseek) int initSequencers (int sensor_port); ///Move to sensorcommon? currently it is used through frameparsall file (lseek)
void initGlobalPars (int sensor_port); /// resets all global parameters but debug mask (if ELPHEL_DEBUG) void initGlobalPars (int sensor_port); /// resets all global parameters but debug mask (if ELPHEL_DEBUG)
int initMultiPars (int sensor_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 int initMultiPars (int sensor_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
void initFramePars (int sensor_port); ///initialize all parameters, set thisFrameNumber to frame16 (read from hardware, usually 0 after resetting i2c and cmd_seq) void initFramePars (int sensor_port); ///initialize all parameters, set thisFrameNumber to frame16 (read from hardware, usually 0 after resetting i2c and cmd_seq)
void stopFrameSequencer(int sensor_port, int dis_int);
void resetFrameNumber (int sensor_port, u32 aframe, int hreset); /// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow) void resetFrameNumber (int sensor_port, u32 aframe, int hreset); /// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow)
unsigned long get_imageParamsFrame(int sensor_port, int n, int frame); unsigned long get_imageParamsFrame(int sensor_port, int n, int frame);
...@@ -35,6 +36,7 @@ void set_imageParamsR_all(int sensor_port, int n, unsigned long d); ...@@ -35,6 +36,7 @@ void set_imageParamsR_all(int sensor_port, int n, unsigned long d);
//Next 2 called from ISR //Next 2 called from ISR
void updateInterFrame(int sensor_port, u32 compressed_frame, struct interframe_params_t * interframe_pars); void updateInterFrame(int sensor_port, u32 compressed_frame, struct interframe_params_t * interframe_pars);
void updateFramePars (int sensor_port, int frame16); void updateFramePars (int sensor_port, int frame16);
int setFrameParStatic (int sensor_port, unsigned long index, unsigned long val);
int setFrameParsStatic (int sensor_port, int numPars, struct frameparspair_t * pars); int setFrameParsStatic (int sensor_port, int numPars, struct frameparspair_t * pars);
unsigned long getThisFrameNumber (int sensor_port); /// just return current thisFrameNumber unsigned long getThisFrameNumber (int sensor_port); /// just return current thisFrameNumber
......
...@@ -150,17 +150,21 @@ const unsigned long ahead_tab[]= ...@@ -150,17 +150,21 @@ const unsigned long ahead_tab[]=
/// For Micron sensors limitfps should have the same latency as changing window height, otherwise when WOI_HEIGHT 0x3c0->0x790 and next frame VBLANK 0x13e->0x284 /// For Micron sensors limitfps should have the same latency as changing window height, otherwise when WOI_HEIGHT 0x3c0->0x790 and next frame VBLANK 0x13e->0x284
/// sensor waits till the counter overflows (>10 seconds) without any frame sync pulses /// sensor waits till the counter overflows (>10 seconds) without any frame sync pulses
onchange_limitfps, 0, 2, 1, 1, 1, 0, /// check compressor will keep up, limit sensor FPS if needed onchange_limitfps, 0, 2, 1, 1, 1, 0, /// check compressor will keep up, limit sensor FPS if needed
onchange_compmode, 0, 0, 1, 1, 1, 0, /// program compressor modes /// onchange_compmode, 0, 0, 1, 1, 1, 0, /// program compressor modes
onchange_compmode, 0, 0, 0, 0, 0, 0, /// program compressor modes
onchange_focusmode, 1, 0, 0, 0, 0, 0, /// program focus modes (through writing the tables, so no sequencer) onchange_focusmode, 1, 0, 0, 0, 0, 0, /// program focus modes (through writing the tables, so no sequencer)
// onchange_trigseq, 0, 0, 0, 0, 0, 0, /// program sequencer (int/ext) // onchange_trigseq, 0, 0, 0, 0, 0, 0, /// program sequencer (int/ext)
// onchange_trigseq, 1, 0, 0, 0, 0, 0, /// program sequencer (int/ext) NOTE:needs >24 bit data, too much for sequencer // onchange_trigseq, 1, 0, 0, 0, 0, 0, /// program sequencer (int/ext) NOTE:needs >24 bit data, too much for sequencer
onchange_trigseq, 1, 2, 1, 1, 1, 0, /// program sequencer (int/ext) NOTE:needs >24 bit data, too much for sequencer. Should be not later than onchange_triggermode and limitfps // onchange_trigseq, 1, 2, 1, 1, 1, 0, /// program sequencer (int/ext) NOTE:needs >24 bit data, too much for sequencer. Should be not later than onchange_triggermode and limitfps
onchange_trigseq, 0, 2, 1, 1, 1, 0, /// NC393: OK to program through the sequencer (full 32 bits)
onchange_irq, 0, 0, 0, 0, 0, 0, /// program smart IRQ mode onchange_irq, 0, 0, 0, 0, 0, 0, /// program smart IRQ mode
onchange_comprestart, 0, 0, 0, 0, 0, 0, /// restart after changing geometry (recognizes ASAP and programs memory channel 2 then) onchange_comprestart, 0, 0, 0, 0, 0, 0, /// restart after changing geometry (recognizes ASAP and programs memory channel 2 then)
/// onchange_compstop should have the same latency as onchange_window /// onchange_compstop should have the same latency as onchange_window
// NC393 - triggered mode wants onchange_compstop==2, while onchange_window == 1?
// onchange_compstop, 0, 2, 1, 2, 1, 0, /// stop compressor when changing geometry // onchange_compstop, 0, 2, 1, 2, 1, 0, /// stop compressor when changing geometry
onchange_compstop, 0, 2, 1, 1, 1, 0, /// stop compressor when changing geometry /// onchange_compstop, 0, 2, 1, 1, 1, 0, /// stop compressor when changing geometry
onchange_compstop, 0, 2, 2, 2, 2, 0, /// stop compressor when changing geometry
onchange_compctl, 0, 0, 1, 1, 1, 0, /// only start/stop/single (after explicitly changed, not when geometry was changed) onchange_compctl, 0, 0, 1, 1, 1, 0, /// only start/stop/single (after explicitly changed, not when geometry was changed)
// onchange_gammaload, 1, 0, 0, 0, 0, 0, /// write gamma tables (should be prepared). Maybe - just last byte, to activate? // onchange_gammaload, 1, 0, 0, 0, 0, 0, /// write gamma tables (should be prepared). Maybe - just last byte, to activate?
onchange_gammaload, 1, 1, 1, 1, 1, 0, /// write gamma tables (should be prepared). Maybe - just last byte, to activate? onchange_gammaload, 1, 1, 1, 1, 1, 0, /// write gamma tables (should be prepared). Maybe - just last byte, to activate?
......
...@@ -727,23 +727,6 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port ...@@ -727,23 +727,6 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
// try MT9P001 first // try MT9P001 first
psensor= &mt9p001; psensor= &mt9p001;
#ifdef NC353
// set control lines
CCAM_NEGRST; ///set negative MRST polarity
CCAM_TRIG_INT;
CCAM_MRST_OFF;
CCAM_ARST_OFF;
udelay (100);
local_irq_save(flags); // IRQ Off
i2c_stop_wait();
i2c_writeData(0, (psensor->i2c_addr) & 0xfe, &chipver_reg, 1, 0); // no stop before read (cxi2c.c)
i2c_readData (0, (psensor->i2c_addr) | 1, i2c_read_data, 2, 0); ///restart, not start (cxi2c.c)
local_irq_restore(flags); // IRQ restore
if (((I2C_READ_DATA16(0) ^ MT9P001_PARTID) & MT9X001_PARTIDMASK)==0) {
dev_dbg(g_dev_ptr,"Found MT9P001 2592x1944 sensor, chip ID=%x\n",(i2c_read_data[0]<<8)+i2c_read_data[1]);
sensor_subtype=MT9P_TYP; //1;
}
#else
// set control lines // set control lines
sensio_ctl.mrst = 1; sensio_ctl.mrst = 1;
sensio_ctl.mrst_set = 1; sensio_ctl.mrst_set = 1;
...@@ -766,34 +749,11 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port ...@@ -766,34 +749,11 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
dev_dbg(g_dev_ptr,"Found MT9P001 2592x1944 sensor, chip ID=%x\n",i2c_read_dataw); dev_dbg(g_dev_ptr,"Found MT9P001 2592x1944 sensor, chip ID=%x\n",i2c_read_dataw);
sensor_subtype=MT9P_TYP; //1; sensor_subtype=MT9P_TYP; //1;
} }
#endif
// dev_dbg(g_dev_ptr,"sensor id= 0x%x\n",i2c_read_data[0]); // dev_dbg(g_dev_ptr,"sensor id= 0x%x\n",i2c_read_data[0]);
// MDD1(dev_dbg(g_dev_ptr,"sensor=0x%x\n", (int)sensor)); // MDD1(dev_dbg(g_dev_ptr,"sensor=0x%x\n", (int)sensor));
if (sensor_subtype ==0) { // not a 5MPix chip if (sensor_subtype ==0) { // not a 5MPix chip
// CCAM_ARST_ON; // Why was it here // CCAM_ARST_ON; // Why was it here
psensor= &mt9m001; //address the same for all others psensor= &mt9m001; //address the same for all others
#ifdef NC353
local_irq_save(flags); // IRQ Off
i2c_stop_wait();
i2c_writeData(0, (psensor->i2c_addr) & 0xfe, &chipver_reg, 1, 0); // no stop before read
i2c_readData (0, (psensor->i2c_addr) | 1, i2c_read_data, 2, 0); //restart, not strart
local_irq_restore(flags); // IRQ restore
// dev_dbg(g_dev_ptr,"-sensor id= 0x%x\n",i2c_read_data[0]);
if (((I2C_READ_DATA16(0)^MT9M001_PARTID) & MT9X001_PARTIDMASK)==0) {
dev_dbg(g_dev_ptr,"Found MT9M001 1280x1024 sensor, chip ID=%x\n",I2C_READ_DATA16(0));
psensor= &mt9m001;
sensor_subtype=MT9M_TYP; //1;
} else if (((I2C_READ_DATA16(0)^MT9D001_PARTID) & MT9X001_PARTIDMASK)==0) {
dev_dbg(g_dev_ptr,"Found MT9D001 1600x1200 sensor, chip ID=%x\n",I2C_READ_DATA16(0));
psensor= &mt9d001;
sensor_subtype=MT9D_TYP; //2;
} else if (((I2C_READ_DATA16(0)^MT9T001_PARTID) & MT9X001_PARTIDMASK)==0) {
dev_dbg(g_dev_ptr,"Found MT9T001 2048x1536 sensor, chip ID=%x\n",I2C_READ_DATA16(0));
psensor= &mt9t001;
sensor_subtype=MT9T_TYP; //3;
// if(d[2] == 0x01) - MT9T001 chip rev 01 - color gains had a bug
}
#else
X3X3_I2C_RCV2(sensor_port, psensor->i2c_addr, P_MT9X001_CHIPVER, &i2c_read_dataw); X3X3_I2C_RCV2(sensor_port, psensor->i2c_addr, P_MT9X001_CHIPVER, &i2c_read_dataw);
if (((i2c_read_dataw ^MT9M001_PARTID) & MT9X001_PARTIDMASK)==0) { if (((i2c_read_dataw ^MT9M001_PARTID) & MT9X001_PARTIDMASK)==0) {
dev_dbg(g_dev_ptr,"Found MT9M001 1280x1024 sensor, chip ID=%x\n",i2c_read_dataw); dev_dbg(g_dev_ptr,"Found MT9M001 1280x1024 sensor, chip ID=%x\n",i2c_read_dataw);
...@@ -811,7 +771,6 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port ...@@ -811,7 +771,6 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
} else { } else {
dev_dbg(g_dev_ptr,"Found Unknown sensor, chip ID=%x\n",i2c_read_dataw); dev_dbg(g_dev_ptr,"Found Unknown sensor, chip ID=%x\n",i2c_read_dataw);
} }
#endif
} }
// MDD1(dev_dbg(g_dev_ptr,"sensor=0x%x, sensor_subtype=0x%x\n", (int)sensor, (int)sensor_subtype)); // MDD1(dev_dbg(g_dev_ptr,"sensor=0x%x, sensor_subtype=0x%x\n", (int)sensor, (int)sensor_subtype));
if (sensor_subtype ==0) return 0; // no sensor found if (sensor_subtype ==0) return 0; // no sensor found
...@@ -830,7 +789,9 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port ...@@ -830,7 +789,9 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
add_sensor_proc(sensor_port,onchange_triggermode, &mt9x001_pgm_triggermode); // program sensor trigger mode add_sensor_proc(sensor_port,onchange_triggermode, &mt9x001_pgm_triggermode); // program sensor trigger mode
add_sensor_proc(sensor_port,onchange_sensorregs, &mt9x001_pgm_sensorregs); // write sensor registers (only changed from outside the driver as they may have different latencies)? add_sensor_proc(sensor_port,onchange_sensorregs, &mt9x001_pgm_sensorregs); // write sensor registers (only changed from outside the driver as they may have different latencies)?
// MDD1(dev_dbg(g_dev_ptr,"sensor->sensorType=0x%lx\n", sensor->sensorType)); // MDD1(dev_dbg(g_dev_ptr,"sensor->sensorType=0x%lx\n", sensor->sensorType));
setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); // was so setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); // should cause other actions
// setFrameParStatic (sensor_port, P_SENSOR, sensor->sensorType);
common_pars->sensors[sensor_port] = sensor->sensorType;
// setFramePar(thispars, P_SENSOR | FRAMEPAIR_FORCE_NEWPROC, sensor->sensorType); // force actions // setFramePar(thispars, P_SENSOR | FRAMEPAIR_FORCE_NEWPROC, sensor->sensorType); // force actions
// MDD1(dev_dbg(g_dev_ptr,"\n")); // MDD1(dev_dbg(g_dev_ptr,"\n"));
///TODO: Fill G_MULTI_REGSM+i - which registers need individual values in multi-sensor applications ///TODO: Fill G_MULTI_REGSM+i - which registers need individual values in multi-sensor applications
...@@ -888,7 +849,8 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port ...@@ -888,7 +849,8 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
///< @return 0 - OK, negative - error ///< @return 0 - OK, negative - error
{ {
// unsigned long flags; // this function uses software i2c operations - they need to have interrupts (and hardware i2c off) // unsigned long flags; // this function uses software i2c operations - they need to have interrupts (and hardware i2c off)
struct frameparspair_t pars_to_update[258+(MAX_SENSORS * P_MULTI_NUMREGS )]; // for all the sensor registers. Other P_* values will reuse the same ones // struct frameparspair_t pars_to_update[258+(MAX_SENSORS * P_MULTI_NUMREGS )]; // for all the sensor registers. Other P_* values will reuse the same ones
struct frameparspair_t pars_to_update[262+(MAX_SENSORS * P_MULTI_NUMREGS )]; // for all the sensor registers. Other P_* values will reuse the same ones
int first_sensor_i2c; int first_sensor_i2c;
unsigned short * sensor_register_overwrites; unsigned short * sensor_register_overwrites;
x393_sensio_ctl_t sensio_ctl = {.d32=0}; x393_sensio_ctl_t sensio_ctl = {.d32=0};
...@@ -902,36 +864,6 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port ...@@ -902,36 +864,6 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16); dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
if (frame16 >= 0) return -1; // should be ASAP if (frame16 >= 0) return -1; // should be ASAP
// reset sensor by applying MRST (low): // reset sensor by applying MRST (low):
#ifdef NC353
CCAM_MRST_ON;
udelay (100);
CCAM_MRST_OFF;
udelay (100);
dev_dbg(g_dev_ptr,"Reading sensor registers to the shadows:\n");
first_sensor_i2c=sensor->i2c_addr;
if (GLOBALPARS(sensor_port, G_SENS_AVAIL)) {
first_sensor_i2c+= I2C359_INC * ((GLOBALPARS(sensor_port, G_SENS_AVAIL) & 1)?1:((GLOBALPARS(sensor_port, G_SENS_AVAIL) & 2)?2:3));
}
i2c_read_data[0]=0;
local_irq_save(flags); // IRQ Off (rather long - all 256 registers through i2c, but there is no hurry - sensor is off)
i2c_stop_wait();
//G_SENS_AVAIL
i2c_writeData(0, (first_sensor_i2c) & 0xfe, i2c_read_data, 1, 0); // data (register #) is 0. no stop before read (cxi2c.c)
i2c_readData (0, (first_sensor_i2c) | 1, i2c_read_data, 512, 0); // read all 256 registers (512 bytes) restart, not strart (cxi2c.c)
local_irq_restore(flags); // IRQ restore
// save these registers as shadows and propagate
nupdate=0;
// For multiple sensors will use shadows from first one. Change?
for (i=0; i<256; i++) { // possible to modify register range to save (that is why nupdate is separate from i)
regval=I2C_READ_DATA16(i);
regnum=P_SENSOR_REGS+i;
SETFRAMEPARS_SET(regnum,regval);
if ((mreg=MULTIREG(regnum,0))) for (j=0;j<MAX_SENSORS; j++) {
SETFRAMEPARS_SET(mreg+j,regval);
}
}
#else
// CCAM_MRST_ON; // CCAM_MRST_ON;
if (debug_delays & 0xff) { if (debug_delays & 0xff) {
dev_dbg(g_dev_ptr,"Resetting MT9X001 sensor, port=%d\n",sensor_port); dev_dbg(g_dev_ptr,"Resetting MT9X001 sensor, port=%d\n",sensor_port);
...@@ -970,8 +902,12 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port ...@@ -970,8 +902,12 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
sensor_reg_copy[sensor_port][i] = i2c_read_data_dw[i]; sensor_reg_copy[sensor_port][i] = i2c_read_data_dw[i];
} }
#endif
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows // if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows
if (nupdate) setFrameParsStatic(sensor_port, nupdate, pars_to_update); // save changes to sensor register shadows for all frames
dev_dbg(g_dev_ptr,"Initializing MT9X001 registers with default values:\n"); dev_dbg(g_dev_ptr,"Initializing MT9X001 registers with default values:\n");
sensor_subtype=sensor->sensorType - SENSOR_MT9X001; sensor_subtype=sensor->sensorType - SENSOR_MT9X001;
switch (sensor_subtype) { switch (sensor_subtype) {
...@@ -995,20 +931,16 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port ...@@ -995,20 +931,16 @@ int mt9x001_pgm_initsensor (int sensor_port, ///< sensor port
} }
// enable hardware i2c - NOTE: the only place where the i2c controller is enabled. // enable hardware i2c - NOTE: the only place where the i2c controller is enabled.
// dev_dbg(g_dev_ptr,"Starting hardware sequencers\n"); // dev_dbg(g_dev_ptr,"Starting hardware sequencers\n");
#ifdef NC353
local_irq_save(flags); // IRQ Off, so both sequencers to be started at the same time
i2c_run();
X3X3_SEQ_RUN;
local_irq_restore(flags); // IRQ restore
#else
#endif
nupdate=0; // Second pass over the registers to set nupdate=0; // Second pass over the registers to set
//#define SET_SENSOR_MBPAR(p,f,s,r,v) //#define SET_SENSOR_MBPAR(p,f,s,r,v)
for (i=0; i<sensor_register_overwrites_number;i++ ) { // unconditionally set those registers NOTE: Should be < 63 of them! for (i=0; i<sensor_register_overwrites_number;i++ ) { // unconditionally set those registers NOTE: Should be < 63 of them!
SET_SENSOR_MBPAR(sensor_port, SET_SENSOR_MBPAR(sensor_port,
frame16, frame16, // == -1 (immediate)
sensor->i2c_addr, sensor->i2c_addr,
sensor_register_overwrites[2*i],\ sensor_register_overwrites[2*i],
sensor_register_overwrites[2*i+1]); sensor_register_overwrites[2*i+1]);
dev_dbg(g_dev_ptr,"{%d} SET_SENSOR_MBPAR(0x%x,0x%x,0x%x, 0x%x, 0x%x)\n",sensor_port, sensor_port, frame16, (int) sensor->i2c_addr, (int) sensor_register_overwrites[2*i], (int) sensor_register_overwrites[2*i+1]); dev_dbg(g_dev_ptr,"{%d} SET_SENSOR_MBPAR(0x%x,0x%x,0x%x, 0x%x, 0x%x)\n",sensor_port, sensor_port, frame16, (int) sensor->i2c_addr, (int) sensor_register_overwrites[2*i], (int) sensor_register_overwrites[2*i+1]);
...@@ -1390,6 +1322,8 @@ int mt9x001_pgm_limitfps (int sensor_port, ///< sensor port numb ...@@ -1390,6 +1322,8 @@ int mt9x001_pgm_limitfps (int sensor_port, ///< sensor port numb
SETFRAMEPARS_SET(P_PERIOD, pix_period); SETFRAMEPARS_SET(P_PERIOD, pix_period);
} }
// Update period from external trigger (assuming internal/self trigger, we do not know real external trigger period) // Update period from external trigger (assuming internal/self trigger, we do not know real external trigger period)
dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_TRIG] = %d, thispars->pars[P_TRIG_PERIOD] =%d(0x%x)\n",
sensor_port,(int)thispars->pars[P_TRIG], (int)thispars->pars[P_TRIG_PERIOD], (int)thispars->pars[P_TRIG_PERIOD]);
if (thispars->pars[P_TRIG]!=0){ if (thispars->pars[P_TRIG]!=0){
trig_period = camsync_to_sensor(thispars->pars[P_TRIG_PERIOD], thispars->pars[P_CLK_SENSOR]); trig_period = camsync_to_sensor(thispars->pars[P_TRIG_PERIOD], thispars->pars[P_CLK_SENSOR]);
if (trig_period > pix_period) pix_period=trig_period; if (trig_period > pix_period) pix_period=trig_period;
...@@ -1991,7 +1925,7 @@ int mt9x001_pgm_triggermode (int sensor_port, ///< sensor p ...@@ -1991,7 +1925,7 @@ int mt9x001_pgm_triggermode (int sensor_port, ///< sensor p
unsigned long newreg; unsigned long newreg;
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16); dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
if (frame16 >= PARS_FRAMES) return -1; // wrong frame if (frame16 >= PARS_FRAMES) return -1; // wrong frame
newreg= (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1] & 0xfe7f) | // old value without snamshot and GRR bits newreg= (thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1] & 0xfe7f) | // old value without snapshot and GRR bits
((thispars->pars[P_TRIG] & 4)?0x100:0) | // snapshot mode for P_TRIG==4 or 20 ((thispars->pars[P_TRIG] & 4)?0x100:0) | // snapshot mode for P_TRIG==4 or 20
((thispars->pars[P_TRIG] & 0x10)?0x80:0); // GRR mode for P_TRIG==20 ((thispars->pars[P_TRIG] & 0x10)?0x80:0); // GRR mode for P_TRIG==20
if (newreg != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1]) { if (newreg != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1]) {
......
...@@ -1002,7 +1002,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -1002,7 +1002,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
int i; int i;
int this_sensor_type; int this_sensor_type;
long * multiOutDelay; long * multiOutDelay;
x393_sens_mode_t sens_mode = {.d32=0}; // to disable senosr channel and prevent SoF pulses while 10359 memory is being trained x393_sens_mode_t sens_mode = {.d32=0}; // to disable senor channel and prevent SoF pulses while 10359 memory is being trained
sens_mode.chn_en = 0; sens_mode.chn_en = 0;
sens_mode.chn_en_set = 1; sens_mode.chn_en_set = 1;
X393_SEQ_SEND1 (sensor_port, frame16, x393_sens_mode, sens_mode); X393_SEQ_SEND1 (sensor_port, frame16, x393_sens_mode, sens_mode);
...@@ -1030,6 +1030,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -1030,6 +1030,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
if ((((bitstream_version ^ I2C359_MINVERSION) & 0xffff0000)!=0) || ((bitstream_version & 0xffff) < (I2C359_MINVERSION & 0xffff))) { if ((((bitstream_version ^ I2C359_MINVERSION) & 0xffff0000)!=0) || ((bitstream_version & 0xffff) < (I2C359_MINVERSION & 0xffff))) {
dev_err(g_dev_ptr,"invalid 10359 bitstream version, found 0x%08lx, required >= 0x%08x\n",bitstream_version, I2C359_MINVERSION ); dev_err(g_dev_ptr,"invalid 10359 bitstream version, found 0x%08lx, required >= 0x%08x\n",bitstream_version, I2C359_MINVERSION );
setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType);
common_pars->sensors[sensor_port] = sensor->sensorType;
return -1; return -1;
} }
dev_dbg(g_dev_ptr,"10359 bitstream version =0x%08lx\n",bitstream_version); dev_dbg(g_dev_ptr,"10359 bitstream version =0x%08lx\n",bitstream_version);
...@@ -1129,6 +1130,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p ...@@ -1129,6 +1130,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
if (GLOBALPARS(sensor_port,G_SENS_AVAIL)==0) { if (GLOBALPARS(sensor_port,G_SENS_AVAIL)==0) {
dev_warn(g_dev_ptr,"No supported sensors connected to 10359A board\n"); dev_warn(g_dev_ptr,"No supported sensors connected to 10359A board\n");
setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType); setFramePar(sensor_port, thispars, P_SENSOR, sensor->sensorType);
common_pars->sensors[sensor_port] = sensor->sensorType;
if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to sensor register shadows
return 0; return 0;
} }
......
...@@ -239,14 +239,15 @@ const unsigned long param_depend_tab[]= ...@@ -239,14 +239,15 @@ const unsigned long param_depend_tab[]=
P_RFOCUS_TOP, ONCHANGE_FOCUSMODE , P_RFOCUS_TOP, ONCHANGE_FOCUSMODE ,
P_RFOCUS_HEIGHT, ONCHANGE_FOCUSMODE , P_RFOCUS_HEIGHT, ONCHANGE_FOCUSMODE ,
P_FOCUS_FILTER, ONCHANGE_FOCUSMODE , P_FOCUS_FILTER, ONCHANGE_FOCUSMODE ,
P_TRIG_MASTER, ONCHANGE_TRIGSEQ ,
P_TRIG_CONDITION, ONCHANGE_TRIGSEQ , P_TRIG_CONDITION, ONCHANGE_TRIGSEQ ,
P_TRIG_DELAY, ONCHANGE_TRIGSEQ , P_TRIG_DELAY, ONCHANGE_TRIGSEQ ,
P_TRIG_OUT, ONCHANGE_TRIGSEQ , P_TRIG_OUT, ONCHANGE_TRIGSEQ ,
P_TRIG_PERIOD, ONCHANGE_TRIGSEQ , P_TRIG_PERIOD, ONCHANGE_TRIGSEQ | ONCHANGE_LIMITFPS,
P_SKIP_FRAMES, ONCHANGE_RECALCSEQ , P_SKIP_FRAMES, ONCHANGE_RECALCSEQ ,
P_I2C_QPERIOD, ONCHANGE_I2C , P_I2C_QPERIOD, ONCHANGE_I2C ,
P_I2C_BYTES, ONCHANGE_I2C , P_I2C_BYTES, ONCHANGE_I2C ,
P_IRQ_SMART, ONCHANGE_IRQ , P_I2C_EOF, ONCHANGE_IRQ ,
P_EXTERN_TIMESTAMP, ONCHANGE_TRIGSEQ , P_EXTERN_TIMESTAMP, ONCHANGE_TRIGSEQ ,
P_TRIG_BITLENGTH, ONCHANGE_TRIGSEQ , P_TRIG_BITLENGTH, ONCHANGE_TRIGSEQ ,
P_XMIT_TIMESTAMP, ONCHANGE_TRIGSEQ , P_XMIT_TIMESTAMP, ONCHANGE_TRIGSEQ ,
......
...@@ -379,6 +379,7 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( ...@@ -379,6 +379,7 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16) MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
if (frame16 >= 0) return -1; // can only work in ASAP mode if (frame16 >= 0) return -1; // can only work in ASAP mode
common_pars->sensors[sensor_port] = thispars->pars[P_SENSOR];
if (thispars->pars[P_SENSOR]) { if (thispars->pars[P_SENSOR]) {
dev_dbg(g_dev_ptr,"{%d} frame16=%d, SENSOR ALREADY DETECTED = %d\n",sensor_port,frame16, (int) thispars->pars[P_SENSOR]); dev_dbg(g_dev_ptr,"{%d} frame16=%d, SENSOR ALREADY DETECTED = %d\n",sensor_port,frame16, (int) thispars->pars[P_SENSOR]);
return 0; // Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0) return 0; // Sensor is already detected - do not bother (to re-detect it P_SENSOR should be set to 0)
...@@ -387,7 +388,6 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( ...@@ -387,7 +388,6 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
#ifndef NC353
// NC393 - nothing to do here - use a separate module for sensor setup: DT, sysfs, something else (add pin pullup/down) // NC393 - nothing to do here - use a separate module for sensor setup: DT, sysfs, something else (add pin pullup/down)
// currently assign same sensor to all subchannles (first present) // currently assign same sensor to all subchannles (first present)
// thispars->pars[P_SENSOR] = get_detected_sensor_code(sensor_port, -1); // "-1" - first detected sensor // thispars->pars[P_SENSOR] = get_detected_sensor_code(sensor_port, -1); // "-1" - first detected sensor
...@@ -408,22 +408,22 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( ...@@ -408,22 +408,22 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
i2c_drive_mode (sensor_port, SDA_DRIVE_HIGH, SDA_RELEASE); i2c_drive_mode (sensor_port, SDA_DRIVE_HIGH, SDA_RELEASE);
i2c_stop_run_reset (sensor_port, I2C_CMD_RUN); // also programs status update i2c_stop_run_reset (sensor_port, I2C_CMD_RUN); // also programs status update
legacy_i2c(1<<sensor_port);// Setup i2c pages for legacy i2c commands. TODO NC393: update for compatibility with 14MPix legacy_i2c(1<<sensor_port);// Setup i2c pages for legacy i2c commands. TODO NC393: update for compatibility with 14MPix
#ifdef INIT_IN_TRIGGERED
camsync_mode.trig = 1; // start in stopped triggered mode
#else
camsync_mode.trig = 0; camsync_mode.trig = 0;
#endif
camsync_mode.trig_set = 1; camsync_mode.trig_set = 1;
// This causes mismatch with parameters, let it be there // This causes mismatch with parameters, let it be there
// camsync_mode.ext = 1; // use external timestamp (default) // camsync_mode.ext = 1; // use external timestamp (default)
// camsync_mode.ext_set = 1; // camsync_mode.ext_set = 1;
x393_camsync_mode (camsync_mode); x393_camsync_mode (camsync_mode);
// Set inactive state to all I/O) and period: // Set inactive state to all I/O) and period:
x393_camsync_trig_src(camsync_src); x393_camsync_trig_src(camsync_src);
x393_camsync_trig_dst(camsync_dst); x393_camsync_trig_dst(camsync_dst);
set_x393_camsync_trig_period(0); set_x393_camsync_trig_period(0);
// dev_dbg(g_dev_ptr,"trying MT9P001\n"); // dev_dbg(g_dev_ptr,"trying MT9P001\n");
// mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type // mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type
...@@ -473,151 +473,14 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( ...@@ -473,151 +473,14 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
phase= 0x40000; phase= 0x40000;
setFramePar(sensor_port, thispars, P_SENSOR_PHASE | FRAMEPAIR_FORCE_NEWPROC, phase); // will schedule clock/phase adjustment setFramePar(sensor_port, thispars, P_SENSOR_PHASE | FRAMEPAIR_FORCE_NEWPROC, phase); // will schedule clock/phase adjustment
} }
setFramePar(sensor_port, thispars, P_IRQ_SMART | FRAMEPAIR_FORCE_NEWPROC, 3); // smart IRQ mode programming (and enable interrupts) setFramePar(sensor_port, thispars, P_I2C_EOF | FRAMEPAIR_FORCE_NEWPROC, 0); // increment i2c at SOF - change to EOF?
// NOTE: sensor detected - enabling camera interrupts here (actual interrupts will start later) // NOTE: sensor detected - enabling camera interrupts here (actual interrupts will start later)
// Here interrupts are disabled - with compressor_interrupts (0) earlier in this function) // Here interrupts are disabled - with compressor_interrupts (0) earlier in this function)
compressor_interrupts (1,sensor_port); // FIXME: Should they already be set beforfe detection? If not - remove from framepars.php compressor_interrupts (1,sensor_port); // FIXME: Should they already be set before detection? If not - remove from framepars.php
sensor_interrupts (1,sensor_port); sensor_interrupts (1,sensor_port);
return 0; return 0;
#else
// NOTE: disabling interrupts here !!!
compressor_interrupts (0);
dev_dbg(g_dev_ptr,"%s Disabled camera interrupts\n",__func__);
// This 3 initialization commands were not here, trying to temporarily fix problem when WP was 8/16 words higher than actual data in DMA buffer
if (GLOBALPARS(sensor_port, G_TEST_CTL_BITS) & (1<< G_TEST_CTL_BITS_RESET_DMA_COMPRESSOR )) {
dev_dbg(g_dev_ptr,"%s x313_dma_stop()\n",__func__);
/// x313_dma_stop();
dev_dbg(g_dev_ptr,"%s x313_dma_init()\n",__func__);
/// x313_dma_init();
dev_dbg(g_dev_ptr,"%s reset_compressor()\n",__func__);
reset_compressor(sensor_port);
}
// TODO: Add 10347 detection here // if (IS_KAI11000) return init_KAI11000();
// Need to set slow clock
// f1=imageParamsR[P_CLK_SENSOR]=20000000; setClockFreq(1, imageParamsR[P_CLK_SENSOR]); X3X3_RSTSENSDCM;
was_sensor_freq=getClockFreq(1); // using clock driver data, not thispars
setFramePar(sensor_port, thispars, P_CLK_FPGA, getClockFreq(0)); // just in case - read the actual fpga clock frequency and store it (no actions)
setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000);
setClockFreq(1, thispars->pars[P_CLK_SENSOR]);
dev_dbg(g_dev_ptr,"\nsensor clock set to %d\n",(int) thispars->pars[P_CLK_SENSOR]);
udelay (100);// 0.0001 sec to stabilize clocks
X3X3_RSTSENSDCM; // FPGA DCM can fail after clock change, needs to be reset
X3X3_SENSDCM_CLK2X_RESET; // reset pclk2x DCM also
mdelay (50);// 0.05 sec to stabilize clocks
// setting reasonable state of the control signals
CCAM_DCLK_ON;
CCAM_CNVEN_OFF;
CCAM_NEGRST; ///set negative MRST polarity
CCAM_MRST_ON;
CCAM_TRIG_INT;
CCAM_EXTERNALTS_EN; // Maybe use default as enabled - yes, it will not be active if not available
udelay (100); // apply clock before removing MRS
// first trying MT9P001 that does not need converter
// try multisensor here (before removing MRST)
if (thispars->pars[P_SENSOR]==0) multisensor_pgm_detectsensor (sensor_port, sensor, thispars, prevpars, frame16); // multisensor
if (thispars->pars[P_SENSOR]==0) {
dev_dbg(g_dev_ptr,"removing MRST from the sensor\n");
CCAM_MRST_OFF;
}
if (thispars->pars[P_SENSOR]==0) {
mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 5.0 Mpixel - should return sensor type
dev_dbg(g_dev_ptr,"trying MT9P001\n");
}
// temporary - disabling old sensors
#define ENABLE_OLD_SENSORS 1
#ifdef ENABLE_OLD_SENSORS
if (thispars->pars[P_SENSOR]==0) { // no - it is not MT9P001)
dev_dbg(g_dev_ptr,"trying other MT9X001\n");
CCAM_CNVEN_ON;
// CCAM_ARST_ON; ///MT9P001 expects ARST==0 (STANDBY) - done inside mt9x001.c
// enable output for power converter signals
// This should be done first!!!
// printk ("Will Turn DC power for the sensor after 1 sec delay...\n"); udelay (1000000);
// turning on DC-DC converter may cause system to reboot because of a power spike, so start slow
#ifdef NC353
port_csp0_addr[X313_WA_DCDC] = 0x44; // 48 - enough, 41 - ok - was 0x61; //
printk ("sensor power set low\n ");
mdelay (10); // Wait voltage to come up (~10 ms)
printk ("will set to 0x41\n");
mdelay (10); // to find the problem
port_csp0_addr[X313_WA_DCDC] = 0x41; //
printk ("will set to 0x30\n");
mdelay (10); // to find the problem
port_csp0_addr[X313_WA_DCDC] = 0x30; //
printk ("will set to 0x28\n");
mdelay (10); // to find the problem
port_csp0_addr[X313_WA_DCDC] = 0x28; //
printk ("will set to 0x24\n");
mdelay (10); // to find the problem
port_csp0_addr[X313_WA_DCDC] = 0x24; //
printk ("will set to 0x22\n");
mdelay (10); // to find the problem
port_csp0_addr[X313_WA_DCDC] = 0x22; //
mdelay (10); // to find the problem
port_csp0_addr[X313_WA_DCDC] = 0x10; // now - full frequency (same as 0x21). Slow that down if the sensor clock is above 20MHz (i.e.0x22 for 40MHz)
printk (".. full\n");
mdelay (10); // Wait voltage to stabilize
CCAM_POSRST; //set positive MRST polarity (default)
udelay (100); // apply clock before removing MRST
CCAM_MRST_OFF;
#endif
}
#ifdef CONFIG_ETRAX_ELPHEL_KAC1310
if (thispars->pars[P_SENSOR]==0) kac1310_pgm_detectsensor(sensor, thispars, prevpars, frame16); // try KAC-1310 (does not exist anymore)
#endif
#ifdef CONFIG_ETRAX_ELPHEL_IBIS51300
if (thispars->pars[P_SENSOR]==0) ibis1300_pgm_detectsensor(sensor, thispars, prevpars, frame16); // try IBIS5-1300 (software dead)
#endif
// invert MRST for other sensors
if (thispars->pars[P_SENSOR]==0) {
CCAM_NEGRST; //set negative MRST polarity
printk ("Inverted MRST\n");
udelay (100);
}
#ifdef CONFIG_ETRAX_ELPHEL_MT9X001
if (thispars->pars[P_SENSOR]==0) dev_dbg(g_dev_ptr,"trying MT9X001\n");
if (thispars->pars[P_SENSOR]==0) mt9x001_pgm_detectsensor(sensor_port, sensor, thispars, prevpars, frame16); // try Micron 1.3/2.0/3.0 Mpixel
#endif
#ifdef CONFIG_ETRAX_ELPHEL_KAC1310
if (thispars->pars[P_SENSOR]==0) kac5000_pgm_detectsensor(sensorsensor_port, sensor, thispars, prevpars, frame16); // try KAC-5000
#endif
#ifdef CONFIG_ETRAX_ELPHEL_ZR32112
if (thispars->pars[P_SENSOR]==0) zr32112_pgm_detectsensor(sensorsensor_port, sensor, thispars, prevpars, frame16); // try ZR32112
#endif
#ifdef CONFIG_ETRAX_ELPHEL_ZR32212
if (thispars->pars[P_SENSOR]==0) zr32212_pgm_detectsensor(sensorsensor_port, sensor, thispars, prevpars, frame16); // try ZR32212
#endif
#endif // ENABLE_OLD_SENSORS *************** temporary disabling other sensors ********************
if (thispars->pars[P_SENSOR]==0) {
sensor->sensorType=SENSOR_NONE; // to prevent from initializing again
dev_dbg(g_dev_ptr,"No image sensor found\n");
}
setFramePar(sensor_port, thispars, P_SENSOR_WIDTH, sensor->imageWidth); // Maybe get rid of duplicates?
setFramePar(sensor_port, thispars, P_SENSOR_HEIGHT, sensor->imageHeight); // Maybe get rid of duplicates?
if (sensor->i2c_period==0) sensor->i2c_period=2500; // SCL period in ns, (standard i2c - 2500)
qperiod=thispars->pars[P_I2C_QPERIOD];
if (qperiod==0) qperiod=(sensor->i2c_period * (thispars->pars[P_CLK_FPGA]/1000))/4000000;
setFramePar(sensor_port, thispars, P_I2C_QPERIOD | FRAMEPAIR_FORCE_NEWPROC, qperiod); // force i2c
i2cbytes=thispars->pars[P_I2C_BYTES];
if (i2cbytes==0) i2cbytes=sensor->i2c_bytes;
setFramePar(sensor_port, thispars, P_I2C_BYTES | FRAMEPAIR_FORCE_NEWPROC, i2cbytes); // force i2c
// restore/set sensor clock
if ((was_sensor_freq < sensor->minClockFreq) || (was_sensor_freq > sensor->maxClockFreq)) was_sensor_freq=sensor->nomClockFreq;
setFramePar(sensor_port, thispars, P_CLK_SENSOR | FRAMEPAIR_FORCE_NEWPROC, was_sensor_freq); // will schedule clock/phase adjustment
phase=thispars->pars[P_SENSOR_PHASE];
// TODO: remove phase adjustment from here
if (phase==0) {
phase= 0x40000;
setFramePar(sensor_port, thispars, P_SENSOR_PHASE | FRAMEPAIR_FORCE_NEWPROC, phase); // will schedule clock/phase adjustment
}
setFramePar(sensor_port, thispars, P_IRQ_SMART | FRAMEPAIR_FORCE_NEWPROC, 3); // smart IRQ mode programming (and enable interrupts)
// NOTE: sensor detected - enabling camera interrupts here (actual interrupts will start later)
// Here interrupts are disabled - with compressor_interrupts (0) earlier in this function)
compressor_interrupts (1);
return 0;
#endif
} }
/** Reset and initialize sensor (all is done in sensor-specific functions) /** Reset and initialize sensor (all is done in sensor-specific functions)
* - resets sensor, * - resets sensor,
...@@ -1397,6 +1260,10 @@ int pgm_limitfps (int sensor_port, ///< sensor port number (0..3 ...@@ -1397,6 +1260,10 @@ int pgm_limitfps (int sensor_port, ///< sensor port number (0..3
// if (async && (thispars->pars[P_TRIG_PERIOD] >=256)) { // <256 - single trig // if (async && (thispars->pars[P_TRIG_PERIOD] >=256)) { // <256 - single trig
// if (async && (thispars->pars[P_TRIG_PERIOD] !=1)) { // <256 - single trig, here only ==1 is for single // if (async && (thispars->pars[P_TRIG_PERIOD] !=1)) { // <256 - single trig, here only ==1 is for single
// Update period to comply even if it is not in async mode // Update period to comply even if it is not in async mode
if (!thispars->pars[P_CLK_SENSOR]){ // not initialized
dev_dbg(g_dev_ptr,"{%d} P_CLK_SENSOR == 0, abort command\n",sensor_port);
return -1;
}
if (thispars->pars[P_TRIG_PERIOD] !=1) { // <256 - single trig, here only ==1 is for single if (thispars->pars[P_TRIG_PERIOD] !=1) { // <256 - single trig, here only ==1 is for single
min_period_camsync = sensor_to_camsync(min_period, thispars->pars[P_CLK_SENSOR]); min_period_camsync = sensor_to_camsync(min_period, thispars->pars[P_CLK_SENSOR]);
if (thispars->pars[P_TRIG_PERIOD] < min_period_camsync) SETFRAMEPARS_SET(P_TRIG_PERIOD, min_period_camsync); // set it (and propagate to the later frames) if (thispars->pars[P_TRIG_PERIOD] < min_period_camsync) SETFRAMEPARS_SET(P_TRIG_PERIOD, min_period_camsync); // set it (and propagate to the later frames)
...@@ -1443,7 +1310,6 @@ int pgm_triggermode(int sensor_port, ///< sensor port number (0..3 ...@@ -1443,7 +1310,6 @@ int pgm_triggermode(int sensor_port, ///< sensor port number (0..3
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16); dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16) MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
if (frame16 >= PARS_FRAMES) return -1; // wrong frame if (frame16 >= PARS_FRAMES) return -1; // wrong frame
#ifndef NC353
camsync_mode.trig = (thispars->pars[P_TRIG] & 4)?1:0; camsync_mode.trig = (thispars->pars[P_TRIG] & 4)?1:0;
if (camsync_mode.trig) { // if trigger mode, enable camsync module, if off - do nothing if (camsync_mode.trig) { // if trigger mode, enable camsync module, if off - do nothing
camsync_mode.en = 1; camsync_mode.en = 1;
...@@ -1457,13 +1323,17 @@ int pgm_triggermode(int sensor_port, ///< sensor port number (0..3 ...@@ -1457,13 +1323,17 @@ int pgm_triggermode(int sensor_port, ///< sensor port number (0..3
// set directly, bypassing sequencer as it may fail with wrong trigger // set directly, bypassing sequencer as it may fail with wrong trigger
x393_camsync_mode (camsync_mode); x393_camsync_mode (camsync_mode);
MDP(DBGB_PADD, sensor_port,"x393_camsync_mode(0x%x)\n",camsync_mode.d32) MDP(DBGB_PADD, sensor_port,"x393_camsync_mode(0x%x)\n",camsync_mode.d32)
// now update common trigger parameters and mark dependent channels to update, if anything changed;
if (thispars->pars[P_TRIG] != common_pars->trig_mode){
int i;
dev_dbg(g_dev_ptr,"{%d} Updating common trigger mode, old=0x%lx, new=0x%lx\n",sensor_port,common_pars->trig_mode,thispars->pars[P_TRIG]);
common_pars->trig_mode = thispars->pars[P_TRIG];
for (i=0; i<SENSOR_PORTS; i++) if (i != sensor_port) {
common_pars->updated[i] = 1;
}
}
return 0; return 0;
#else
// int fpga_addr= frame16;
// int async=(thispars->pars[P_TRIG] & 4)?1:0;
X3X3_SEQ_SEND1(frame16, X313_WA_DCR0, X353_DCR0(SENSTRIGEN,async));
return 0;
#endif
} }
...@@ -2567,43 +2437,53 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3 ...@@ -2567,43 +2437,53 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3
struct frameparspair_t pars_to_update[10]; // ??? needed, increase if more entries will be added - just one struct frameparspair_t pars_to_update[10]; // ??? needed, increase if more entries will be added - just one
int nupdate=0; int nupdate=0;
int d; int d;
#ifndef NC353 int is_master = 0;
int update_master_channel = 0; // set if any of the common (not channel-specific) parameters is modified
x393_camsync_io_t camsync_src = {.d32=0}; x393_camsync_io_t camsync_src = {.d32=0};
x393_camsync_io_t camsync_dst = {.d32=0}; x393_camsync_io_t camsync_dst = {.d32=0};
x393_gpio_set_pins_t gpio_set_pins = {.d32=0}; x393_gpio_set_pins_t gpio_set_pins = {.d32=0};
x393_camsync_mode_t camsync_mode = {.d32=0}; x393_camsync_mode_t camsync_mode = {.d32=0};
int update_master_channel = 0; // set if any of the common (not channel-specific) parameters is modified
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16); dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16) MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
// MDP(DBGB_PADD, sensor_port,"X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",sensor_port, frame16, cmprs_mode.d32); // MDP(DBGB_PADD, sensor_port,"X393_SEQ_SEND1(0x%x, 0x%x, x393_cmprs_control_reg, 0x%x)\n",sensor_port, frame16, cmprs_mode.d32);
if (frame16 >= PARS_FRAMES) return -1; // wrong frame if (frame16 >= PARS_FRAMES) return -1; // wrong frame
if (frame16 >= 0) return -1; // ASAP only mode //+++++ if (frame16 >= 0) return -1; // ASAP only mode Was on
// Trigger condition changed? (0 - internal sequencer) // See if master channel is set to this channel directly
if (FRAMEPAR_MODIFIED(P_TRIG_CONDITION)) { is_master = (thispars->pars[P_TRIG_MASTER] == sensor_port)? 1 : 0;
camsync_src.d32 = thispars->pars[P_TRIG_CONDITION]; if (is_master && FRAMEPAR_MODIFIED(P_TRIG_MASTER)) {
x393_camsync_trig_src(camsync_src); update_master_channel = 1;
update_master_channel=1; camsync_mode.master_chn = sensor_port;
dev_dbg(g_dev_ptr,"{%d} x393_camsync_trig_src(0x%x)\n",sensor_port, camsync_src.d32); camsync_mode.master_chn_set = 1;
MDP(DBGB_PADD, sensor_port,"x393_camsync_trig_src(0x%x)\n", camsync_src.d32)
} }
// Process per-channel (not common) parameters regardless of the master status (just trigger delay)
// Trigger delay changed? // Trigger delay changed?
if (FRAMEPAR_MODIFIED(P_TRIG_DELAY)) { // individual per-channel parameters if (FRAMEPAR_MODIFIED(P_TRIG_DELAY)) { // individual per-channel parameters
set_x393_camsync_trig_delay (thispars->pars[P_TRIG_DELAY], sensor_port); // CAMSYNC trigger delay set_x393_camsync_trig_delay (thispars->pars[P_TRIG_DELAY], sensor_port); // CAMSYNC trigger delay
dev_dbg(g_dev_ptr,"{%d} set_x393_camsync_trig_delay(0x%x, %d)\n",sensor_port, camsync_src.d32, sensor_port); dev_dbg(g_dev_ptr,"{%d} set_x393_camsync_trig_delay(0x%x, %d)\n",sensor_port, camsync_src.d32, sensor_port);
MDP(DBGB_PADD, sensor_port,"set_x393_camsync_trig_delay(0x%x, %d)\n", camsync_src.d32, sensor_port) MDP(DBGB_PADD, sensor_port,"set_x393_camsync_trig_delay(0x%x, %d)\n", camsync_src.d32, sensor_port)
} }
if (!is_master){
dev_dbg(g_dev_ptr,"{%d} frame16=%d: nothing to do, master channel is %d\n",sensor_port,frame16, (int) thispars->pars[P_TRIG_MASTER]);
return 0;
}
// Trigger condition changed? (0 - internal sequencer)
if (FRAMEPAR_MODIFIED(P_TRIG_CONDITION)) {
camsync_src.d32 = thispars->pars[P_TRIG_CONDITION];
x393_camsync_trig_src(camsync_src);
// update_master_channel=1;
dev_dbg(g_dev_ptr,"{%d} x393_camsync_trig_src(0x%x)\n",sensor_port, camsync_src.d32);
MDP(DBGB_PADD, sensor_port,"x393_camsync_trig_src(0x%x)\n", camsync_src.d32)
}
// Sequencer output word changed? (to which outputs it is sent and what polarity) // Sequencer output word changed? (to which outputs it is sent and what polarity)
if (FRAMEPAR_MODIFIED(P_TRIG_OUT)) { if (FRAMEPAR_MODIFIED(P_TRIG_OUT)) {
camsync_dst.d32 = thispars->pars[P_TRIG_OUT]; camsync_dst.d32 = thispars->pars[P_TRIG_OUT];
x393_camsync_trig_dst(camsync_dst); x393_camsync_trig_dst(camsync_dst);
update_master_channel=1; // update_master_channel=1;
dev_dbg(g_dev_ptr,"{%d} x393_camsync_trig_dst(0x%x)\n",sensor_port, camsync_dst.d32); dev_dbg(g_dev_ptr,"{%d} x393_camsync_trig_dst(0x%x)\n",sensor_port, camsync_dst.d32);
MDP(DBGB_PADD, sensor_port,"x393_camsync_trig_dst(0x%x)\n", camsync_dst.d32) MDP(DBGB_PADD, sensor_port,"x393_camsync_trig_dst(0x%x)\n", camsync_dst.d32)
// dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_CAMSYNCOUT, (int) thispars->pars[P_TRIG_OUT]);
// Enable connection from the trigger module to the FPGA GPIO pins
if (thispars->pars[P_TRIG_OUT]!=0) { if (thispars->pars[P_TRIG_OUT]!=0) {
gpio_set_pins.chn_a = 3; // Set dibit enable gpio_set_pins.chn_a = 3; // Set dibit enable
x393_gpio_set_pins(gpio_set_pins); x393_gpio_set_pins(gpio_set_pins);
...@@ -2635,7 +2515,7 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3 ...@@ -2635,7 +2515,7 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3
SETFRAMEPARS_SET(P_TRIG_PERIOD,prevpars->pars[P_TRIG_PERIOD]); //+1 SETFRAMEPARS_SET(P_TRIG_PERIOD,prevpars->pars[P_TRIG_PERIOD]); //+1
} else { } else {
set_x393_camsync_trig_period(thispars->pars[P_TRIG_PERIOD]); set_x393_camsync_trig_period(thispars->pars[P_TRIG_PERIOD]);
update_master_channel=1; // update_master_channel=1;
dev_dbg(g_dev_ptr,"{%d} set_x393_camsync_trig_period(0x%lx)\n",sensor_port, thispars->pars[P_TRIG_PERIOD]); dev_dbg(g_dev_ptr,"{%d} set_x393_camsync_trig_period(0x%lx)\n",sensor_port, thispars->pars[P_TRIG_PERIOD]);
MDP(DBGB_PADD, sensor_port,"set_x393_camsync_trig_period(0x%lx)\n", thispars->pars[P_TRIG_PERIOD]) MDP(DBGB_PADD, sensor_port,"set_x393_camsync_trig_period(0x%lx)\n", thispars->pars[P_TRIG_PERIOD])
} }
...@@ -2644,7 +2524,7 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3 ...@@ -2644,7 +2524,7 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3
if (FRAMEPAR_MODIFIED(P_EXTERN_TIMESTAMP)) { if (FRAMEPAR_MODIFIED(P_EXTERN_TIMESTAMP)) {
camsync_mode.ext = thispars->pars[P_EXTERN_TIMESTAMP]?1:0; camsync_mode.ext = thispars->pars[P_EXTERN_TIMESTAMP]?1:0;
camsync_mode.ext_set = 1; camsync_mode.ext_set = 1;
update_master_channel=1; // update_master_channel=1;
} }
// P_XMIT_TIMESTAMP changed? (0 - internal sequencer) // P_XMIT_TIMESTAMP changed? (0 - internal sequencer)
if (FRAMEPAR_MODIFIED(P_XMIT_TIMESTAMP)) { if (FRAMEPAR_MODIFIED(P_XMIT_TIMESTAMP)) {
...@@ -2654,77 +2534,39 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3 ...@@ -2654,77 +2534,39 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3
// camsync_mode.ts_chns = (thispars->pars[P_EXTERN_TIMESTAMP]?1:0) << sensor_port; // camsync_mode.ts_chns = (thispars->pars[P_EXTERN_TIMESTAMP]?1:0) << sensor_port;
// camsync_mode.ts_chns_set = 1 << sensor_port; // camsync_mode.ts_chns_set = 1 << sensor_port;
} }
if (update_master_channel){
camsync_mode.master_chn = sensor_port;
camsync_mode.master_chn_set = 1;
}
if (camsync_mode.d32){ // anything set? if (camsync_mode.d32){ // anything set?
x393_camsync_mode (camsync_mode); x393_camsync_mode (camsync_mode);
dev_dbg(g_dev_ptr,"{%d} x393_camsync_mode(0x%x)\n",sensor_port, camsync_mode.d32); dev_dbg(g_dev_ptr,"{%d} x393_camsync_mode(0x%x)\n",sensor_port, camsync_mode.d32);
MDP(DBGB_PADD, sensor_port,"x393_camsync_mode(0x%x)\n", camsync_mode.d32) MDP(DBGB_PADD, sensor_port,"x393_camsync_mode(0x%x)\n", camsync_mode.d32)
} }
// Does not seem to have any parameters to update?
if (nupdate) setFramePars(sensor_port, thispars, nupdate, pars_to_update); // save changes, schedule functions if (nupdate) setFramePars(sensor_port, thispars, nupdate, pars_to_update); // save changes, schedule functions
return 0;
#else // now update common trigger parameters and mark dependent channels to update, if anything changed;
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16); if ((thispars->pars[P_TRIG_MASTER] != common_pars->master_chn) ||
if (frame16 >= PARS_FRAMES) return -1; // wrong frame (thispars->pars[P_TRIG_PERIOD] != common_pars->trig_period) ||
if (frame16 >= 0) return -1; // ASAP only mode (thispars->pars[P_TRIG_BITLENGTH] != common_pars->trig_bitlength) ||
// Trigger condition changed? (0 - internal sequencer) (thispars->pars[P_EXTERN_TIMESTAMP] != common_pars->extern_timestamp) ||
if (FRAMEPAR_MODIFIED(P_TRIG_CONDITION)) { (thispars->pars[P_XMIT_TIMESTAMP] != common_pars->xmit_timestamp) ||
port_csp0_addr[X313_WA_CAMSYNCTRIG] = thispars->pars[P_TRIG_CONDITION]; (thispars->pars[P_TRIG_CONDITION] != common_pars->trig_condition) ||
dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_CAMSYNCTRIG, (int)thispars->pars[P_TRIG_CONDITION]); (thispars->pars[P_TRIG_OUT] != common_pars->trig_out)){
} int i; //, f;
// Trigger delay changed? dev_dbg(g_dev_ptr,"{%d} Updating common trigger parameters\n",sensor_port);
if (FRAMEPAR_MODIFIED(P_TRIG_DELAY)) { common_pars->master_chn = thispars->pars[P_TRIG_MASTER];
port_csp0_addr[X313_WA_CAMSYNCDLY] = thispars->pars[P_TRIG_DELAY]; common_pars->trig_period = thispars->pars[P_TRIG_PERIOD];
dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_CAMSYNCDLY, (int) thispars->pars[P_TRIG_DELAY]); common_pars->trig_bitlength = thispars->pars[P_TRIG_BITLENGTH];
} common_pars->extern_timestamp = thispars->pars[P_EXTERN_TIMESTAMP];
// Sequencer output word changed? (to which outputs it is sent and what polarity) common_pars->xmit_timestamp = thispars->pars[P_XMIT_TIMESTAMP];
if (FRAMEPAR_MODIFIED(P_TRIG_OUT)) { common_pars->trig_condition = thispars->pars[P_TRIG_CONDITION];
port_csp0_addr[X313_WA_CAMSYNCOUT] = thispars->pars[P_TRIG_OUT]; common_pars->trig_out = thispars->pars[P_TRIG_OUT];
dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_CAMSYNCOUT, (int) thispars->pars[P_TRIG_OUT]); // f = (frame16<0)? -1:(frame16 + 1);
// Enable connection from the trigger module to the FPGA GPIO pins for (i=0; i<SENSOR_PORTS; i++) if (i != sensor_port) {
if (thispars->pars[P_TRIG_OUT]!=0) { common_pars->updated[i] = 1; //f;
port_csp0_addr[X313_WA_IOPINS] = X313_WA_IOPINS_EN_TRIG_OUT;
dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_IOPINS, (int) X313_WA_IOPINS_EN_TRIG_OUT);
} else {
// Not needed, I think
// port_csp0_addr[X313_WA_IOPINS] = X313_WA_IOPINS_DIS_TRIG_OUT;
// dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_IOPINS, (int) X313_WA_IOPINS_DIS_TRIG_OUT);
}
}
// Sequencer period changed? (0 - stopped, 1 - single trigger, >=256 - start repetitive)
if (FRAMEPAR_MODIFIED(P_TRIG_PERIOD)) {
if (unlikely((thispars->pars[P_TRIG_PERIOD] > 1) && (thispars->pars[P_TRIG_PERIOD] < 256))) { // Wrong value, restore old one
SETFRAMEPARS_SET(P_TRIG_PERIOD,prevpars->pars[P_TRIG_PERIOD]);
} else {
port_csp0_addr[X313_WA_CAMSYNCPER] = thispars->pars[P_TRIG_PERIOD];
dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_CAMSYNCPER, (int)thispars->pars[P_TRIG_PERIOD]);
}
}
// Bit length changed or not yet initialized?
if (FRAMEPAR_MODIFIED(P_TRIG_BITLENGTH) || (thispars->pars[P_TRIG_BITLENGTH]==0)) {
d=thispars->pars[P_TRIG_BITLENGTH];
if (unlikely((d<2) || (d>255))) { // Wrong value, restore old one
d=P_TRIG_BITLENGTH_DEFAULT;
SETFRAMEPARS_SET(P_TRIG_BITLENGTH,d);
} }
port_csp0_addr[X313_WA_CAMSYNCPER] = d; dev_dbg(g_dev_ptr,"{%d} common_pars->updated= {%ld, %ld, %ld, %ld}\n",sensor_port,
dev_dbg(g_dev_ptr,"{%d} writing bit length-1: port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_CAMSYNCPER, d); common_pars->updated[0],common_pars->updated[1],common_pars->updated[2],common_pars->updated[3]);
} }
// P_EXTERN_TIMESTAMP changed? (0 - internal sequencer)
if (FRAMEPAR_MODIFIED(P_EXTERN_TIMESTAMP)) {
port_csp0_addr[X313_WA_DCR1]=X353_DCR1(EXTERNALTS,thispars->pars[P_EXTERN_TIMESTAMP]?1:0);
dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_DCR1, (int)X353_DCR1(EXTERNALTS,thispars->pars[P_EXTERN_TIMESTAMP]?1:0));
}
// P_XMIT_TIMESTAMP changed? (0 - internal sequencer)
if (FRAMEPAR_MODIFIED(P_XMIT_TIMESTAMP)) {
port_csp0_addr[X313_WA_DCR1]=X353_DCR1(OUTPUTTS,thispars->pars[P_XMIT_TIMESTAMP]?1:0);
dev_dbg(g_dev_ptr,"{%d} port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_DCR1, (int)X353_DCR1(OUTPUTTS,thispars->pars[P_XMIT_TIMESTAMP]?1:0));
}
if (nupdate) setFramePars(sensor_port, thispars, nupdate, pars_to_update); // save changes, schedule functions
return 0; return 0;
#endif
} }
/** Program smart IRQ mode (needs to be on, at least bit 0) /** Program smart IRQ mode (needs to be on, at least bit 0)
...@@ -2738,8 +2580,9 @@ int pgm_irq (int sensor_port, ///< sensor port number (0..3) ...@@ -2738,8 +2580,9 @@ int pgm_irq (int sensor_port, ///< sensor port number (0..3)
///< be applied to, negative - ASAP ///< be applied to, negative - ASAP
///< @return OK - 0, <0 - error ///< @return OK - 0, <0 - error
{ {
x393_i2c_ctltbl_t i2c_ctl = {.d32=0};
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16); dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
MDP(DBGB_PSFN, sensor_port,"frame16=%d, does nothing\n",frame16) MDP(DBGB_PSFN, sensor_port,"frame16=%d,\n",frame16)
if (frame16 >= PARS_FRAMES) return -1; // wrong frame if (frame16 >= PARS_FRAMES) return -1; // wrong frame
#ifdef NC353 #ifdef NC353
int fpga_addr=(frame16 <0) ? X313_SEQ_ASAP : (X313_SEQ_FRAME0+frame16); int fpga_addr=(frame16 <0) ? X313_SEQ_ASAP : (X313_SEQ_FRAME0+frame16);
...@@ -2750,8 +2593,13 @@ int pgm_irq (int sensor_port, ///< sensor port number (0..3) ...@@ -2750,8 +2593,13 @@ int pgm_irq (int sensor_port, ///< sensor port number (0..3)
X3X3_SEQ_SEND1(fpga_addr, X313_WA_SMART_IRQ, (2 | ((thispars->pars[P_IRQ_SMART] & 1)?1:0)) | \ X3X3_SEQ_SEND1(fpga_addr, X313_WA_SMART_IRQ, (2 | ((thispars->pars[P_IRQ_SMART] & 1)?1:0)) | \
(8 | ((thispars->pars[P_IRQ_SMART] & 2)?4:0))); (8 | ((thispars->pars[P_IRQ_SMART] & 2)?4:0)));
#else
i2c_ctl.eof_not_sof = thispars->pars[P_I2C_EOF]?3:2; // set on or off (MSB - "set")
X393_SEQ_SEND1 (sensor_port, frame16, x393_sensi2c_ctrl, i2c_ctl);
#endif #endif
/* /*
if (thispars->pars[P_COMPRESSOR_RUN]==0) {
*
MDF3(dev_dbg(g_dev_ptr," X3X3_SEQ_SEND1(0x%x,0x%x, 0x%x)\n", fpga_addr, (int) X313_WA_SMART_IRQ, (int) ( (2 | ((thispars->pars[P_IRQ_SMART] & 1)?1:0)) | \ MDF3(dev_dbg(g_dev_ptr," X3X3_SEQ_SEND1(0x%x,0x%x, 0x%x)\n", fpga_addr, (int) X313_WA_SMART_IRQ, (int) ( (2 | ((thispars->pars[P_IRQ_SMART] & 1)?1:0)) | \
(8 | ((thispars->pars[P_IRQ_SMART] & 2)?4:0))))); (8 | ((thispars->pars[P_IRQ_SMART] & 2)?4:0)))));
*/ */
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define USELONGLONG 1 #define USELONGLONG 1
#define ETRAXFS_MMAP_CACHE_BUG y #define ETRAXFS_MMAP_CACHE_BUG y
//#define INIT_IN_TRIGGERED // Init sensors in triggered mode, stopped
#if ELPHEL_DEBUG #if ELPHEL_DEBUG
#define EDBG(x) x #define EDBG(x) x
...@@ -279,6 +280,7 @@ ...@@ -279,6 +280,7 @@
#define SENSORWIDTH_IBIS51300 1280 ///< FillFactory IBIS51300 width #define SENSORWIDTH_IBIS51300 1280 ///< FillFactory IBIS51300 width
#define SENSORHEIGHT_IBIS51300 1024 ///< FillFactory IBIS51300 height #define SENSORHEIGHT_IBIS51300 1024 ///< FillFactory IBIS51300 height
#define P_TRIG_MASTER 3 ///< Master channel for setting trigger para,eters
#define P_SENSOR_RUN 4 ///< Sensor acquisition mode 0 - stop, 1 - single, 2 - run #define P_SENSOR_RUN 4 ///< Sensor acquisition mode 0 - stop, 1 - single, 2 - run
#define SENSOR_RUN_STOP 0 ///< Sensor acquisition mode: STOP #define SENSOR_RUN_STOP 0 ///< Sensor acquisition mode: STOP
#define SENSOR_RUN_SINGLE 1 ///< Sensor acquisition mode: SINGLE FRAME #define SENSOR_RUN_SINGLE 1 ///< Sensor acquisition mode: SINGLE FRAME
...@@ -449,8 +451,9 @@ ...@@ -449,8 +451,9 @@
#define P_SKIP_FRAMES 107 ///< number of frames to skip after restarting sensor+compressor - now zero/nonzero? #define P_SKIP_FRAMES 107 ///< number of frames to skip after restarting sensor+compressor - now zero/nonzero?
#define P_I2C_QPERIOD 108 ///< number of system clock periods in 1/4 of i2c SCL period to the sensor/sensor board // 393: Moved to DT #define P_I2C_QPERIOD 108 ///< number of system clock periods in 1/4 of i2c SCL period to the sensor/sensor board // 393: Moved to DT
#define P_I2C_BYTES 109 ///< number of bytes in hardware i2c write (after slave addr) -0/1/2 #define P_I2C_BYTES 109 ///< number of bytes in hardware i2c write (after slave addr) -0/1/2
#define P_IRQ_SMART 110 ///< TODO: Obsolete for 393, update"smart" IRQ modes: +1 - wait for VACT in early compressor_done, //#define P_IRQ_SMART 110 ///< TODO: Obsolete for 393, update"smart" IRQ modes: +1 - wait for VACT in early compressor_done,
///< +2 - wait for dma fifo ready // 393: Combine IRQ? 353: bit 0 will be always 1 (needs fix in FPGA) ///< +2 - wait for dma fifo ready // 393: Combine IRQ? 353: bit 0 will be always 1 (needs fix in FPGA)
#define P_I2C_EOF 110 ///< 0:increment i2c sequencer at the SOF (same as ystem frame), 1 - increment early (at previous EOF)
#define P_EXTERN_TIMESTAMP 111 ///< Use external timestamp (received with sync) when availabele, 0 - always use local timestamp #define P_EXTERN_TIMESTAMP 111 ///< Use external timestamp (received with sync) when availabele, 0 - always use local timestamp
#define P_OVERSIZE 112 ///< ignore sensor dimensions, use absolute WOI_LEFT, WOI_TOP #define P_OVERSIZE 112 ///< ignore sensor dimensions, use absolute WOI_LEFT, WOI_TOP
#define P_XMIT_TIMESTAMP 113 ///< 0 - transmit just sync pulse, 1 - pulse+timestamp over the sync line #define P_XMIT_TIMESTAMP 113 ///< 0 - transmit just sync pulse, 1 - pulse+timestamp over the sync line
...@@ -988,7 +991,8 @@ struct framepars_past_t { ...@@ -988,7 +991,8 @@ struct framepars_past_t {
}; };
/// All parameter data for a sensor port, including future ones and past. Size should be PAGE_SIZE aligned /// All parameter data for a sensor port, including future ones and past. Size should be PAGE_SIZE aligned
struct framepars_all_t { struct framepars_all_t
{
struct framepars_t framePars[PARS_FRAMES]; ///< Future frame parameters struct framepars_t framePars[PARS_FRAMES]; ///< Future frame parameters
struct framepars_t func2call; ///< func2call.pars[] - each parameter has a 32-bit mask of what pgm_function to call - other fields not used struct framepars_t func2call; ///< func2call.pars[] - each parameter has a 32-bit mask of what pgm_function to call - other fields not used
unsigned long globalPars[NUM_GPAR]; ///< parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both R/W unsigned long globalPars[NUM_GPAR]; ///< parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both R/W
...@@ -997,6 +1001,32 @@ struct framepars_all_t { ...@@ -997,6 +1001,32 @@ struct framepars_all_t {
unsigned long multiSensRvrsIndex[P_MAX_PAR_ROUNDUP]; ///< reverse index (to parent) for the multiSensIndex in lower 16 bits, high 16 bits - sensor number unsigned long multiSensRvrsIndex[P_MAX_PAR_ROUNDUP]; ///< reverse index (to parent) for the multiSensIndex in lower 16 bits, high 16 bits - sensor number
}; };
/// Parameters, common for all channels (trigger mode)
struct common_pars_t{
unsigned long master_chn; ///< Master channel (controlparameters through this channel) ([0] - value, [1] - frame)
unsigned long sensors[SENSOR_PORTS]; ///< detected sensors
long updated[SENSOR_PORTS]; ///< 0 no update, -1 - ASAP, SENSOR_PORTS - frame 0, 2*SENSOR_PORTS-1 - SENSOR_PORTS-1
unsigned long trig_period; ///< Trigger period (in 100 MHz clocks
unsigned long trig_bitlength; ///< duration of one bit minus 1 in 25MHz clocks, maximal value 255 (256*40ns)
unsigned long extern_timestamp; ///< Use external (received) timestamp if available
unsigned long xmit_timestamp; ///< Transmit timestamp with sync pulse
unsigned long trig_condition; ///< Trigger condition (Each dibit: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high)
unsigned long trig_out; ///< trigger output (Each dibit: 0 - inactive, 1 - keep (nop), 2 - active low, 3 - active high)
unsigned long trig_mode; ///< trigger_mode (0: free running, 4 - ERS snapshot, 20 - GRR
};
/*
#define TRIGMODE_FREERUN 0
#define TRIGMODE_SNAPSHOT 4
#define TRIGMODE_GRR 20
* TRIG_PERIOD 500 0x1f4
* TRIG_BITLENGTH 31 0x1f
* EXTERN_TIMESTAMP 1 0x1
* XMIT_TIMESTAMP 0 0x0
* TRIG_CONDITION 0 0x0
* TRIG_OUT 0 0x0
*/
/// Key/value pair of parameters /// Key/value pair of parameters
struct frameparspair_t { struct frameparspair_t {
unsigned long num; ///< parameter index ( as defined by P_* constants) ORed with "force new" (0x10000) - parameter value will be considered a new one unsigned long num; ///< parameter index ( as defined by P_* constants) ORed with "force new" (0x10000) - parameter value will be considered a new one
...@@ -1073,6 +1103,7 @@ struct p_names_t { ...@@ -1073,6 +1103,7 @@ struct p_names_t {
#define DEFINE_P_NAMES(x) struct p_names_t x[]= { \ #define DEFINE_P_NAMES(x) struct p_names_t x[]= { \
P_NAME_ENTRY(NUMBER), \ P_NAME_ENTRY(NUMBER), \
P_NAME_ENTRY(SENSOR), \ P_NAME_ENTRY(SENSOR), \
P_NAME_ENTRY(TRIG_MASTER), \
P_NAME_ENTRY(SENSOR_RUN), \ P_NAME_ENTRY(SENSOR_RUN), \
P_NAME_ENTRY(SENSOR_SINGLE), \ P_NAME_ENTRY(SENSOR_SINGLE), \
P_NAME_ENTRY(ACTUAL_WIDTH), \ P_NAME_ENTRY(ACTUAL_WIDTH), \
...@@ -1189,7 +1220,7 @@ struct p_names_t { ...@@ -1189,7 +1220,7 @@ struct p_names_t {
P_NAME_ENTRY(SKIP_FRAMES), \ P_NAME_ENTRY(SKIP_FRAMES), \
P_NAME_ENTRY(I2C_QPERIOD), \ P_NAME_ENTRY(I2C_QPERIOD), \
P_NAME_ENTRY(I2C_BYTES), \ P_NAME_ENTRY(I2C_BYTES), \
P_NAME_ENTRY(IRQ_SMART), \ P_NAME_ENTRY(I2C_EOF), \
P_NAME_ENTRY(EXTERN_TIMESTAMP), \ P_NAME_ENTRY(EXTERN_TIMESTAMP), \
P_NAME_ENTRY(OVERSIZE), \ P_NAME_ENTRY(OVERSIZE), \
P_NAME_ENTRY(XMIT_TIMESTAMP), \ P_NAME_ENTRY(XMIT_TIMESTAMP), \
...@@ -1485,7 +1516,7 @@ struct p_names_t { ...@@ -1485,7 +1516,7 @@ struct p_names_t {
#define LSEEK_AUTOEXP_GET 0x1a ///< copy window and exposure parameters to autoexp_state #define LSEEK_AUTOEXP_GET 0x1a ///< copy window and exposure parameters to autoexp_state
#define LSEEK_TRIGGER_PGM 0x1b ///< program trigger parameters #define LSEEK_TRIGGER_PGM 0x1b ///< program trigger parameters
#define LSEEK_I2C_PGM 0x1c ///< program hardware i2c speed/bytes #define LSEEK_I2C_PGM 0x1c ///< program hardware i2c speed/bytes
#define LSEEK_IRQ_SMART_PGM 0x1d ///< program "smart" irq modes (+1 - wait VACT, +2 - wait dma fifo) #define LSEEK_I2C_EOF_PGM 0x1d ///< program "smart" irq modes (+1 - wait VACT, +2 - wait dma fifo)
#define LSEEK_EXTERN_TIMESTAMP_PGM 0x1e ///< 1 - use external timestamps if available #define LSEEK_EXTERN_TIMESTAMP_PGM 0x1e ///< 1 - use external timestamps if available
#define LSEEK_DMA_INIT 0x1f ///< (re-) initialize ETRAX DMA for compressor #define LSEEK_DMA_INIT 0x1f ///< (re-) initialize ETRAX DMA for compressor
#define LSEEK_DMA_STOP 0x20 ///< STOP ETRAX DMA #define LSEEK_DMA_STOP 0x20 ///< STOP ETRAX DMA
...@@ -1572,7 +1603,7 @@ struct p_names_t { ...@@ -1572,7 +1603,7 @@ struct p_names_t {
LSEEK_NAME_ENTRY(AUTOEXP_GET), \ LSEEK_NAME_ENTRY(AUTOEXP_GET), \
LSEEK_NAME_ENTRY(TRIGGER_PGM), \ LSEEK_NAME_ENTRY(TRIGGER_PGM), \
LSEEK_NAME_ENTRY(I2C_PGM), \ LSEEK_NAME_ENTRY(I2C_PGM), \
LSEEK_NAME_ENTRY(IRQ_SMART_PGM), \ LSEEK_NAME_ENTRY(I2C_EOF_PGM), \
LSEEK_NAME_ENTRY(EXTERN_TIMESTAMP_PGM), \ LSEEK_NAME_ENTRY(EXTERN_TIMESTAMP_PGM), \
LSEEK_NAME_ENTRY(DMA_INIT), \ LSEEK_NAME_ENTRY(DMA_INIT), \
LSEEK_NAME_ENTRY(DMA_STOP), \ LSEEK_NAME_ENTRY(DMA_STOP), \
...@@ -1956,8 +1987,19 @@ struct huffman_encoded_t { ...@@ -1956,8 +1987,19 @@ struct huffman_encoded_t {
}; };
/// All other integer constants exported to PHP space (C:"CONSTANT" -> PHP:"ELPHEL_CONST_CONSTANT) /// All other integer constants exported to PHP space (C:"CONSTANT" -> PHP:"ELPHEL_CONST_CONSTANT)
#define FRAME_ASAP -1 // use in PHP to specify ASAP through normal sequencer (current frame plus minimal latency)
#define FRAME_IMMED -2 // use in PHP to specify ASAP bypassing sequencer - works w/o frame sync pulses
#define TRIGMODE_FREERUN 0
#define TRIGMODE_SNAPSHOT 4
#define TRIGMODE_GRR 20
#define CONST_NAME_ENTRY(y) { y, #y } #define CONST_NAME_ENTRY(y) { y, #y }
#define DEFINE_CONST_NAMES(x) struct p_names_t x[]= { \ #define DEFINE_CONST_NAMES(x) struct p_names_t x[]= { \
CONST_NAME_ENTRY(FRAME_IMMED), \
CONST_NAME_ENTRY(FRAME_ASAP), \
CONST_NAME_ENTRY(TRIGMODE_FREERUN), \
CONST_NAME_ENTRY(TRIGMODE_SNAPSHOT), \
CONST_NAME_ENTRY(TRIGMODE_GRR), \
CONST_NAME_ENTRY(SENSOR_RUN_STOP), \ CONST_NAME_ENTRY(SENSOR_RUN_STOP), \
CONST_NAME_ENTRY(SENSOR_RUN_SINGLE), \ CONST_NAME_ENTRY(SENSOR_RUN_SINGLE), \
CONST_NAME_ENTRY(SENSOR_RUN_CONT), \ CONST_NAME_ENTRY(SENSOR_RUN_CONT), \
......
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