Commit e7e0c7be authored by Andrey Filippov's avatar Andrey Filippov

re-organized trigger behavior

parent a8a661b1
......@@ -190,7 +190,18 @@ 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
};
struct common_pars_t *common_pars = NULL;
/* Remove after compilation OK */
//struct sensorproc_t * sensorproc = NULL;
//void compressor_interrupts (int on) {}
......@@ -244,7 +255,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 +263,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 +281,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);
......@@ -937,6 +950,8 @@ 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__);
......@@ -1075,26 +1090,49 @@ 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
{
int npar, nframe, index;
struct framepars_t *framepars = aframepars[sensor_port];
for (npar = 0; npar < numPars; npar++) {
index = pars[npar].num;
if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX;
for (nframe = 0; nframe < PARS_FRAMES; nframe++) {
framepars[nframe].pars[index] = pars[npar].val;
}
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 & 0xffff; // get rid of any modifier (not applicable here)
if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX;
for (nframe = 0; nframe < PARS_FRAMES; nframe++) {
framepars[nframe].pars[index] = pars[npar].val;
}
}
return 0;
}
/** Set parameters for the specified frame (atomic, with interrupts off). Used from applications through driver write */
//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)
......@@ -1371,6 +1409,34 @@ 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[7];
int nupdate = 0;
int updated_period = 0;
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));
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;
// 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
......@@ -1400,7 +1466,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 +1485,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 +1497,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"));
......
......@@ -6,11 +6,11 @@
//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)
......@@ -35,6 +35,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]) {
......
......@@ -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,
......@@ -2567,43 +2430,54 @@ 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;
int is_master = 0;
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_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 +2509,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 +2518,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,16 +2528,38 @@ 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
// 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]);
}
return 0;
#else
dev_dbg(g_dev_ptr,"{%d} frame16=%d\n",sensor_port,frame16);
......@@ -2738,8 +2634,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 +2647,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,27 @@ 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)
};
/*
* 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 +1098,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 +1215,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 +1511,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 +1598,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), \
......
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