Commit 7e2ae73e authored by Andrey Filippov's avatar Andrey Filippov

implemented multiple ports setting using driver write method

parent e7e0c7be
...@@ -199,8 +199,15 @@ static struct common_pars_t scommon_pars = { ...@@ -199,8 +199,15 @@ static struct common_pars_t scommon_pars = {
.extern_timestamp = 0, .extern_timestamp = 0,
.xmit_timestamp = 0, .xmit_timestamp = 0,
.trig_condition = 0, .trig_condition = 0,
.trig_out = 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; 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;
...@@ -300,6 +307,31 @@ int initSequencers(int sensor_port) ...@@ -300,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)
...@@ -955,7 +987,9 @@ void _processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16 ...@@ -955,7 +987,9 @@ void _processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame16
// 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)
...@@ -1137,6 +1171,7 @@ int setFrameParsStatic(int sensor_port, ///< sensor_port sensor po ...@@ -1137,6 +1171,7 @@ int setFrameParsStatic(int sensor_port, ///< sensor_port sensor po
//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
...@@ -1151,6 +1186,12 @@ int setFrameParsAtomic(int sensor_port, ///< sensor port number (0 ...@@ -1151,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??
...@@ -1266,6 +1307,9 @@ int setFrameParsAtomic(int sensor_port, ///< sensor port number (0 ...@@ -1266,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))) {
...@@ -1412,15 +1456,13 @@ int setFrameParLocked(int sensor_port, ///< sensor port numb ...@@ -1412,15 +1456,13 @@ int setFrameParLocked(int sensor_port, ///< sensor port numb
void trigSlaveUpdate(int sensor_port) ///< sensor port number (0..3) void trigSlaveUpdate(int sensor_port) ///< sensor port number (0..3)
{ {
struct framepars_t *framepars = aframepars[sensor_port]; struct framepars_t *framepars = aframepars[sensor_port];
struct frameparspair_t pars_to_update[7]; struct frameparspair_t pars_to_update[8];
int nupdate = 0; int nupdate = 0;
int updated_period = 0; int updated_period = 0;
while (common_pars->updated[sensor_port]) { while (common_pars->updated[sensor_port]) {
// int frame16 = (common_pars->updated[sensor_port] < 0)?-1:(common_pars->updated[sensor_port]-1); // 1 was added ta enable frame16=0
// dev_dbg(g_devfp_ptr,"port= %d, frame16=%d, thisFrameNumber[%d] = %d\n", sensor_port, frame16, sensor_port, (int) thisFrameNumber(sensor_port));
dev_dbg(g_devfp_ptr,"port= %d, thisFrameNumber[%d] = %d\n", sensor_port, sensor_port, (int) thisFrameNumber(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; common_pars->updated[sensor_port] = 0;
if (pars_to_update[nupdate ].num != P_TRIG_PERIOD){ if (pars_to_update[nupdate ].num != P_TRIG_PERIOD){ //???
updated_period = FRAMEPAIR_FORCE_PROC; 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_MASTER ; pars_to_update[nupdate++].val = common_pars->master_chn;
...@@ -1430,6 +1472,7 @@ void trigSlaveUpdate(int sensor_port) ///< sensor port number (0..3) ...@@ -1430,6 +1472,7 @@ void trigSlaveUpdate(int sensor_port) ///< sensor port number (0..3)
pars_to_update[nupdate ].num= P_XMIT_TIMESTAMP ; pars_to_update[nupdate++].val = common_pars->xmit_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_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_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[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 if (nupdate) setFramePars(sensor_port, &framepars[thisFrameNumber(sensor_port)], nupdate, pars_to_update); // save changes, schedule functions
...@@ -1449,7 +1492,7 @@ int setFramePars(int sensor_port, ///< sensor port number (0 ...@@ -1449,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;
...@@ -1751,7 +1794,9 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1751,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",
...@@ -1777,12 +1822,53 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1777,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;
...@@ -1810,11 +1896,23 @@ ssize_t framepars_write(struct file * file, const char * buf, size_t count, loff ...@@ -1810,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;
...@@ -1886,11 +1984,25 @@ static ssize_t store_this_frame(struct device *dev, struct device_attribute *att ...@@ -1886,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)
...@@ -1962,6 +2074,15 @@ static DEVICE_ATTR(this_frame0, SYSFS_PERMISSIONS, show_this_f ...@@ -1962,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);
...@@ -1972,6 +2093,10 @@ static struct attribute *root_dev_attrs[] = { ...@@ -1972,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
}; };
......
...@@ -17,6 +17,7 @@ int initSequencers (int sensor_port); ///Move to sensorcommon? currently it ...@@ -17,6 +17,7 @@ int initSequencers (int sensor_port); ///Move to sensorcommon? currently it
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);
......
...@@ -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);
......
...@@ -1260,6 +1260,10 @@ int pgm_limitfps (int sensor_port, ///< sensor port number (0..3 ...@@ -1260,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)
...@@ -1306,7 +1310,6 @@ int pgm_triggermode(int sensor_port, ///< sensor port number (0..3 ...@@ -1306,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;
...@@ -1320,13 +1323,17 @@ int pgm_triggermode(int sensor_port, ///< sensor port number (0..3 ...@@ -1320,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
} }
...@@ -2432,7 +2439,6 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3 ...@@ -2432,7 +2439,6 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3
int d; int d;
int is_master = 0; int is_master = 0;
int update_master_channel = 0; // set if any of the common (not channel-specific) parameters is modified int update_master_channel = 0; // set if any of the common (not channel-specific) parameters is modified
#ifndef NC353
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};
...@@ -2561,66 +2567,6 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3 ...@@ -2561,66 +2567,6 @@ int pgm_trigseq (int sensor_port, ///< sensor port number (0..3
common_pars->updated[0],common_pars->updated[1],common_pars->updated[2],common_pars->updated[3]); common_pars->updated[0],common_pars->updated[1],common_pars->updated[2],common_pars->updated[3]);
} }
return 0; 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));
}
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) /** Program smart IRQ mode (needs to be on, at least bit 0)
......
...@@ -1012,8 +1012,13 @@ struct common_pars_t{ ...@@ -1012,8 +1012,13 @@ struct common_pars_t{
unsigned long xmit_timestamp; ///< Transmit timestamp with sync pulse 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_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_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_PERIOD 500 0x1f4
* TRIG_BITLENGTH 31 0x1f * TRIG_BITLENGTH 31 0x1f
* EXTERN_TIMESTAMP 1 0x1 * EXTERN_TIMESTAMP 1 0x1
...@@ -1982,8 +1987,19 @@ struct huffman_encoded_t { ...@@ -1982,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