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); ///<
/** 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};
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 */
//struct sensorproc_t * sensorproc = NULL;
//void compressor_interrupts (int on) {}
......@@ -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
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
common_pars = &scommon_pars;
}
int framepars_open(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);
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);
void trigSlaveUpdate(int sensor_port);
/**
* @brief Reset hardware sequencers (i2c, command) and initialize framepars structure
* Does not seem to do anything with the sequencers
*/
int initSequencers(int sensor_port)
{
......@@ -268,7 +288,7 @@ int initSequencers(int sensor_port)
if (!hardware_initialized) {
dev_dbg(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
// Start RTC by writing 0 to seconds if it was not already set, otherwise preserve current time
get_fpga_rtc(&sec_usec);
......@@ -287,6 +307,31 @@ int initSequencers(int sensor_port)
initFramePars(sensor_port);
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 */
void resetFrameNumber(int sensor_port, ///< sensor_port sensor port number (0..3)
......@@ -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))
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;
dev_dbg(g_devfp_ptr,"%s : port= %d, .functions=0x%08lx)\n",__func__, sensor_port, procpars->functions);
i++;
......@@ -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);
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);
// 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__);
_processParsASAP(sensor_port, sensorproc, frame16); // NC393: never gets here ? Only after _processParsSeq?
if (debug_flags) {
MDP(DBGB_FPPI,sensor_port,"(after first _processParsASAP), frame16=%d, maxahead=%d\n",
frame16, maxahead)
......@@ -1075,18 +1124,40 @@ 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 numPars number of parameters to set
* @param pars array of parameters (number/value pairs)
* @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
{
struct framepars_t *framepars = aframepars[sensor_port];
int nframe;
index &= 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] = val;
}
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;
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;
......@@ -1095,10 +1166,12 @@ int setFrameParsStatic(int sensor_port, int numPars, struct frameparspair_t * pa
return 0;
}
/** 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
int setFrameParsAtomic(int sensor_port, ///< sensor port number (0..3)
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)
///< 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
......@@ -1113,6 +1186,12 @@ int setFrameParsAtomic(int sensor_port, ///< sensor port number (0
struct framepars_t *framepars = aframepars[sensor_port];
unsigned long *funcs2call =afuncs2call[sensor_port];
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_prev = (findex_this - 1) & PARS_FRAMES_MASK;
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
}
// 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
// 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)
debug_flags = 20; // enable debug print several times
if (!(get_globalParam(sensor_port, G_TASKLET_CTL) & (1 << TASKLET_CTL_NOSAME))) {
......@@ -1371,6 +1453,33 @@ int setFrameParLocked(int sensor_port, ///< sensor port numb
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.
* Schedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in the particular parameter index
* Called from tasklets (while executing (*_)pgm_* functions
......@@ -1383,7 +1492,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
///< @return 0 - OK, -ERR_FRAMEPARS_BADINDEX
{
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;
unsigned long val, bmask, bmask32;
int index, bindex;
......@@ -1400,7 +1509,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
frame16 = (this_framepars->pars[P_FRAME]) & PARS_FRAMES_MASK;
val = pars[npar].val;
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)
// remark: code below looks similar to setFramePar function, call it instead
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
val = FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, framepars[frame16].pars[index], val);
}
//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))) {
bmask = 1 << (index & 31);
bindex = index >> 5;
......@@ -1430,6 +1540,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0
if (pars[npar].num & FRAMEPAIR_FORCE_PROC) {
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)
if ((pars[npar].num & FRAMEPAIR_JUST_THIS) == 0) {
// MDF8(printk(": --- setting next frames"));
......@@ -1683,7 +1794,9 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff
int latency = -1;
int first = 0;
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;
// 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",
......@@ -1709,12 +1822,53 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff
}
while (first < count) {
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:
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;
#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:
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;
case FRAMEPARS_SETLATENCY:
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
}
last = first + 1;
while ((last < count) && ((pars[last].num & 0xff00) != 0xff00)) last++; // skip to the end or next special instructions
if (port_mask) {
int ii;
dev_dbg(g_devfp_ptr, "0x%x: port_mask=0x%x\n", (int) privData->minor, port_mask);
for (ii =0; ii < SENSOR_PORTS; ii++) if (port_mask & (1 << ii)){
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 (count > sizeof(pars_static)) kfree(pars);
return -EFAULT;
......@@ -1818,11 +1984,25 @@ static ssize_t store_this_frame(struct device *dev, struct device_attribute *att
resetFrameNumber(get_channel_from_name(attr),
aframe,
(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 {
return - EINVAL;
}
return count;
}
// 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)
......@@ -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_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(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(fpga_time, SYSFS_PERMISSIONS, show_fpga_time, store_fpga_time);
......@@ -1904,6 +2093,10 @@ static struct attribute *root_dev_attrs[] = {
&dev_attr_this_frame3.attr,
&dev_attr_all_frames.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
};
......
......@@ -6,17 +6,18 @@
//extern struct framepars_t (*framepars)[PARS_FRAMES];
extern struct framepars_t *aframepars[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 *amultiSensIndex[SENSOR_PORTS];
extern unsigned long *amultiSensRvrsIndex[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
void init_framepars_ptr(int sensor_port);
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)
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 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)
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);
//Next 2 called from ISR
void updateInterFrame(int sensor_port, u32 compressed_frame, struct interframe_params_t * interframe_pars);
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);
unsigned long getThisFrameNumber (int sensor_port); /// just return current thisFrameNumber
......
......@@ -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
/// 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_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_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, 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_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
// 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, 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_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?
......
......@@ -727,23 +727,6 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
// try MT9P001 first
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
sensio_ctl.mrst = 1;
sensio_ctl.mrst_set = 1;
......@@ -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);
sensor_subtype=MT9P_TYP; //1;
}
#endif
// 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));
if (sensor_subtype ==0) { // not a 5MPix chip
// CCAM_ARST_ON; // Why was it here
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);
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);
......@@ -811,7 +771,6 @@ int mt9x001_pgm_detectsensor (int sensor_port, ///< sensor port
} else {
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));
if (sensor_subtype ==0) return 0; // no sensor found
......@@ -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_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));
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
// MDD1(dev_dbg(g_dev_ptr,"\n"));
///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
///< @return 0 - OK, negative - error
{
// 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;
unsigned short * sensor_register_overwrites;
x393_sensio_ctl_t sensio_ctl = {.d32=0};
......@@ -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);
if (frame16 >= 0) return -1; // should be ASAP
// 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;
if (debug_delays & 0xff) {
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
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");
sensor_subtype=sensor->sensorType - SENSOR_MT9X001;
switch (sensor_subtype) {
......@@ -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.
// 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
//#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!
SET_SENSOR_MBPAR(sensor_port,
frame16,
frame16, // == -1 (immediate)
sensor->i2c_addr,
sensor_register_overwrites[2*i],\
sensor_register_overwrites[2*i],
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
SETFRAMEPARS_SET(P_PERIOD, pix_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){
trig_period = camsync_to_sensor(thispars->pars[P_TRIG_PERIOD], thispars->pars[P_CLK_SENSOR]);
if (trig_period > pix_period) pix_period=trig_period;
......@@ -1991,7 +1925,7 @@ int mt9x001_pgm_triggermode (int sensor_port, ///< sensor p
unsigned long newreg;
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
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] & 0x10)?0x80:0); // GRR mode for P_TRIG==20
if (newreg != thispars->pars[P_SENSOR_REGS+P_MT9X001_RMODE1]) {
......
......@@ -1002,7 +1002,7 @@ int multisensor_pgm_detectsensor (int sensor_port, ///< sensor p
int i;
int this_sensor_type;
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_set = 1;
X393_SEQ_SEND1 (sensor_port, frame16, x393_sens_mode, sens_mode);
......@@ -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))) {
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);
common_pars->sensors[sensor_port] = sensor->sensorType;
return -1;
}
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
if (GLOBALPARS(sensor_port,G_SENS_AVAIL)==0) {
dev_warn(g_dev_ptr,"No supported sensors connected to 10359A board\n");
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
return 0;
}
......
......@@ -239,14 +239,15 @@ const unsigned long param_depend_tab[]=
P_RFOCUS_TOP, ONCHANGE_FOCUSMODE ,
P_RFOCUS_HEIGHT, ONCHANGE_FOCUSMODE ,
P_FOCUS_FILTER, ONCHANGE_FOCUSMODE ,
P_TRIG_MASTER, ONCHANGE_TRIGSEQ ,
P_TRIG_CONDITION, ONCHANGE_TRIGSEQ ,
P_TRIG_DELAY, 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_I2C_QPERIOD, ONCHANGE_I2C ,
P_I2C_BYTES, ONCHANGE_I2C ,
P_IRQ_SMART, ONCHANGE_IRQ ,
P_I2C_EOF, ONCHANGE_IRQ ,
P_EXTERN_TIMESTAMP, ONCHANGE_TRIGSEQ ,
P_TRIG_BITLENGTH, ONCHANGE_TRIGSEQ ,
P_XMIT_TIMESTAMP, ONCHANGE_TRIGSEQ ,
......
......@@ -379,6 +379,7 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
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]) {
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)
......@@ -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)
// currently assign same sensor to all subchannles (first present)
// 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 (
i2c_drive_mode (sensor_port, SDA_DRIVE_HIGH, SDA_RELEASE);
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
#ifdef INIT_IN_TRIGGERED
camsync_mode.trig = 1; // start in stopped triggered mode
#else
camsync_mode.trig = 0;
#endif
camsync_mode.trig_set = 1;
// This causes mismatch with parameters, let it be there
// camsync_mode.ext = 1; // use external timestamp (default)
// camsync_mode.ext_set = 1;
x393_camsync_mode (camsync_mode);
// Set inactive state to all I/O) and period:
x393_camsync_trig_src(camsync_src);
x393_camsync_trig_dst(camsync_dst);
set_x393_camsync_trig_period(0);
// 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
......@@ -473,151 +473,14 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number (
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)
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)
// 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);
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)
* - resets sensor,
......@@ -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] !=1)) { // <256 - single trig, here only ==1 is for single
// 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
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)
......@@ -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);
MDP(DBGB_PSFN, sensor_port,"frame16=%d\n",frame16)
if (frame16 >= PARS_FRAMES) return -1; // wrong frame
#ifndef NC353
camsync_mode.trig = (thispars->pars[P_TRIG] & 4)?1:0;
if (camsync_mode.trig) { // if trigger mode, enable camsync module, if off - do nothing
camsync_mode.en = 1;
......@@ -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
x393_camsync_mode (camsync_mode);
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;
#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
struct frameparspair_t pars_to_update[10]; // ??? needed, increase if more entries will be added - just one
int nupdate=0;
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_dst = {.d32=0};
x393_gpio_set_pins_t gpio_set_pins = {.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);
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);
if (frame16 >= PARS_FRAMES) return -1; // wrong frame
if (frame16 >= 0) return -1; // ASAP only mode
// 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)
//+++++ if (frame16 >= 0) return -1; // ASAP only mode Was on
// See if master channel is set to this channel directly
is_master = (thispars->pars[P_TRIG_MASTER] == sensor_port)? 1 : 0;
if (is_master && FRAMEPAR_MODIFIED(P_TRIG_MASTER)) {
update_master_channel = 1;
camsync_mode.master_chn = sensor_port;
camsync_mode.master_chn_set = 1;
}
// Process per-channel (not common) parameters regardless of the master status (just trigger delay)
// Trigger delay changed?
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
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)
}
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)
if (FRAMEPAR_MODIFIED(P_TRIG_OUT)) {
camsync_dst.d32 = thispars->pars[P_TRIG_OUT];
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);
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) {
gpio_set_pins.chn_a = 3; // Set dibit enable
x393_gpio_set_pins(gpio_set_pins);
......@@ -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
} else {
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]);
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
if (FRAMEPAR_MODIFIED(P_EXTERN_TIMESTAMP)) {
camsync_mode.ext = thispars->pars[P_EXTERN_TIMESTAMP]?1:0;
camsync_mode.ext_set = 1;
update_master_channel=1;
// update_master_channel=1;
}
// P_XMIT_TIMESTAMP changed? (0 - internal sequencer)
if (FRAMEPAR_MODIFIED(P_XMIT_TIMESTAMP)) {
......@@ -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_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?
x393_camsync_mode (camsync_mode);
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)
}
// Does not seem to have any parameters to update?
if (nupdate) setFramePars(sensor_port, thispars, nupdate, pars_to_update); // save changes, schedule functions
return 0;
#else
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
if (frame16 >= PARS_FRAMES) return -1; // wrong frame
if (frame16 >= 0) return -1; // ASAP only mode
// Trigger condition changed? (0 - internal sequencer)
if (FRAMEPAR_MODIFIED(P_TRIG_CONDITION)) {
port_csp0_addr[X313_WA_CAMSYNCTRIG] = thispars->pars[P_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]);
}
// Trigger delay changed?
if (FRAMEPAR_MODIFIED(P_TRIG_DELAY)) {
port_csp0_addr[X313_WA_CAMSYNCDLY] = thispars->pars[P_TRIG_DELAY];
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]);
}
// Sequencer output word changed? (to which outputs it is sent and what polarity)
if (FRAMEPAR_MODIFIED(P_TRIG_OUT)) {
port_csp0_addr[X313_WA_CAMSYNCOUT] = 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]);
// Enable connection from the trigger module to the FPGA GPIO pins
if (thispars->pars[P_TRIG_OUT]!=0) {
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} writing bit length-1: port_csp0_addr[0x%x]=0x%x\n",sensor_port, (int) X313_WA_CAMSYNCPER, d);
}
// 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));
// now update common trigger parameters and mark dependent channels to update, if anything changed;
if ((thispars->pars[P_TRIG_MASTER] != common_pars->master_chn) ||
(thispars->pars[P_TRIG_PERIOD] != common_pars->trig_period) ||
(thispars->pars[P_TRIG_BITLENGTH] != common_pars->trig_bitlength) ||
(thispars->pars[P_EXTERN_TIMESTAMP] != common_pars->extern_timestamp) ||
(thispars->pars[P_XMIT_TIMESTAMP] != common_pars->xmit_timestamp) ||
(thispars->pars[P_TRIG_CONDITION] != common_pars->trig_condition) ||
(thispars->pars[P_TRIG_OUT] != common_pars->trig_out)){
int i; //, f;
dev_dbg(g_dev_ptr,"{%d} Updating common trigger parameters\n",sensor_port);
common_pars->master_chn = thispars->pars[P_TRIG_MASTER];
common_pars->trig_period = thispars->pars[P_TRIG_PERIOD];
common_pars->trig_bitlength = thispars->pars[P_TRIG_BITLENGTH];
common_pars->extern_timestamp = thispars->pars[P_EXTERN_TIMESTAMP];
common_pars->xmit_timestamp = thispars->pars[P_XMIT_TIMESTAMP];
common_pars->trig_condition = thispars->pars[P_TRIG_CONDITION];
common_pars->trig_out = thispars->pars[P_TRIG_OUT];
// f = (frame16<0)? -1:(frame16 + 1);
for (i=0; i<SENSOR_PORTS; i++) if (i != sensor_port) {
common_pars->updated[i] = 1; //f;
}
dev_dbg(g_dev_ptr,"{%d} common_pars->updated= {%ld, %ld, %ld, %ld}\n",sensor_port,
common_pars->updated[0],common_pars->updated[1],common_pars->updated[2],common_pars->updated[3]);
}
if (nupdate) setFramePars(sensor_port, thispars, nupdate, pars_to_update); // save changes, schedule functions
return 0;
#endif
}
/** 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)
///< be applied to, negative - ASAP
///< @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);
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
#ifdef NC353
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)
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)));
#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
/*
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)) | \
(8 | ((thispars->pars[P_IRQ_SMART] & 2)?4:0)))));
*/
......
......@@ -36,6 +36,7 @@
#define USELONGLONG 1
#define ETRAXFS_MMAP_CACHE_BUG y
//#define INIT_IN_TRIGGERED // Init sensors in triggered mode, stopped
#if ELPHEL_DEBUG
#define EDBG(x) x
......@@ -279,6 +280,7 @@
#define SENSORWIDTH_IBIS51300 1280 ///< FillFactory IBIS51300 width
#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 SENSOR_RUN_STOP 0 ///< Sensor acquisition mode: STOP
#define SENSOR_RUN_SINGLE 1 ///< Sensor acquisition mode: SINGLE FRAME
......@@ -449,8 +451,9 @@
#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_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)
#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_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
......@@ -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
struct framepars_all_t {
struct framepars_all_t
{
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
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 {
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
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
......@@ -1073,6 +1103,7 @@ struct p_names_t {
#define DEFINE_P_NAMES(x) struct p_names_t x[]= { \
P_NAME_ENTRY(NUMBER), \
P_NAME_ENTRY(SENSOR), \
P_NAME_ENTRY(TRIG_MASTER), \
P_NAME_ENTRY(SENSOR_RUN), \
P_NAME_ENTRY(SENSOR_SINGLE), \
P_NAME_ENTRY(ACTUAL_WIDTH), \
......@@ -1189,7 +1220,7 @@ struct p_names_t {
P_NAME_ENTRY(SKIP_FRAMES), \
P_NAME_ENTRY(I2C_QPERIOD), \
P_NAME_ENTRY(I2C_BYTES), \
P_NAME_ENTRY(IRQ_SMART), \
P_NAME_ENTRY(I2C_EOF), \
P_NAME_ENTRY(EXTERN_TIMESTAMP), \
P_NAME_ENTRY(OVERSIZE), \
P_NAME_ENTRY(XMIT_TIMESTAMP), \
......@@ -1485,7 +1516,7 @@ struct p_names_t {
#define LSEEK_AUTOEXP_GET 0x1a ///< copy window and exposure parameters to autoexp_state
#define LSEEK_TRIGGER_PGM 0x1b ///< program trigger parameters
#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_DMA_INIT 0x1f ///< (re-) initialize ETRAX DMA for compressor
#define LSEEK_DMA_STOP 0x20 ///< STOP ETRAX DMA
......@@ -1572,7 +1603,7 @@ struct p_names_t {
LSEEK_NAME_ENTRY(AUTOEXP_GET), \
LSEEK_NAME_ENTRY(TRIGGER_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(DMA_INIT), \
LSEEK_NAME_ENTRY(DMA_STOP), \
......@@ -1956,8 +1987,19 @@ struct huffman_encoded_t {
};
/// 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 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_SINGLE), \
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