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

implemented multiple ports setting using driver write method

parent e7e0c7be
Loading
Loading
Loading
Loading
+138 −13
Original line number Original line Diff line number Diff line
@@ -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)
    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
    //    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
//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
	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
	}
	}
// 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
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)
        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
                                                      ///< @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
	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
			}
			}
			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:
						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:
                    case FRAMEPARS_SETFRAME:
                        frame = pars[first].val;
                        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;
                        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
				}
				}
				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
                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",
                    dev_dbg(g_devfp_ptr, "0x%x: setFrameParsAtomic(%ld, %d, %d)\n",
                            (int) privData->minor, frame, latency, last - first);
                            (int) privData->minor, frame, latency, last - first);
                    MDP(DBGB_FFOP, sensor_port, "0x%x: setFrameParsAtomic(%ld, %d, %d)\n",
                    MDP(DBGB_FFOP, sensor_port, "0x%x: setFrameParsAtomic(%ld, %d, %d)\n",
                            (int) privData->minor, frame, latency, last - first)
                            (int) privData->minor, frame, latency, last - first)
                    result = setFrameParsAtomic(sensor_port,frame, latency, last - first, &pars[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
        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
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[] = {
        &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
};
};


+1 −0
Original line number Original line Diff line number Diff line
@@ -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);
+1 −1
Original line number Original line Diff line number Diff line
@@ -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);
+14 −68
Original line number Original line Diff line number Diff line
@@ -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
    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
    // 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
    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
                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)
+16 −0
Original line number Original line Diff line number Diff line
@@ -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 {
};
};


/// 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), \