Commit 39680a19 authored by Andrey Filippov's avatar Andrey Filippov

working on framepars

parent 403a0e08
...@@ -68,20 +68,21 @@ ...@@ -68,20 +68,21 @@
*/ */
#if ELPHEL_DEBUG #if ELPHEL_DEBUG
/* 393: program G_DEBUG through sensor port 0 */
#define MDF(x) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } #define MDF(x) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; }
#define MDF2(x) { if (GLOBALPARS(G_DEBUG) & (1 << 2)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } } #define MDF2(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 2)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } }
/// setFrameParsAtomic /// setFrameParsAtomic
#define MDF5(x) { if (GLOBALPARS(G_DEBUG) & (1 << 5)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } } #define MDF5(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 5)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } }
#define D5(x) { if (GLOBALPARS(G_DEBUG) & (1 << 5)) { x; } } #define D5(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 5)) { x; } }
/// processPars /// processPars
#define MDF6(x) { if (GLOBALPARS(G_DEBUG) & (1 << 6)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } } #define MDF6(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 6)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } }
#define D6(x) { if (GLOBALPARS(G_DEBUG) & (1 << 6)) { x; } } #define D6(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 6)) { x; } }
///update FramePars ///update FramePars
#define MDF7(x) { if (GLOBALPARS(G_DEBUG) & (1 << 7)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } } #define MDF7(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 7)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } }
#define D7(x) { if (GLOBALPARS(G_DEBUG) & (1 << 7)) { x; } } #define D7(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 7)) { x; } }
/// setFramePar[s] /// setFramePar[s]
#define MDF8(x) { if (GLOBALPARS(G_DEBUG) & (1 << 8)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } } #define MDF8(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 8)) { printk("%s:%d:%s ", __FILE__, __LINE__, __FUNCTION__); x; } }
#define D8(x) { if (GLOBALPARS(G_DEBUG) & (1 << 8)) { x; } } #define D8(x) { if (GLOBALPARS(0,G_DEBUG) & (1 << 8)) { x; } }
#define ELPHEL_DEBUG_THIS 0 #define ELPHEL_DEBUG_THIS 0
// #define ELPHEL_DEBUG_THIS 1 // #define ELPHEL_DEBUG_THIS 1
#else #else
...@@ -117,19 +118,31 @@ ...@@ -117,19 +118,31 @@
*/ */
#define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver" #define FRAMEPARS_DRIVER_NAME "Elphel (R) Model 393 Frame Parameters device driver"
static struct framepars_all_t sFrameParsAll __attribute__ ((aligned(PAGE_SIZE))); ///< Sensor Parameters, currently 8 pages all and 2048 pages some, static struct /* 393: sFrameParsAll is an array of 4per-port structures */
static struct framepars_all_t sFrameParsAll[SENSOR_PORTS] __attribute__ ((aligned(PAGE_SIZE))); ///< Sensor Parameters, currently 16 pages all and 2048 pages some, static struct
unsigned long frameParsInitialized; /// set to 0 at startup, 1 after initialization that is triggered by setParsAtomic() unsigned long frameParsInitialized; /// set to 0 at startup, 1 after initialization that is triggered by setParsAtomic()
#define thisFrameNumber GLOBALPARS(G_THIS_FRAME) // Current frame number (may lag from the hardware) #define thisFrameNumber(p) GLOBALPARS(p,G_THIS_FRAME) // Current frame number (may lag from the hardware)
//#define THISFRAMENUMBER GLOBALPARS(G_THIS_FRAME) // Current frame number (may lag from the hardware)
#ifdef NC353
struct framepars_all_t *frameparsall = NULL; /// - will be mmap-ed struct framepars_all_t *frameparsall = NULL; /// - will be mmap-ed
struct framepars_t *framepars = NULL; ///< getting rid of static to be able to use extern struct framepars_t *framepars = NULL; ///< getting rid of static to be able to use extern
struct framepars_past_t *pastpars = NULL; ///< getting rid of static to be able to use extern struct framepars_past_t *pastpars = NULL; ///< getting rid of static to be able to use extern
unsigned long *funcs2call = NULL; /// sFrameParsAll.func2call.pars; - each parameter has a 32-bit mask of what pgm_function to call - other fields not used unsigned long *funcs2call = NULL; /// sFrameParsAll.func2call.pars; - each parameter has a 32-bit mask of what pgm_function to call - other fields not used
unsigned long *globalPars = NULL; /// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both unsigned long *globalPars = NULL; /// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both
unsigned long *multiSensIndex = NULL; /// index for per-sensor alternatives unsigned long *multiSensIndex = NULL; /// index for per-sensor alternatives
unsigned long *multiSensRvrsIndex = NULL; /// reverse index (to parent) for the multiSensIndex unsigned long *multiSensRvrsIndex = NULL; /// reverse index (to parent) for the multiSensIndex
wait_queue_head_t framepars_wait_queue; /// used to wait for the frame to be acquired wait_queue_head_t framepars_wait_queue; /// used to wait for the frame to be acquired
#endif
/* 393 : Changing to per-port */
struct framepars_all_t *aframeparsall = NULL; /// - will be mmap-ed, in 393 points to an array of structures
struct framepars_t *aframepars[SENSOR_PORTS]; ///< getting rid of static to be able to use extern
struct framepars_past_t *apastpars[SENSOR_PORTS]; ///< getting rid of static to be able to use extern
unsigned long *afuncs2call[SENSOR_PORTS]; /// sFrameParsAll.func2call.pars; - each parameter has a 32-bit mask of what pgm_function to call - other fields not used
unsigned long *aglobalPars[SENSOR_PORTS]; /// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both
unsigned long *amultiSensIndex[SENSOR_PORTS]; /// index for per-sensor alternatives
unsigned long *amultiSensRvrsIndex[SENSOR_PORTS]; /// reverse index (to parent) for the multiSensIndex
wait_queue_head_t aframepars_wait_queue[SENSOR_PORTS];/// used to wait for the frame to be acquired
wait_queue_head_t framepars_wait_queue; /// used to wait for the frame to be acquired
/** /**
* @brief file private data * @brief file private data
...@@ -145,15 +158,16 @@ struct framepars_pd { ...@@ -145,15 +158,16 @@ struct framepars_pd {
/** /**
* @brief assign non-static pointers to static data to be used as extern * @brief assign non-static pointers to static data to be used as extern
*/ */
void init_framepars_ptr(void) void init_framepars_ptr(int sensor_port)
{ {
frameparsall = &sFrameParsAll; /// - will be mmap-ed // frameparsall = &sFrameParsAll; /// - will be mmap-ed
framepars = sFrameParsAll.framePars; aframeparsall = sFrameParsAll; /// - will be mmap-ed
pastpars = sFrameParsAll.pastPars; aframepars[sensor_port] = sFrameParsAll[sensor_port].framePars;
funcs2call = sFrameParsAll.func2call.pars; /// each parameter has a 32-bit mask of what pgm_function to call - other fields not used apastpars[sensor_port] = sFrameParsAll[sensor_port].pastPars;
globalPars = sFrameParsAll.globalPars; /// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both afuncs2call[sensor_port] = sFrameParsAll[sensor_port].func2call.pars; /// each parameter has a 32-bit mask of what pgm_function to call - other fields not used
multiSensIndex = sFrameParsAll.multiSensIndex; /// indexes of individual sensor register shadows (first of 3) - now for all parameters, not just sensor ones 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
multiSensRvrsIndex = sFrameParsAll.multiSensRvrsIndex; /// reverse index (to parent) for the multiSensIndex 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
} }
...@@ -166,7 +180,7 @@ int framepars_mmap(struct file *file, struct vm_area_struct *vma); ...@@ -166,7 +180,7 @@ int framepars_mmap(struct file *file, struct vm_area_struct *vma);
/** /**
* @brief Reset hardware sequencers (i2c, command) and initialize framepars structure * @brief Reset hardware sequencers (i2c, command) and initialize framepars structure
*/ */
void initSequencers(void) void initSequencers(int sensor_port)
{ {
unsigned long flags; unsigned long flags;
...@@ -183,37 +197,61 @@ void initSequencers(void) ...@@ -183,37 +197,61 @@ void initSequencers(void)
/** /**
* @brief reset absolute frame number \b thisFrameNumber to \b frame8 * @brief reset absolute frame number \b thisFrameNumber to \b frame8
* @param sensor_port sensor port number (0..3)
*/ */
void resetFrameNumber(void) void resetFrameNumber(int sensor_port)
{ {
int i; int i;
// Setup update mode for
#ifdef TEST_DISABLE_CODE x393_cmdseqmux_status_t stat;
thisFrameNumber = X3X3_I2C_FRAME; x393_status_ctrl_t stat_ctrl;
/* Check if the status update mode for command sequencer is not 3 (auto), set/wait if needed */
stat_ctrl = get_x393_cmdseqmux_status_ctrl();
if (stat_ctrl.mode !=3) {
stat = x393_cmdseqmux_status();
stat_ctrl.seq_num = stat.seq_num + 1;
stat_ctrl.mode = 3;
set_x393_cmdseqmux_status_ctrl(stat_ctrl);
for (i = 0; i < 10; i++) {
stat = x393_cmdseqmux_status();
if (likely(stat.seq_num == stat_ctrl.seq_num))
break;
}
} else {
stat = x393_cmdseqmux_status();
}
switch (sensor_port) {
case 0: thisFrameNumber(sensor_port) = stat.frame_num0; break;
case 1: thisFrameNumber(sensor_port) = stat.frame_num1; break;
case 2: thisFrameNumber(sensor_port) = stat.frame_num2; break;
case 3: thisFrameNumber(sensor_port) = stat.frame_num3; break;
}
#ifdef NC353
thisFrameNumber(sensor_port) = X3X3_I2C_FRAME;
#endif #endif
MDF2(printk(" thisFrameNumber=0x%lx\n", thisFrameNumber)); MDF2(printk(" thisFrameNumber=0x%lx\n", thisFrameNumber(sensor_port)));
// write absolute frame numbers // write absolute frame numbers
for (i = thisFrameNumber; i < (thisFrameNumber + PARS_FRAMES); i++) framepars[i & PARS_FRAMES_MASK].pars[P_FRAME] = i; for (i = thisFrameNumber(sensor_port); i < (thisFrameNumber(sensor_port) + PARS_FRAMES); i++) aframepars[sensor_port][i & PARS_FRAMES_MASK].pars[P_FRAME] = i;
/// initialize frameParsDeps.pars masks:
} }
/** /**
* @brief initialize all parameters, set \b thisFrameNumber to \b frame number read from hardware hardware ( 0 after resetting i2c and cmd_seq) * @brief initialize all parameters, set \b thisFrameNumber to \b frame number read from hardware hardware ( 0 after resetting i2c and cmd_seq)
* @param sensor_port sensor port number (0..3)
*/ */
void initFramePars(void) void initFramePars(int sensor_port)
{ {
int i; int i;
memset(framepars, 0, sizeof(framepars)); memset(aframepars[sensor_port], 0, sizeof(struct framepars_t) * PARS_FRAMES);
resetFrameNumber(); resetFrameNumber(sensor_port);
/// initialize frameParsDeps.pars masks: /// initialize frameParsDeps.pars masks:
for (i = 0; i < (sizeof(param_depend_tab) / 8); i++) { for (i = 0; i < (sizeof(param_depend_tab) / 8); i++) {
funcs2call[param_depend_tab[2 * i] & 0xffff] = param_depend_tab[2 * i + 1]; /// remove possible flags afuncs2call[sensor_port][param_depend_tab[2 * i] & 0xffff] = param_depend_tab[2 * i + 1]; /// remove possible flags
MDF2(printk("funcs2call[0x%lx]=0x%08lx\n", param_depend_tab[2 * i] & 0xffff, param_depend_tab[2 * i + 1])); MDF2(printk("funcs2call[0x%lx]=0x%08lx\n", param_depend_tab[2 * i] & 0xffff, param_depend_tab[2 * i + 1]));
} }
for (i = 0; i < P_SENSOR_NUMREGS; i++) funcs2call[P_SENSOR_REGS + i] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function for (i = 0; i < P_SENSOR_NUMREGS; i++) afuncs2call[sensor_port][P_SENSOR_REGS + i] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
/// Same for 10359 registers - will not change anything if there is no 10359 - these registers will not be chnaged, and if will be it wil cause no action /// Same for 10359 registers - will not change anything if there is no 10359 - these registers will not be changed, and if will be it wil cause no action
for (i = 0; i < P_M10359_NUMREGS; i++) funcs2call[P_M10359_REGS + i] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function for (i = 0; i < P_M10359_NUMREGS; i++) afuncs2call[sensor_port][P_M10359_REGS + i] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
initMultiPars(); /// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection initMultiPars(); /// initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection
frameParsInitialized = 1; frameParsInitialized = 1;
...@@ -221,111 +259,120 @@ void initFramePars(void) ...@@ -221,111 +259,120 @@ void initFramePars(void)
/** /**
* @brief reset all global parameters, set default for debug mask (if ELPHEL_DEBUG) * @brief reset all global parameters, set default for debug mask (if ELPHEL_DEBUG)
* @param sensor_port sensor port number (0..3)
*/ */
void initGlobalPars(void) void initGlobalPars(int sensor_port)
{ {
memset(&globalPars[GLOBALS_PRESERVE], 0, sizeof(globalPars) - GLOBALS_PRESERVE * sizeof(globalPars[0])); memset(&aglobalPars[sensor_port][GLOBALS_PRESERVE], 0, (NUM_GPAR - GLOBALS_PRESERVE) * sizeof(unsigned long));
/// MDF(GLOBALPARS(G_DEBUG) = ELPHEL_DEBUG_STARTUP;// removed - add write to fpga init script /// MDF(GLOBALPARS(G_DEBUG) = ELPHEL_DEBUG_STARTUP;// removed - add write to fpga init script
MDF(printk("GLOBALPARS(G_DEBUG)=%lx\n", GLOBALPARS(G_DEBUG))); MDF(printk("GLOBALPARS(0,G_DEBUG)=%lx\n", GLOBALPARS(0,G_DEBUG)));
} }
/** /**
* @brief initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection * @brief initialize structures for individual per-sensor parameters. Now only works for sensor registers using G_MULTI_REGSM. Should be called after/during sensor detection
* @param sensor_port sensor port number (0..3)
* @return number of multi-regs * @return number of multi-regs
*/ */
int initMultiPars(void) int initMultiPars(int sensor_port)
{ {
int i, j, n; int i, j, n;
int ireg = P_MULTI_REGS; /// multi-reg shadows start index int ireg = P_MULTI_REGS; /// multi-reg shadows start index
unsigned long m; unsigned long m;
memset(multiSensIndex, 0, sizeof(multiSensIndex)); // memset(amultiSensIndex[sensor_port], 0, sizeof(struct framepars_all_t.multiSensIndex));
memset(multiSensRvrsIndex, 0, sizeof(multiSensRvrsIndex)); memset(amultiSensIndex[sensor_port], 0, P_MAX_PAR_ROUNDUP * sizeof(int));
GLOBALPARS(G_MULTI_NUM) = 0; // memset(multiSensRvrsIndex, 0, sizeof(multiSensRvrsIndex));
memset(amultiSensRvrsIndex[sensor_port], 0, P_MAX_PAR_ROUNDUP * sizeof(int));
GLOBALPARS(sensor_port,G_MULTI_NUM) = 0;
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
m = GLOBALPARS(G_MULTI_REGSM + i); /// 1 bit per register that need individual shadows m = GLOBALPARS(sensor_port, G_MULTI_REGSM + i); /// 1 bit per register that need individual shadows
// MDF(printk("i=%d, m=0x%lx\n",i,m)); // MDF(printk("i=%d, m=0x%lx\n",i,m));
for (j = P_SENSOR_REGS + (i << 5); m && (GLOBALPARS(G_MULTI_NUM) < P_MULTI_NUMREGS); j++, m >>= 1) { for (j = P_SENSOR_REGS + (i << 5); m && (GLOBALPARS(sensor_port,G_MULTI_NUM) < P_MULTI_NUMREGS); j++, m >>= 1) {
if (m & 1) { if (m & 1) {
multiSensIndex[j] = ireg; amultiSensIndex[j] = ireg;
// MDF(printk("j=0x%x ireg=0x%x\n",j,ireg)); // MDF(printk("j=0x%x ireg=0x%x\n",j,ireg));
for (n = 0; n < MAX_SENSORS; n++) { for (n = 0; n < MAX_SENSORS; n++) {
funcs2call[ireg] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of these registers will trigger pgm_sensorreg function afuncs2call[sensor_port][ireg] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of these registers will trigger pgm_sensorreg function
multiSensRvrsIndex[ireg++] = j | ((n + 1) << 16); amultiSensRvrsIndex[sensor_port][ireg++] = j | ((n + 1) << 16);
} }
GLOBALPARS(G_MULTI_NUM)++; GLOBALPARS(sensor_port,G_MULTI_NUM)++;
} }
} }
} }
// remark: the line below is called from initFramePars, consider removing it // remark: the line below is called from initFramePars, consider removing it
for (i = 0; i < P_SENSOR_NUMREGS; i++) funcs2call[P_SENSOR_REGS + i] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function for (i = 0; i < P_SENSOR_NUMREGS; i++) afuncs2call[sensor_port][P_SENSOR_REGS + i] = ONCHANGE_SENSORREGS; /// by default each "manual" write to any of 256 registers will trigger pgm_sensorreg function
MDF(printk("GLOBALPARS(G_MULTI_NUM)=%lx\n", GLOBALPARS(G_MULTI_NUM))); MDF(printk("GLOBALPARS(G_MULTI_NUM)=%lx\n", GLOBALPARS(sensor_port, G_MULTI_NUM)));
return GLOBALPARS(G_MULTI_NUM); return GLOBALPARS(sensor_port, G_MULTI_NUM);
} }
/** /**
* @brief reads parameters from the current frame (matching hardware index) * @brief reads parameters from the current frame (matching hardware index)
* @param sensor_port sensor port number (0..3)
* @param n number of a parameter to read * @param n number of a parameter to read
* @return parameter value (unsigned long) * @return parameter value (unsigned long)
*/ */
inline unsigned long get_imageParamsThis(int n) inline unsigned long get_imageParamsThis(int sensor_port, int n)
{ {
return framepars[thisFrameNumber & PARS_FRAMES_MASK].pars[n]; return aframepars[sensor_port][thisFrameNumber(sensor_port) & PARS_FRAMES_MASK].pars[n];
} }
/** /**
* @brief reads parameters from the previous frame (matching hardware index) - used to determine if historam was needed * @brief reads parameters from the previous frame (matching hardware index) - used to determine if historam was needed
* @param sensor_port sensor port number (0..3)
* @param n number of a parameter to read * @param n number of a parameter to read
* @return parameter value (unsigned long) * @return parameter value (unsigned long)
*/ */
inline unsigned long get_imageParamsPrev(int n) inline unsigned long get_imageParamsPrev(int sensor_port, int n)
{ {
return framepars[(thisFrameNumber - 1) & PARS_FRAMES_MASK].pars[n]; return aframepars[sensor_port][(thisFrameNumber(sensor_port) - 1) & PARS_FRAMES_MASK].pars[n];
} }
/** /**
* @brief writes read-only parameter to the current frame (does not propagate to next frames as setFramePar() does) * @brief writes read-only parameter to the current frame (does not propagate to next frames as setFramePar() does)
* In most cases you really need to use setFramePar() instead; * In most cases you really need to use setFramePar() instead;
* @param sensor_port sensor port number (0..3)
* @param n number of a parameter to set * @param n number of a parameter to set
* @param d data to write to the selected parameter * @param d data to write to the selected parameter
*/ */
inline void set_imageParamsThis(int n, unsigned long d) inline void set_imageParamsThis(int sensor_port, int sensor_port, int n, unsigned long d)
{ {
framepars[thisFrameNumber & PARS_FRAMES_MASK].pars[n] = d; aframepars[sensor_port][thisFrameNumber(sensor_port) & PARS_FRAMES_MASK].pars[n] = d;
} }
/** /**
* @brief reads global (not related to particular frames) parameters * @brief reads global (not related to particular frames) parameters
* @param sensor_port sensor port number (0..3)
* @param n number of a parameter to read (numbers start from FRAMEPAR_GLOBALS) * @param n number of a parameter to read (numbers start from FRAMEPAR_GLOBALS)
* @return parameter value (unsigned long) * @return parameter value (unsigned long)
*/ */
inline unsigned long get_globalParam(int n) inline unsigned long get_globalParam(int sensor_port, int n)
{ {
return GLOBALPARS(n); return GLOBALPARS(sensor_port, n);
} }
/** /**
* @brief sets global (not related to particular frames) parameters * @brief sets global (not related to particular frames) parameters
* @param sensor_port sensor port number (0..3)
* @param n number of a parameter to set (numbers start from FRAMEPAR_GLOBALS) * @param n number of a parameter to set (numbers start from FRAMEPAR_GLOBALS)
* @param d data to write to the selected parameter * @param d data to write to the selected parameter
*/ */
inline void set_globalParam(int n, unsigned long d) inline void set_globalParam(int sensor_port, int n, unsigned long d)
{ {
GLOBALPARS(n) = d; GLOBALPARS(sensor_port, n) = d;
} }
/** /**
* @brief set same parameters in all frames * @brief set same parameters in all frames
* currently used only in compressor reset * currently used only in compressor reset
* @param sensor_port sensor port number (0..3)
* @param n number of a parameter to set * @param n number of a parameter to set
* @param d data to write to the selected parameter * @param d data to write to the selected parameter
*/ */
inline void set_imageParamsR_all(int n, unsigned long d) inline void set_imageParamsR_all(int sensor_port, int n, unsigned long d)
{ {
int i; int i;
for (i = 0; i < PARS_FRAMES; i++) aframepars[sensor_port][i].pars[n] = d;
for (i = 0; i < PARS_FRAMES; i++) framepars[i].pars[n] = d;
} }
///++++++++++++++++++++++++++++++++++++++++++ ///++++++++++++++++++++++++++++++++++++++++++
...@@ -336,29 +383,33 @@ inline void set_imageParamsR_all(int n, unsigned long d) ...@@ -336,29 +383,33 @@ inline void set_imageParamsR_all(int n, unsigned long d)
* subset of that frame data is copied to pastpars * subset of that frame data is copied to pastpars
* (thisFrameNumber-2) mod 8 - farthest in the future frame * (thisFrameNumber-2) mod 8 - farthest in the future frame
* after: thisFrameNumber matches hardware pointer * after: thisFrameNumber matches hardware pointer
* @param sensor_port sensor port number (0..3)
* @param interframe_pars pointer to structure (between frames in the frame buffer) to save a pointer to past parameters * @param interframe_pars pointer to structure (between frames in the frame buffer) to save a pointer to past parameters
* pass NULL if compressor was off (or no time to copy?) * pass NULL if compressor was off (or no time to copy?)
*/ */
void updateFramePars(int frame8, struct interframe_params_t * interframe_pars) void updateFramePars(int sensor_port, int frame8, struct interframe_params_t * interframe_pars)
{ {
int findex_this, findex_prev, findex_future, findex_next; int findex_this, findex_prev, findex_future, findex_next;
int index, index32; int index, index32;
unsigned long bmask, bmask32; unsigned long bmask, bmask32;
int pastParsIndex; int pastParsIndex;
struct framepars_t *framepars = aframepars[sensor_port];
/// If interrupt was from compression done (circbuf advanced, interframe_pars!=null), the frame8 (hardware) maybe not yet advanced /// If interrupt was from compression done (circbuf advanced, interframe_pars!=null), the frame8 (hardware) maybe not yet advanced
/// We can fix it here, but it will not work if some frames were not processed in time /// We can fix it here, but it will not work if some frames were not processed in time
if ((interframe_pars != NULL) && (((frame8 ^ thisFrameNumber) & PARS_FRAMES_MASK) == 0)) { if ((interframe_pars != NULL) && (((frame8 ^ thisFrameNumber(sensor_port)) & PARS_FRAMES_MASK) == 0)) {
findex_this = frame8 & PARS_FRAMES_MASK; findex_this = frame8 & PARS_FRAMES_MASK;
/* 393 TODO: Check what to do with P_IRQ_SMART */
if (framepars[findex_this].pars[P_IRQ_SMART] & 4) frame8 = (frame8 + 1) & PARS_FRAMES_MASK; // verify that this mode is enabled (together with bit0) if (framepars[findex_this].pars[P_IRQ_SMART] & 4) frame8 = (frame8 + 1) & PARS_FRAMES_MASK; // verify that this mode is enabled (together with bit0)
} }
while ((frame8 ^ thisFrameNumber) & PARS_FRAMES_MASK) { while ((frame8 ^ thisFrameNumber(sensor_port)) & PARS_FRAMES_MASK) {
/// before update: /// before update:
/// framepars[findex_prev] holds previous frame data (oldest availble) /// framepars[findex_prev] holds previous frame data (oldest availble)
/// framepars[findex_future] holds fartherst in the future one /// framepars[findex_future] holds farthest in the future one
/// after update: /// after update:
/// framepars[findex_prev] holds fartherst in the future one ("this" will become "prev") /// framepars[findex_prev] holds farthest in the future one ("this" will become "prev")
findex_this = thisFrameNumber & 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; // farthest in the future findex_future = (findex_this - 2) & PARS_FRAMES_MASK; // farthest in the future
findex_next = (findex_this + 1) & PARS_FRAMES_MASK; findex_next = (findex_this + 1) & PARS_FRAMES_MASK;
...@@ -366,20 +417,19 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars) ...@@ -366,20 +417,19 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars)
/// TODO:DONE: Change - make pastpars be save for all frames, not just compressed ones /// TODO:DONE: Change - make pastpars be save for all frames, not just compressed ones
/// With PASTPARS_SAVE_ENTRIES being multiple of PARS_FRAMES - make it possible to calculate past_index from thisFrameNumber /// With PASTPARS_SAVE_ENTRIES being multiple of PARS_FRAMES - make it possible to calculate past_index from thisFrameNumber
// pastParsIndex= thisFrameNumber & PASTPARS_SAVE_ENTRIES_MASK; // pastParsIndex= thisFrameNumber & PASTPARS_SAVE_ENTRIES_MASK;
pastParsIndex = (thisFrameNumber - 1) & PASTPARS_SAVE_ENTRIES_MASK; /// copying from what was past frame that might include histogram data pastParsIndex = (thisFrameNumber(sensor_port) - 1) & PASTPARS_SAVE_ENTRIES_MASK; /// copying from what was past frame that might include histogram data
// memcpy (pastpars[pastParsIndex].past_pars, &framepars[findex_prev].pars[PARS_SAVE_FROM], sizeof(pastpars[0].past_pars)); // memcpy (pastpars[pastParsIndex].past_pars, &framepars[findex_prev].pars[PARS_SAVE_FROM], sizeof(pastpars[0].past_pars));
memcpy(pastpars[pastParsIndex].past_pars, &framepars[findex_prev].pars[PARS_SAVE_FROM], PARS_SAVE_COPY << 2); memcpy(apastpars[sensor_port][pastParsIndex].past_pars, &framepars[findex_prev].pars[PARS_SAVE_FROM], PARS_SAVE_COPY * sizeof(int));
/// Now update interframe_pars (interframe area) used to create JPEG headers. Interframe area survives exactly as long as the frames themselves (not like pastpars) /// Now update interframe_pars (interframe area) used to create JPEG headers. Interframe area survives exactly as long as the frames themselves (not like pastpars)
if (interframe_pars) { /// frame was compressed, not just vsync if (interframe_pars) { /// frame was compressed, not just vsync
///TODO: get rid of *_prev, use it for the future. ///TODO: get rid of *_prev, use it for the future.
memcpy(interframe_pars, &framepars[findex_this].pars[P_GTAB_R], 24); /// will leave some gaps, but copy [P_ACTUAL_WIDTH] memcpy(interframe_pars, &framepars[findex_this].pars[P_GTAB_R], 24); /// will leave some gaps, but copy [P_ACTUAL_WIDTH]
interframe_pars->height = framepars[findex_this].pars[P_ACTUAL_HEIGHT]; /// NOTE: P_ACTUAL_WIDTH,P_QUALITY copied with memcpy interframe_pars->height = framepars[findex_this].pars[P_ACTUAL_HEIGHT]; /// NOTE: P_ACTUAL_WIDTH,P_QUALITY copied with memcpy
interframe_pars->color = framepars[findex_this].pars[P_COLOR]; interframe_pars->color = framepars[findex_this].pars[P_COLOR];
interframe_pars->byrshift = framepars[findex_this].pars[P_COMPMOD_BYRSH]; interframe_pars->byrshift = framepars[findex_this].pars[P_COMPMOD_BYRSH];
interframe_pars->quality2 |= (framepars[findex_this].pars[P_PORTRAIT] & 1) << 7; interframe_pars->quality2 |= (framepars[findex_this].pars[P_PORTRAIT] & 1) << 7;
} }
/// copy parameters from findex_future (old "fartherst in the future") to findex_prev (new "fartherst in the future") if it was changed since /// copy parameters from findex_future (old "farthest in the future") to findex_prev (new "fartherst in the future") if it was changed since
if ((bmask32 = framepars[findex_prev].modsince32)) { if ((bmask32 = framepars[findex_prev].modsince32)) {
MDF7(printk("framepars[%d].modsince32=0x%lx\n", findex_prev, bmask32)); MDF7(printk("framepars[%d].modsince32=0x%lx\n", findex_prev, bmask32));
for (index32 = 0; bmask32; index32++, bmask32 >>= 1) { for (index32 = 0; bmask32; index32++, bmask32 >>= 1) {
...@@ -400,10 +450,10 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars) ...@@ -400,10 +450,10 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars)
if (framepars[findex_prev].mod32) memset(framepars[findex_prev].mod, 0, 32 * 4); /// .mod[0]-.mod[30], .mod32 if (framepars[findex_prev].mod32) memset(framepars[findex_prev].mod, 0, 32 * 4); /// .mod[0]-.mod[30], .mod32
framepars[findex_prev].functions = 0; /// No functions yet needed on the brand new frame framepars[findex_prev].functions = 0; /// No functions yet needed on the brand new frame
// remark: replace number 7 with named constant, it should correspond to total frame num (16 in new camera) // remark: replace number 7 with named constant, it should correspond to total frame num (16 in new camera)
framepars[findex_prev].pars[P_FRAME] = thisFrameNumber + 7; /// that will be the full frame number framepars[findex_prev].pars[P_FRAME] = thisFrameNumber(sensor_port) + (PARS_FRAMES-1); /// that will be the full frame number
/// NOTE: Handle past due - copy functions, and mod if functions were non-zero /// NOTE: Handle past due - copy functions, and mod if functions were non-zero
if (framepars[findex_this].functions) { /// Some functions were not yet processed (past due) if (framepars[findex_this].functions) { /// Some functions were not yet processed (past due)
if (!(get_globalParam(G_TASKLET_CTL) & (1 << TASKLET_CTL_IGNPAST))) { if (!(get_globalParam(sensor_port, G_TASKLET_CTL) & (1 << TASKLET_CTL_IGNPAST))) {
framepars[findex_next].functions |= framepars[findex_this].functions; framepars[findex_next].functions |= framepars[findex_this].functions;
if ((bmask32 = framepars[findex_this].mod32)) { if ((bmask32 = framepars[findex_this].mod32)) {
for (index32 = 0; bmask32; index32++, bmask32 >>= 1) { for (index32 = 0; bmask32; index32++, bmask32 >>= 1) {
...@@ -413,42 +463,40 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars) ...@@ -413,42 +463,40 @@ void updateFramePars(int frame8, struct interframe_params_t * interframe_pars)
framepars[findex_next].mod32 |= framepars[findex_this].mod32; framepars[findex_next].mod32 |= framepars[findex_this].mod32;
} }
} }
MDF7(printk("resubmitting past due functions = 0x%lx for frame=%ld (0x%x)\n", framepars[findex_this].functions, thisFrameNumber, findex_this)); MDF7(printk("resubmitting past due functions = 0x%lx for frame=%ld (0x%x)\n", framepars[findex_this].functions, thisFrameNumber(sensor_port), findex_this));
} else { } else {
MDF(printk("Ignored past due functions = 0x%lx for frame=%ld (0x%x)\n", framepars[findex_this].functions, thisFrameNumber, findex_this)); MDF(printk("Ignored past due functions = 0x%lx for frame=%ld (0x%x)\n", framepars[findex_this].functions, thisFrameNumber(sensor_port), findex_this));
} }
} }
thisFrameNumber++; thisFrameNumber(sensor_port)++;
} }
} }
void update_frame_pars(void)
{
printk(KERN_DEBUG "%s stub\n", __func__);
}
/** /**
* @brief process parameters that are overdue or due in ASAP mode (not through the sequencer) * @brief process parameters that are overdue or due in ASAP mode (not through the sequencer)
* Called twice from processPars - at the beginning and at the end to finish off any derivatives (needed?) * Called twice from processPars - at the beginning and at the end to finish off any derivatives (needed?)
* @param sensor_port sensor port number (0..3)
* @param sensorproc * @param sensorproc
* @param frame8 * @param frame8
*/ */
inline void processParsASAP(struct sensorproc_t * sensorproc, int frame8) inline void processParsASAP(int sensor_port, struct sensorproc_t * sensorproc, int frame8)
{ {
unsigned long todo, mask, remain; unsigned long todo, mask, remain;
int pars_ahead; /// considering parameter "pars_ahead" of the (frame8+job_ahead) mod 8 int pars_ahead; /// considering parameter "pars_ahead" of the (frame8+job_ahead) mod 8
int frame_proc; /// current frame for which parameters are considered int frame_proc; /// current frame for which parameters are considered
struct framepars_t * procpars; struct framepars_t * procpars;
struct framepars_t * prevpars; /// maybe - drop calculation for each function, move it to pgm_* where needed? struct framepars_t * prevpars; /// maybe - drop calculation for each function, move it to pgm_* where needed?
unsigned long * p_nasap = &GLOBALPARS(G_CALLNASAP); struct framepars_t *framepars = aframepars[sensor_port];
unsigned long * p_nasap = &GLOBALPARS(sensor_port, G_CALLNASAP);
int i; int i;
int rslt; int rslt;
struct framepars_t *framepars = aframepars[sensor_port];
#if ELPHEL_DEBUG #if ELPHEL_DEBUG
unsigned long allfunctions = framepars[0].functions | framepars[1].functions | framepars[2].functions | framepars[3].functions | unsigned long allfunctions = framepars[0].functions | framepars[1].functions | framepars[2].functions | framepars[3].functions |
framepars[4].functions | framepars[5].functions | framepars[6].functions | framepars[7].functions; framepars[4].functions | framepars[5].functions | framepars[6].functions | framepars[7].functions;
if (allfunctions) MDF6(printk("frame8=%d, functions: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", frame8, framepars[0].functions, framepars[1].functions, framepars[2].functions, framepars[3].functions, framepars[4].functions, framepars[5].functions, framepars[6].functions, framepars[7].functions)); if (allfunctions) MDF6(printk("frame8=%d, functions: %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", frame8, framepars[0].functions,
framepars[1].functions, framepars[2].functions, framepars[3].functions, framepars[4].functions, framepars[5].functions,
framepars[6].functions, framepars[7].functions));
#endif #endif
/// do all ASAP tasks (they should not be done ahead of the corresponding interrupt!) /// do all ASAP tasks (they should not be done ahead of the corresponding interrupt!)
/// Now try overdue functions with latencies >=1 and try them in ASAP mode /// Now try overdue functions with latencies >=1 and try them in ASAP mode
...@@ -469,9 +517,12 @@ inline void processParsASAP(struct sensorproc_t * sensorproc, int frame8) ...@@ -469,9 +517,12 @@ inline void processParsASAP(struct sensorproc_t * sensorproc, int frame8)
remain <<= 1; remain <<= 1;
} }
/// now (todo & mask) !=0 /// now (todo & mask) !=0
MDF6(printk(" todo=0x%08lx (curr=0x%08lx) frame8=%d, pars_ahead=%d, frame_proc=%d i=%d, mask=0x%08lx\n", todo, procpars->functions, frame8, pars_ahead, frame_proc, i, mask)); MDF6(printk(" todo=0x%08lx (curr=0x%08lx) frame8=%d, pars_ahead=%d, frame_proc=%d i=%d, mask=0x%08lx\n",
todo, procpars->functions, frame8, pars_ahead, frame_proc, i, mask));
MDF6(printk(" %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n", framepars[0].functions, framepars[1].functions, framepars[2].functions, framepars[3].functions, framepars[4].functions, framepars[5].functions, framepars[6].functions, framepars[7].functions)); MDF6(printk(" %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
framepars[0].functions, framepars[1].functions, framepars[2].functions, framepars[3].functions,
framepars[4].functions, framepars[5].functions, framepars[6].functions, framepars[7].functions));
if (sensorproc->pgm_func[i]) { if (sensorproc->pgm_func[i]) {
rslt = sensorproc->pgm_func[i] ( &(sensorproc->sensor), procpars, prevpars, -1); rslt = sensorproc->pgm_func[i] ( &(sensorproc->sensor), procpars, prevpars, -1);
...@@ -497,15 +548,16 @@ inline void processParsASAP(struct sensorproc_t * sensorproc, int frame8) ...@@ -497,15 +548,16 @@ inline void processParsASAP(struct sensorproc_t * sensorproc, int frame8)
//#define G_CALLNEXT4 123 // bitmask of actions to be four or more frames ahead of the programmed one //#define G_CALLNEXT4 123 // bitmask of actions to be four or more frames ahead of the programmed one
inline void processParsSeq(struct sensorproc_t * sensorproc, int frame8, int maxahead) inline void processParsSeq(int sensor_port, struct sensorproc_t * sensorproc, int frame8, int maxahead)
{ {
unsigned long todo, mask, remain; unsigned long todo, mask, remain;
int job_ahead; /// doing job "job_ahead" ahead of needed int job_ahead; /// doing job "job_ahead" ahead of needed
int pars_ahead; /// considering parameter "pars_ahead" of the (frame8+job_ahead) mod 8 int pars_ahead; /// considering parameter "pars_ahead" of the (frame8+job_ahead) mod 8
int frame_proc; /// current frame for which parameters are considered int frame_proc; /// current frame for which parameters are considered
struct framepars_t * procpars; struct framepars_t * procpars;
struct framepars_t * prevpars; /// maybe - drop calculation fpr each function, move it to pgm_* where needed? struct framepars_t * prevpars; /// maybe - drop calculation for each function, move it to pgm_* where needed?
unsigned long * p_nasap = &GLOBALPARS(G_CALLNASAP); struct framepars_t *framepars = aframepars[sensor_port];
unsigned long * p_nasap = &GLOBALPARS(sensor_port, G_CALLNASAP);
int seq_frame; /// sequencer frame for which pgm_* function should schedule data int seq_frame; /// sequencer frame for which pgm_* function should schedule data
int i; int i;
int rslt; int rslt;
...@@ -572,6 +624,7 @@ inline void processParsSeq(struct sensorproc_t * sensorproc, int frame8, int max ...@@ -572,6 +624,7 @@ inline void processParsSeq(struct sensorproc_t * sensorproc, int frame8, int max
/** /**
* @brief Program image acquisition, according to the parameters changed * @brief Program image acquisition, according to the parameters changed
* Called from ISR? * Called from ISR?
* @param sensor_port sensor port number (0..3)
* @param sensorproc pointer to sensor static parameters and functions * @param sensorproc pointer to sensor static parameters and functions
* @param frame8 current hardware frame number * @param frame8 current hardware frame number
* @param maxahead maximal number of frames to program ahead of the current (make it P_* parameter ?) * @param maxahead maximal number of frames to program ahead of the current (make it P_* parameter ?)
...@@ -580,66 +633,70 @@ inline void processParsSeq(struct sensorproc_t * sensorproc, int frame8, int max ...@@ -580,66 +633,70 @@ inline void processParsSeq(struct sensorproc_t * sensorproc, int frame8, int max
//TODO: "Do it later" should be the only reason not to erase todo bit //TODO: "Do it later" should be the only reason not to erase todo bit
//#define P_CALLASAP 107 // bitmask - what functions work only in the current frame (ASAP) mode //#define P_CALLASAP 107 // bitmask - what functions work only in the current frame (ASAP) mode
void processPars(struct sensorproc_t * sensorproc, int frame8, int maxahead) void processPars(int sensor_port, struct sensorproc_t * sensorproc, int frame8, int maxahead)
{ {
frame8 &= PARS_FRAMES_MASK; frame8 &= PARS_FRAMES_MASK;
/// 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!)
// MDF6(printk("before first processParsASAP\n")); // MDF6(printk("before first processParsASAP\n"));
processParsASAP(sensorproc, frame8); processParsASAP(sensor_port, sensorproc, frame8);
/// now - the rest commands that use FPGA queues for the i2c/sequencer commands, executed at frame syncs /// now - the rest commands that use FPGA queues for the i2c/sequencer commands, executed at frame syncs
/// for jobahead =0 it is still possible to have some functions in ASAP mode with non-zero latency /// for jobahead =0 it is still possible to have some functions in ASAP mode with non-zero latency
// MDF6(printk("before processParsSeq\n")); // MDF6(printk("before processParsSeq\n"));
processParsSeq(sensorproc, frame8, maxahead); processParsSeq(sensor_port, sensorproc, frame8, maxahead);
/// re-test ASAP tasks - they might appear as a result of other commands executed /// re-test ASAP tasks - they might appear as a result of other commands executed
// MDF6(printk("before second processParsASAP\n")); // MDF6(printk("before second processParsASAP\n"));
processParsASAP(sensorproc, frame8); processParsASAP(sensor_port, sensorproc, frame8);
} }
/** /**
* @brief schedule pgm_func to be executed for selected frame (frame8) * @brief schedule pgm_func to be executed for selected frame (frame8)
* @param sensor_port sensor port number (0..3)
* @param frame8 frame number (3-bit) to schedule a function for * @param frame8 frame number (3-bit) to schedule a function for
* @param func_num function number to schedule * @param func_num function number to schedule
*/ */
void schedule_pgm_func(int frame8, int func_num) void schedule_pgm_func(int sensor_port, int frame8, int func_num)
{ {
MDF1(printk(" frame8=%d, func_num=%d\n", frame8, func_num)); MDF1(printk(" frame8=%d, func_num=%d\n", frame8, func_num));
framepars[frame8 & PARS_FRAMES_MASK].functions |= 1 << func_num; aframepars[sensor_port][frame8 & PARS_FRAMES_MASK].functions |= 1 << func_num;
} }
/** /**
* @brief schedule pgm_func to be executed for this_framepars->pars[P_FRAME] & PARS_FRAMES_MASK * @brief schedule pgm_func to be executed for this_framepars->pars[P_FRAME] & PARS_FRAMES_MASK
* @param sensor_port sensor port number (0..3)
* @param this_framepars pointer to frame parameters structure * @param this_framepars pointer to frame parameters structure
* @param func_num number of function to schedule * @param func_num number of function to schedule
*/ */
void schedule_this_pgm_func(struct framepars_t * this_framepars, int func_num) void schedule_this_pgm_func(int sensor_port, struct framepars_t * this_framepars, int func_num)
{ {
int frame8 = this_framepars->pars[P_FRAME] & PARS_FRAMES_MASK; int frame8 = this_framepars->pars[P_FRAME] & PARS_FRAMES_MASK;
MDF1(printk(" frame8=%d, func_num=%d\n", frame8, func_num)); MDF1(printk(" frame8=%d, func_num=%d\n", frame8, func_num));
framepars[frame8].functions |= 1 << func_num; aframepars[sensor_port][frame8].functions |= 1 << func_num;
} }
/** /**
* @brief just return current thisFrameNumber * @brief just return current thisFrameNumber
* @param sensor_port sensor port number (0..3)
* @return current value of thisFrameNumber * @return current value of thisFrameNumber
*/ */
unsigned long getThisFrameNumber(void) unsigned long getThisFrameNumber(int sensor_port)
{ {
return thisFrameNumber; return thisFrameNumber(sensor_port);
} }
/** /**
* @brief Set parameters that will never change (usually after sensor discovery) * @brief Set parameters that will never change (usually after sensor discovery)
* @param sensor_port sensor port number (0..3)
* @param numPars number of parameters to set * @param numPars number of parameters to set
* @param pars array of parameters (number/value pairs) * @param pars array of parameters (number/value pairs)
* @return always 0 * @return always 0
*/ */
int setFrameParsStatic(int numPars, struct frameparspair_t * pars) int setFrameParsStatic(int sensor_port, int numPars, struct frameparspair_t * pars)
{ {
int npar, nframe, index; int npar, nframe, index;
struct framepars_t *framepars = aframepars[sensor_port];
for (npar = 0; npar < numPars; npar++) { for (npar = 0; npar < numPars; npar++) {
index = pars[npar].num; index = pars[npar].num;
if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX; if (index > P_MAX_PAR) return -ERR_FRAMEPARS_BADINDEX;
...@@ -652,6 +709,7 @@ int setFrameParsStatic(int numPars, struct frameparspair_t * pars) ...@@ -652,6 +709,7 @@ int setFrameParsStatic(int numPars, struct frameparspair_t * pars)
/** /**
* @brief set parameters for the specified frame (atomic, with interrupts off). Used from applications through driver write * @brief set parameters for the specified frame (atomic, with interrupts off). Used from applications through driver write
* @param sensor_port sensor port number (0..3)
* @param frameno absolute (full) frame number parameters should be applied to * @param frameno absolute (full) frame number parameters should be applied to
* @param maxLatency maximal command latency (parameters should be set not less than maxLatency ahead of the current frame) * @param 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)
...@@ -660,29 +718,30 @@ int setFrameParsStatic(int numPars, struct frameparspair_t * pars) ...@@ -660,29 +718,30 @@ int setFrameParsStatic(int numPars, struct frameparspair_t * pars)
* @return 0 - OK, -ERR_FRAMEPARS_TOOEARLY, -ERR_FRAMEPARS_TOOLATE * @return 0 - OK, -ERR_FRAMEPARS_TOOEARLY, -ERR_FRAMEPARS_TOOLATE
*/ */
///TODO: Check that writes never to the future or past frame (only 6 of 8 are allowed). Have seen just_this to flood all ///TODO: Check that writes never to the future or past frame (only 6 of 8 are allowed). Have seen just_this to flood all
int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struct frameparspair_t * pars) int setFrameParsAtomic(int sensor_port, unsigned long frameno, int maxLatency, int numPars, struct frameparspair_t * pars)
{ {
unsigned long flags; unsigned long flags;
int npar, nframe; int npar, nframe;
unsigned long val, bmask, bmask32; unsigned long val, bmask, bmask32;
int index, bindex; int index, bindex;
struct framepars_t *framepars = aframepars[sensor_port];
unsigned long *funcs2call =afuncs2call[sensor_port];
if (!frameParsInitialized) { if (!frameParsInitialized) {
initSequencers(); /// Will call initFramePars(); and initialize functions initSequencers(); /// Will call initFramePars(); and initialize functions
} }
int findex_this = thisFrameNumber & PARS_FRAMES_MASK; int findex_this = thisFrameNumber(sensor_port) & PARS_FRAMES_MASK;
int findex_prev = (findex_this - 1) & PARS_FRAMES_MASK; int findex_prev = (findex_this - 1) & PARS_FRAMES_MASK;
int findex_future = (findex_this - 2) & PARS_FRAMES_MASK; /// actually - fartherst in the future?? int findex_future = (findex_this - 2) & PARS_FRAMES_MASK; /// actually - fartherst in the future??
// int frame8= frameno & PARS_FRAMES_MASK; // int frame8= frameno & PARS_FRAMES_MASK;
int frame8; int frame8;
MDF2(printk(": frameno=0x%lx, findex_this=%d (0x%lx) maxLatency=%d, numPars=%d\n", frameno, findex_this, thisFrameNumber, maxLatency, numPars)); MDF2(printk(": frameno=0x%lx, findex_this=%d (0x%lx) maxLatency=%d, numPars=%d\n", frameno, findex_this, thisFrameNumber(sensor_port), maxLatency, numPars));
D1I(local_irq_save(flags)); D1I(local_irq_save(flags));
PROFILE_NOW(6); PROFILE_NOW(6);
if (maxLatency >= 0) { if (maxLatency >= 0) {
if (frameno <= (thisFrameNumber + maxLatency)) { if (frameno <= (thisFrameNumber(sensor_port) + maxLatency)) {
D1I(local_irq_restore(flags)); D1I(local_irq_restore(flags));
return -ERR_FRAMEPARS_TOOLATE; return -ERR_FRAMEPARS_TOOLATE;
}else if (frameno >= (thisFrameNumber + (PARS_FRAMES - 1))) { }else if (frameno >= (thisFrameNumber(sensor_port) + (PARS_FRAMES - 1))) {
D1I(local_irq_restore(flags)); D1I(local_irq_restore(flags));
return -ERR_FRAMEPARS_TOOEARLY; return -ERR_FRAMEPARS_TOOEARLY;
} }
...@@ -701,9 +760,9 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc ...@@ -701,9 +760,9 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc
D5(printk(" index=0x%x, val=0x%lx", index, val)); D5(printk(" index=0x%x, val=0x%lx", index, val));
if (index >= FRAMEPAR_GLOBALS) { /// ignore frame logic, set "static" parameters to frame 0 if (index >= FRAMEPAR_GLOBALS) { /// ignore frame logic, set "static" parameters to frame 0
if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { /// combine new value with the old one if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { /// combine new value with the old one
val = FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, GLOBALPARS(index), val); val = FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, GLOBALPARS(sensor_port,index), val);
} }
GLOBALPARS(index) = val; GLOBALPARS(sensor_port, index) = val;
D5(printk(" set GLOBALPARS(0x%x)=0x%lx\n", index, val)); D5(printk(" set GLOBALPARS(0x%x)=0x%lx\n", index, val));
} else if (pars[npar].num & FRAMEPAIR_FRAME_FUNC) { } else if (pars[npar].num & FRAMEPAIR_FRAME_FUNC) {
funcs2call[index] = val; funcs2call[index] = val;
...@@ -754,7 +813,7 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc ...@@ -754,7 +813,7 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc
if (!(get_globalParam(G_TASKLET_CTL) & (1 << TASKLET_CTL_NOSAME))) { if (!(get_globalParam(G_TASKLET_CTL) & (1 << TASKLET_CTL_NOSAME))) {
// processParsSeq (sensorproc, thisFrameNumber & PARS_FRAMES_MASK, 0); ///maxahead=0, the rest will be processed after frame sync, from the tasklet // processParsSeq (sensorproc, thisFrameNumber & PARS_FRAMES_MASK, 0); ///maxahead=0, the rest will be processed after frame sync, from the tasklet
MDF5(printk("\n")); MDF5(printk("\n"));
processPars(sensorproc, thisFrameNumber & PARS_FRAMES_MASK, 0); ///maxahead=0, the rest will be processed after frame sync, from the tasklet processPars(sensorproc, thisFrameNumber(sensor_port) & PARS_FRAMES_MASK, 0); ///maxahead=0, the rest will be processed after frame sync, from the tasklet
} }
PROFILE_NOW(7); PROFILE_NOW(7);
D1I(local_irq_restore(flags)); D1I(local_irq_restore(flags));
...@@ -764,24 +823,27 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc ...@@ -764,24 +823,27 @@ int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struc
// (like "single frame" - compressor, sensor) first write "stop", then - "single" with FRAMEPAIR_JUST_THIS // (like "single frame" - compressor, sensor) first write "stop", then - "single" with FRAMEPAIR_JUST_THIS
/** /**
* @brief set a single output (calculated) parameter for the frame referenced by this_framepars structure. * @brief set a single output (calculated) parameter for the frame referenced by this_framepars structure.
* Shedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in mindex * Schedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in mindex
* @param sensor_port sensor port number (0..3)
* @param this_framepars pointer to the current parameters structure * @param this_framepars pointer to the current parameters structure
* @param mindex parameter number (with optional modifiers in high bits) * @param mindex parameter number (with optional modifiers in high bits)
* @param val parameter value to set * @param val parameter value to set
* @return 0 - OK, -ERR_FRAMEPARS_BADINDEX * @return 0 - OK, -ERR_FRAMEPARS_BADINDEX
*/ */
int setFramePar(struct framepars_t * this_framepars, unsigned long mindex, unsigned long val) int setFramePar(int sensor_port, struct framepars_t * this_framepars, unsigned long mindex, unsigned long val)
{ {
int frame8 = (this_framepars->pars[P_FRAME]) & PARS_FRAMES_MASK; int frame8 = (this_framepars->pars[P_FRAME]) & PARS_FRAMES_MASK;
unsigned long flags; unsigned long flags;
int nframe; int nframe;
unsigned long bmask, bmask32, bindex; unsigned long bmask, bmask32, bindex;
int findex_this = thisFrameNumber & PARS_FRAMES_MASK; int findex_this = thisFrameNumber(sensor_port) & PARS_FRAMES_MASK;
int findex_prev = (findex_this - 1) & PARS_FRAMES_MASK; int findex_prev = (findex_this - 1) & PARS_FRAMES_MASK;
int findex_future = (findex_this - 2) & PARS_FRAMES_MASK; int findex_future = (findex_this - 2) & PARS_FRAMES_MASK;
int index = mindex & 0xffff; int index = mindex & 0xffff;
struct framepars_t *framepars = aframepars[sensor_port];
unsigned long *funcs2call =afuncs2call[sensor_port];
MDF8(printk(": thisFrameNumber=0x%lx frame8=%d index= %d (0x%lx), val=0x%lx\n", thisFrameNumber, frame8, index, mindex, val)); MDF8(printk(": thisFrameNumber=0x%lx frame8=%d index= %d (0x%lx), val=0x%lx\n", thisFrameNumber(sensor_port), frame8, index, mindex, val));
D1I(local_irq_save(flags)); D1I(local_irq_save(flags));
// if (index > P_MAX_PAR) { // if (index > P_MAX_PAR) {
if (index > ((index >= FRAMEPAR_GLOBALS) ? (P_MAX_GPAR + FRAMEPAR_GLOBALS) : P_MAX_PAR)) { if (index > ((index >= FRAMEPAR_GLOBALS) ? (P_MAX_GPAR + FRAMEPAR_GLOBALS) : P_MAX_PAR)) {
...@@ -791,9 +853,9 @@ int setFramePar(struct framepars_t * this_framepars, unsigned long mindex, unsig ...@@ -791,9 +853,9 @@ int setFramePar(struct framepars_t * this_framepars, unsigned long mindex, unsig
//TODO: optimize to use mask several parameters together //TODO: optimize to use mask several parameters together
if (index >= FRAMEPAR_GLOBALS) { /// ignore frame logic, set "static" parameters to frame 0 if (index >= FRAMEPAR_GLOBALS) { /// ignore frame logic, set "static" parameters to frame 0
if (mindex & FRAMEPAIR_MASK_BYTES) { /// combine new value with the old one if (mindex & FRAMEPAIR_MASK_BYTES) { /// combine new value with the old one
val = FRAMEPAIR_FRAME_MASK_NEW(mindex, GLOBALPARS(index), val); val = FRAMEPAIR_FRAME_MASK_NEW(mindex, GLOBALPARS(sensor_port,index), val);
} }
GLOBALPARS(index) = val; GLOBALPARS(sensor_port,index) = val;
} else if (mindex & FRAMEPAIR_FRAME_FUNC) { /// write to func_proc[] instead } else if (mindex & FRAMEPAIR_FRAME_FUNC) { /// write to func_proc[] instead
funcs2call[index] = val; funcs2call[index] = val;
// } else { // } else {
...@@ -846,22 +908,25 @@ int setFramePar(struct framepars_t * this_framepars, unsigned long mindex, unsig ...@@ -846,22 +908,25 @@ int setFramePar(struct framepars_t * this_framepars, unsigned long mindex, unsig
} }
/** /**
* @brief set multiple output (calculated) parameters for the frame referenced by this_framepars structure. * @brief set multiple output (calculated) parameters for the frame referenced by this_framepars structure.
* Shedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in the particular parameter index * Schedules action only if the FRAMEPAIR_FORCE_PROC modifier bit is set in the particular parameter index
* @param sensor_port sensor port number (0..3)
* @param this_framepars pointer to the current parameters structure * @param this_framepars pointer to the current parameters structure
* @param numPars number of parameters to set * @param numPars number of parameters to set
* @param pars array of parameters (number/value pairs). Parameter numbers accept modifiers * @param pars array of parameters (number/value pairs). Parameter numbers accept modifiers
* @return 0 - OK, -ERR_FRAMEPARS_BADINDEX * @return 0 - OK, -ERR_FRAMEPARS_BADINDEX
*/ */
int setFramePars(struct framepars_t * this_framepars, int numPars, struct frameparspair_t * pars) int setFramePars(int sensor_port, struct framepars_t * this_framepars, int numPars, struct frameparspair_t * pars)
{ {
int frame8; int frame8;
unsigned long flags; unsigned long flags;
int npar, nframe; int npar, nframe;
unsigned long val, bmask, bmask32; unsigned long val, bmask, bmask32;
int index, bindex; int index, bindex;
int findex_this = thisFrameNumber & PARS_FRAMES_MASK; int findex_this = thisFrameNumber(sensor_port) & PARS_FRAMES_MASK;
int findex_prev = (findex_this - 1) & PARS_FRAMES_MASK; int findex_prev = (findex_this - 1) & PARS_FRAMES_MASK;
int findex_future = (findex_this - 2) & PARS_FRAMES_MASK; int findex_future = (findex_this - 2) & PARS_FRAMES_MASK;
struct framepars_t *framepars = aframepars[sensor_port];
unsigned long *funcs2call =afuncs2call[sensor_port];
MDF8(printk(": this_framepars=0x%x numPars=%d\n", (int)this_framepars, numPars)); MDF8(printk(": this_framepars=0x%x numPars=%d\n", (int)this_framepars, numPars));
D1I(local_irq_save(flags)); D1I(local_irq_save(flags));
...@@ -878,9 +943,9 @@ int setFramePars(struct framepars_t * this_framepars, int numPars, struct framep ...@@ -878,9 +943,9 @@ int setFramePars(struct framepars_t * this_framepars, int numPars, struct framep
} }
if (index >= FRAMEPAR_GLOBALS) { /// ignore frame logic, set "static" parameters to frame 0 if (index >= FRAMEPAR_GLOBALS) { /// ignore frame logic, set "static" parameters to frame 0
if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { /// combine new value with the old one if (pars[npar].num & FRAMEPAIR_MASK_BYTES) { /// combine new value with the old one
val = FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, GLOBALPARS(index), val); val = FRAMEPAIR_FRAME_MASK_NEW(pars[npar].num, GLOBALPARS(sensor_port,index), val);
} }
GLOBALPARS(index) = val; GLOBALPARS(sensor_port,index) = val;
} else if (pars[npar].num & FRAMEPAIR_FRAME_FUNC) { } else if (pars[npar].num & FRAMEPAIR_FRAME_FUNC) {
funcs2call[index] = val; funcs2call[index] = val;
// } else { // } else {
...@@ -961,14 +1026,16 @@ int framepars_open(struct inode *inode, struct file *filp) ...@@ -961,14 +1026,16 @@ int framepars_open(struct inode *inode, struct file *filp)
{ {
int res; int res;
struct framepars_pd * privData; struct framepars_pd * privData;
privData = (struct framepars_pd*)kmalloc(sizeof(struct framepars_pd), GFP_KERNEL); privData = (struct framepars_pd*)kmalloc(sizeof(struct framepars_pd), GFP_KERNEL);
if (!privData) return -ENOMEM; if (!privData) return -ENOMEM;
filp->private_data = privData; filp->private_data = privData;
privData->minor = MINOR(inode->i_rdev); privData->minor = MINOR(inode->i_rdev);
MDF1(printk(": minor=0x%x\n", privData->minor)); MDF1(printk(": minor=0x%x\n", privData->minor));
switch (privData->minor) { switch (privData->minor) {
case CMOSCAM_MINOR_FRAMEPARS: case CMOSCAM_MINOR_FRAMEPARS_CHN_0:
case CMOSCAM_MINOR_FRAMEPARS_CHN_1:
case CMOSCAM_MINOR_FRAMEPARS_CHN_2:
case CMOSCAM_MINOR_FRAMEPARS_CHN_3:
inode->i_size = 0; //or return 8 - number of frame pages? inode->i_size = 0; //or return 8 - number of frame pages?
return 0; return 0;
default: default:
...@@ -991,7 +1058,10 @@ int framepars_release(struct inode *inode, struct file *filp) ...@@ -991,7 +1058,10 @@ int framepars_release(struct inode *inode, struct file *filp)
MDF1(printk(": minor=0x%x\n", p)); MDF1(printk(": minor=0x%x\n", p));
switch ( p ) { switch ( p ) {
case CMOSCAM_MINOR_FRAMEPARS: case CMOSCAM_MINOR_FRAMEPARS_CHN_0:
case CMOSCAM_MINOR_FRAMEPARS_CHN_1:
case CMOSCAM_MINOR_FRAMEPARS_CHN_2:
case CMOSCAM_MINOR_FRAMEPARS_CHN_3:
break; break;
default: default:
return -EINVAL; //! do not need to free anything - "wrong number" return -EINVAL; //! do not need to free anything - "wrong number"
...@@ -1016,23 +1086,28 @@ int framepars_release(struct inode *inode, struct file *filp) ...@@ -1016,23 +1086,28 @@ int framepars_release(struct inode *inode, struct file *filp)
loff_t framepars_lseek(struct file * file, loff_t offset, int orig) loff_t framepars_lseek(struct file * file, loff_t offset, int orig)
{ {
unsigned long target_frame; unsigned long target_frame;
struct framepars_pd * privData = (struct framepars_pd*) file -> private_data;
MDF1(printk(" offset=0x%x, orig=0x%x\n", (int)offset, (int)orig)); int sensor_port = privData -> minor - CMOSCAM_MINOR_FRAMEPARS_CHN_0;
MDF1(printk(" offset=0x%x, orig=0x%x, sensor_port = %d\n", (int)offset, (int)orig, sensor_port));
switch (orig) { switch (orig) {
case SEEK_SET: case SEEK_SET:
file->f_pos = offset; file->f_pos = offset;
break; break;
case SEEK_CUR: case SEEK_CUR:
if (offset == 0) return getThisFrameNumber(); /// do not modify frame number if (offset == 0) return getThisFrameNumber(sensor_port); /// do not modify frame number
file->f_pos = getThisFrameNumber() + offset; /// modifies frame number, but it is better to use absolute SEEK SET file->f_pos = getThisFrameNumber(sensor_port) + offset; /// modifies frame number, but it is better to use absolute SEEK SET
break; break;
case SEEK_END: case SEEK_END:
if (offset <= 0) { if (offset <= 0) {
break; break;
} else if (offset >= LSEEK_FRAME_WAIT_REL) { } else if (offset >= LSEEK_FRAME_WAIT_REL) {
if (offset >= LSEEK_FRAME_WAIT_ABS) target_frame = offset - LSEEK_FRAME_WAIT_ABS; /// Wait for absolute frame number if (offset >= LSEEK_FRAME_WAIT_ABS) target_frame = offset - LSEEK_FRAME_WAIT_ABS; /// Wait for absolute frame number
else target_frame = getThisFrameNumber() + offset - LSEEK_FRAME_WAIT_REL; /// Skip 0..255 frames else target_frame = getThisFrameNumber(sensor_port) + offset - LSEEK_FRAME_WAIT_REL;
wait_event_interruptible(framepars_wait_queue, getThisFrameNumber() >= target_frame); /// Skip 0..255 frames
// wait_event_interruptible (framepars_wait_queue, getThisFrameNumber()>=target_frame);
wait_event_interruptible (framepars_wait_queue, 1);
wait_event_interruptible(aframepars_wait_queue[sensor_port], getThisFrameNumber(sensor_port) >= target_frame);
// if (getThisFrameNumber()<target_frame) wait_event_interruptible (framepars_wait_queue,getThisFrameNumber()>=target_frame); // if (getThisFrameNumber()<target_frame) wait_event_interruptible (framepars_wait_queue,getThisFrameNumber()>=target_frame);
return getThisFrameNumber(); /// Does not modify current frame pointer? lseek (,0,SEEK_CUR) anyway returns getThisFrameNumber() return getThisFrameNumber(); /// Does not modify current frame pointer? lseek (,0,SEEK_CUR) anyway returns getThisFrameNumber()
} else { //! Other lseek commands } else { //! Other lseek commands
......
#ifndef _FRAMEPARS_H #ifndef _FRAMEPARS_H
#define _FRAMEPARS_H #define _FRAMEPARS_H
#ifndef SENSOR_PORTS
#include <elphel/c313a.h> // to get SENSOR_PORTS
#endif
//extern struct framepars_t (*framepars)[PARS_FRAMES]; //extern struct framepars_t (*framepars)[PARS_FRAMES];
extern struct framepars_t *framepars; extern struct framepars_t *aframepars[SENSOR_PORTS];
extern struct framepars_past_t *pastpars; extern struct framepars_past_t *apastpars[SENSOR_PORTS];
extern unsigned long *globalPars; extern unsigned long *aglobalPars[SENSOR_PORTS];
extern unsigned long *multiSensIndex; extern unsigned long *amultiSensIndex[SENSOR_PORTS];
extern unsigned long *multiSensRvrsIndex; extern unsigned long *amultiSensRvrsIndex[SENSOR_PORTS];
extern wait_queue_head_t framepars_wait_queue[SENSOR_PORTS];
extern wait_queue_head_t framepars_wait_queue;
///TODO: init framepars (zero parameters) before initscripts (not when detecting the sensors) - then initscript will be able to overwrite some ///TODO: init framepars (zero parameters) before initscripts (not when detecting the sensors) - then initscript will be able to overwrite some
void init_framepars_ptr(void); void init_framepars_ptr(int sensor_port);
void initSequencers(void); ///Move to sensorcommon? currently it is used through frameparsall file (lseek) void initSequencers (int sensor_port); ///Move to sensorcommon? currently it is used through frameparsall file (lseek)
void initGlobalPars(void); /// 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(void); /// 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(void); ///initialize all parameters, set thisFrameNumber to frame8 (read from hardware, usually 0 after resetting i2c and cmd_seq) void initFramePars (int sensor_port); ///initialize all parameters, set thisFrameNumber to frame8 (read from hardware, usually 0 after resetting i2c and cmd_seq)
void resetFrameNumber(void); /// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow) void resetFrameNumber (int sensor_port); /// reset this frame number (called from initFramePars(), also can be used to avoid frame number integer overflow)
unsigned long get_imageParamsThis (int n); unsigned long get_imageParamsThis (int sensor_port, int n);
unsigned long get_imageParamsPrev (int n); unsigned long get_imageParamsPrev (int sensor_port, int n);
void set_imageParamsThis (int n,unsigned long d); void set_imageParamsThis (int sensor_port, int n, unsigned long d);
unsigned long get_globalParam (int n); unsigned long get_globalParam (int sensor_port, int n);
void set_globalParam (int n, unsigned long d); void set_globalParam (int sensor_port, int n, unsigned long d);
void set_imageParamsR_all(int n, unsigned long d); void set_imageParamsR_all(int sensor_port, int n, unsigned long d);
void update_frame_pars(void); void updateFramePars (int sensor_port, int frame8, struct interframe_params_t * frame_pars); /// called from ISR - advance thisFrameNumber to match hardware frame8, copy parameters as needed.
void updateFramePars(int frame8, struct interframe_params_t * frame_pars); /// called from ISR - advance thisFrameNumber to match hardware frame8, copy parameters as needed.
/// frame8 usually is just next after thisFrameNumber /// frame8 usually is just next after thisFrameNumber
/// frame_pars - pointer to structure (between frames in the frame buffer) to save a pointer to past parameters /// frame_pars - pointer to structure (between frames in the frame buffer) to save a pointer to past parameters
int setFrameParsStatic(int numPars, struct frameparspair_t * pars); int setFrameParsStatic (int sensor_port, int numPars, struct frameparspair_t * pars);
unsigned long getThisFrameNumber(void); /// just return current thisFrameNumber unsigned long getThisFrameNumber (int sensor_port); /// just return current thisFrameNumber
/// set parameters for the frame number frameno, knowing that they should be set not less than maxLatency ahead (may be sensor - dependent) /// set parameters for the frame number frameno, knowing that they should be set not less than maxLatency ahead (may be sensor - dependent)
/// Parameters (numPars of them) will be updated all at once, with interrupts disabled /// Parameters (numPars of them) will be updated all at once, with interrupts disabled
/// Return - 0 if OK, -ERR_FRAMEPARS_TOOEARLY or -ERR_FRAMEPARS_TOOLATE if it is too early or too late to set parameters (numPars may be 0 to just test) /// Return - 0 if OK, -ERR_FRAMEPARS_TOOEARLY or -ERR_FRAMEPARS_TOOLATE if it is too early or too late to set parameters (numPars may be 0 to just test)
...@@ -42,27 +43,28 @@ unsigned long getThisFrameNumber(void); /// just return current thisFrameNumber ...@@ -42,27 +43,28 @@ unsigned long getThisFrameNumber(void); /// just return current thisFrameNumber
/// TODO: Make (an "unlimited") future commands que based on lists and a tree frame index /// TODO: Make (an "unlimited") future commands que based on lists and a tree frame index
int setFrameParsAtomic(unsigned long frameno, int maxLatency, int numPars, struct frameparspair_t * pars); int setFrameParsAtomic (int sensor_port, unsigned long frameno, int maxLatency, int numPars, struct frameparspair_t * pars);
/// set output/calculated parameter and propogate changes - will not trigger any actions /// set output/calculated parameter and propagate changes - will not trigger any actions
int setFramePar(struct framepars_t * this_framepars, unsigned long mindex, unsigned long val); int setFramePar (int sensor_port, struct framepars_t * this_framepars, unsigned long mindex, unsigned long val);
///same for several pars at once ///same for several pars at once
int setFramePars(struct framepars_t * this_framepars, int numPars, struct frameparspair_t * pars); int setFramePars (int sensor_port, struct framepars_t * this_framepars, int numPars, struct frameparspair_t * pars);
/// schedule pgm_func to be executed for selected frame /// schedule pgm_func to be executed for selected frame
void schedule_pgm_func(int frame8, int func_num); void schedule_pgm_func (int sensor_port, int frame8, int func_num);
/// schedule pgm_func to be executed for the current frame /// schedule pgm_func to be executed for the current frame
void schedule_this_pgm_func(struct framepars_t * this_framepars, int func_num); void schedule_this_pgm_func (int sensor_port, struct framepars_t * this_framepars, int func_num);
/// program acquisition, according to the parameters changed. /// program acquisition, according to the parameters changed.
/// maxahead - how many frames ahead of time (start with most urgent, then 1 ahead, ...) /// maxahead - how many frames ahead of time (start with most urgent, then 1 ahead, ...)
/// make maxahead - P_* parameter? /// make maxahead - P_* parameter?
inline void processParsASAP (struct sensorproc_t * sensorproc, int frame8); /* 393: See if sesnor port is needed here */
inline void processParsSeq (struct sensorproc_t * sensorproc, int frame8, int maxahead); inline void processParsASAP (int sensor_port, struct sensorproc_t * sensorproc, int frame8);
inline void processParsSeq (int sensor_port, struct sensorproc_t * sensorproc, int frame8, int maxahead);
void processPars (struct sensorproc_t * sensorproc, int frame8, int maxahead); void processPars (int sensor_port, struct sensorproc_t * sensorproc, int frame8, int maxahead);
///*** TODO: Add option (flag?) to write "single" (like single compress, single sensor) so it will not make all the next frames "single" ///*** TODO: Add option (flag?) to write "single" (like single compress, single sensor) so it will not make all the next frames "single"
int framepars_init(struct platform_device *pdev); int framepars_init (struct platform_device *pdev);
int framepars_remove(struct platform_device *pdev); int framepars_remove (struct platform_device *pdev);
#endif #endif
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#define EDBG(x) #define EDBG(x)
#endif #endif
#define ROUND_UP(N, S) ((((N) + (S) - 1) / (S)) * (S))
// _IOC_TYPE, bits 8 to 15 in ioctl cmd // _IOC_TYPE, bits 8 to 15 in ioctl cmd
...@@ -234,8 +234,11 @@ ...@@ -234,8 +234,11 @@
#define SENSORWIDTH_IBIS51300 1280 #define SENSORWIDTH_IBIS51300 1280
#define SENSORHEIGHT_IBIS51300 1024 #define SENSORHEIGHT_IBIS51300 1024
/// Parameters related to multi-sensor (10359A) setup /// Parameters related to multi-sensor (10359A) setup
#define MAX_SENSORS 3 // maximal number of sensor attached (modify some hard-wired constants below if this to be changed) //#define MAX_SENSORS 3 // maximal number of sensor attached (modify some hard-wired constants below if this to be changed)
//! Parameters below are accessed through mmap, because of cache coherency problem it make sense to keep them compact (maybe group by 8 - cache line of 32 bytes) /* Modified for 393 - using up to 4 sub-sensors (even as 10359 only supports 3 */
#define MAX_SENSORS 4 // maximal number of sensor attached (modify some hard-wired constants below if this to be changed)
#define SENSOR_PORTS 4 // Number of sensor ports (each has individual framepars_all_t
//! Parameters below are accessed through mmap, because of cache coherence problem it make sense to keep them compact (maybe group by 8 - cache line of 32 bytes)
#define P_SENSOR_RUN 4 // 0 - stop, 1 - single, 2 - run #define P_SENSOR_RUN 4 // 0 - stop, 1 - single, 2 - run
#define SENSOR_RUN_STOP 0 #define SENSOR_RUN_STOP 0
#define SENSOR_RUN_SINGLE 1 #define SENSOR_RUN_SINGLE 1
...@@ -592,6 +595,13 @@ ...@@ -592,6 +595,13 @@
#define P_MULTI_REGS (P_M10359_REGS + P_M10359_NUMREGS) /// 32-words aligned #define P_MULTI_REGS (P_M10359_REGS + P_M10359_NUMREGS) /// 32-words aligned
#define P_MAX_PAR (P_MULTI_REGS + (MAX_SENSORS * P_MULTI_NUMREGS )) /// maximal # of used parameter+1 #define P_MAX_PAR (P_MULTI_REGS + (MAX_SENSORS * P_MULTI_NUMREGS )) /// maximal # of used parameter+1
/* 393: Making P_MAX_PAR multiple of PAGE_SIZE/2, so framepars_all_t will be multiple of PAGE_SIZE*/
#ifndef PAGE_SIZE
#define PAGE_SIZE 4096 // not using <asm/page.h> as this file may be used outside of kernel
#endif
#define P_MAX_PAR_ROUNDUP ROUND_UP (P_MAX_PAR , (PAGE_SIZE/8)) // half page in DWORDs
#ifdef SAFE_CHECK #ifdef SAFE_CHECK
#define MULTIREG(x,n) ((((n)>=0) && ((n)<MAX_SENSORS) && ((x) >0) && ((x) < P_MAX_PAR) && (multiSensIndex[x] > 0))? (multiSensIndex[x]+(n)) : 0) #define MULTIREG(x,n) ((((n)>=0) && ((n)<MAX_SENSORS) && ((x) >0) && ((x) < P_MAX_PAR) && (multiSensIndex[x] > 0))? (multiSensIndex[x]+(n)) : 0)
#else #else
...@@ -602,8 +612,9 @@ ...@@ -602,8 +612,9 @@
//#define P_MAX_PAR 511 /// maximal # of used parameter //#define P_MAX_PAR 511 /// maximal # of used parameter
//#define P_MAX_GPAR 1023 // maximal # of global parameter //#define P_MAX_GPAR 1023 // maximal # of global parameter
#define P_MAX_GPAR 2047 /// maximal # of global parameter - TODO: change name to NUM_GPAR and make it 2048 //#define P_MAX_GPAR 2047 /// maximal # of global parameter - TODO: change name to NUM_GPAR and make it 2048
#define NUM_GPAR 2048 /// maximal # of global parameter - TODO: change name to NUM_GPAR and make it 2048
#define P_MAX_GPAR (NUM_GPAR - 1) /// maximal # of global parameter - TODO: change name to NUM_GPAR and make it 2048
#define PARS_SAVE_FROM 128 /// PARS_SAVE_NUM parameters starting from PARS_SAVE_FROM from "this" frame will be saved in circular buffer, PASTPARS_SAVE_ENTRIES entries #define PARS_SAVE_FROM 128 /// PARS_SAVE_NUM parameters starting from PARS_SAVE_FROM from "this" frame will be saved in circular buffer, PASTPARS_SAVE_ENTRIES entries
#define PARS_SAVE_COPY 16 /// number of parameters copied from future (framepars) to the past (pastpars) #define PARS_SAVE_COPY 16 /// number of parameters copied from future (framepars) to the past (pastpars)
...@@ -617,7 +628,7 @@ ...@@ -617,7 +628,7 @@
#define GLOBALS_PRESERVE 0x20 /// number of parameters that are not erased during initGlobalPars #define GLOBALS_PRESERVE 0x20 /// number of parameters that are not erased during initGlobalPars
/// First 32 parameter values are not erased with initGlobalPars /// First 32 parameter values are not erased with initGlobalPars
#define GLOBALPARS(x) globalPars[(x)-FRAMEPAR_GLOBALS] // should work in drivers and applications #define GLOBALPARS(p, x) (aglobalPars[p][(x)-FRAMEPAR_GLOBALS]) // should work in drivers and applications
#define G_DEBUG (FRAMEPAR_GLOBALS + 2) /// Each bit turns on/off some debug outputs #define G_DEBUG (FRAMEPAR_GLOBALS + 2) /// Each bit turns on/off some debug outputs
#define G_TEST_CTL_BITS (FRAMEPAR_GLOBALS + 3) /// turn some features on/off in the drivers for debugging purposes #define G_TEST_CTL_BITS (FRAMEPAR_GLOBALS + 3) /// turn some features on/off in the drivers for debugging purposes
...@@ -817,10 +828,14 @@ ...@@ -817,10 +828,14 @@
/// when the 3-bit counter is combined with the software variable to get the full 32-bit frame number /// when the 3-bit counter is combined with the software variable to get the full 32-bit frame number
/// Each parameter page includes 927 parameter registers, as well as 97 bitmasks to speed up updates between frames /// Each parameter page includes 927 parameter registers, as well as 97 bitmasks to speed up updates between frames
/// So if no parameters are changed - nothing to be copied from page to page /// So if no parameters are changed - nothing to be copied from page to page
#define PARS_FRAMES 8 // number of frames handled in buffer /* Modified for 393 : 16 hardware frames, aligning framepars_all_t to PAGE_SIZE*/
#define PARS_FRAMES_MASK (PARS_FRAMES-1) // currently 7 #define PARS_FRAMES 16 // 8 // number of frames handled in buffer
#define PASTPARS_SAVE_ENTRIES (PARS_FRAMES << 8) // 2048 #define PARS_FRAMES_MASK (PARS_FRAMES-1) // currently 15t // 7
#define PASTPARS_SAVE_ENTRIES_MASK ((PARS_FRAMES << 8)-1) // 0x7ff // Keeping the same size of past frames storage as in 353:
//#define PASTPARS_SAVE_ENTRIES (PARS_FRAMES << 8) // 2048
//#define PASTPARS_SAVE_ENTRIES_MASK ((PARS_FRAMES << 8)-1) // 0x7ff
#define PASTPARS_SAVE_ENTRIES (PARS_FRAMES << 7) // 2048
#define PASTPARS_SAVE_ENTRIES_MASK ((PARS_FRAMES << 7)-1) // 0x7ff
struct framepars_t { struct framepars_t {
unsigned long pars[927]; // parameter values (indexed by P_* constants) unsigned long pars[927]; // parameter values (indexed by P_* constants)
unsigned long functions; // each bit specifies function to be executed (triggered by some parameters change) unsigned long functions; // each bit specifies function to be executed (triggered by some parameters change)
...@@ -893,13 +908,14 @@ struct framepars_past_t { ...@@ -893,13 +908,14 @@ struct framepars_past_t {
unsigned long past_pars[PARS_SAVE_NUM]; unsigned long past_pars[PARS_SAVE_NUM];
}; };
// size should be PAGE_SIZE aligned
struct framepars_all_t { struct framepars_all_t {
struct framepars_t framePars[PARS_FRAMES]; struct framepars_t framePars[PARS_FRAMES];
struct framepars_t func2call; /// func2call.pars[] - each parameter has a 32-bit mask of what pgm_function to call - other fields not used struct framepars_t func2call; /// func2call.pars[] - each parameter has a 32-bit mask of what pgm_function to call - other fields not used
unsigned long globalPars[P_MAX_GPAR]; /// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both R/W unsigned long globalPars[NUM_GPAR]; /// parameters that are not frame-related, their changes do not initiate any actions so they can be mmaped for both R/W
struct framepars_past_t pastPars [PASTPARS_SAVE_ENTRIES]; struct framepars_past_t pastPars [PASTPARS_SAVE_ENTRIES];
unsigned long multiSensIndex[P_MAX_PAR]; /// indexes of individual sensor register shadows (first of 3) - now for all parameters, not just sensor ones unsigned long multiSensIndex[P_MAX_PAR_ROUNDUP]; /// indexes of individual sensor register shadows (first of 3) - now for all parameters, not just sensor ones
unsigned long multiSensRvrsIndex[P_MAX_PAR]; /// reverse index (to parent) for the multiSensIndex in lower 16 bits, high 16 bits - sensor number unsigned long multiSensRvrsIndex[P_MAX_PAR_ROUNDUP]; /// reverse index (to parent) for the multiSensIndex in lower 16 bits, high 16 bits - sensor number
}; };
struct frameparspair_t { struct frameparspair_t {
...@@ -1771,7 +1787,7 @@ struct gamma_stuct_t { ...@@ -1771,7 +1787,7 @@ struct gamma_stuct_t {
#define HISTOGRAM_TABLE_OFFSET 52 /// Histogram tables data starts 44 bytes from the histogram page structure (for PHP raw histogram) #define HISTOGRAM_TABLE_OFFSET 52 /// Histogram tables data starts 44 bytes from the histogram page structure (for PHP raw histogram)
///TODO: Update when histogram_stuct_t is changed ///TODO: Update when histogram_stuct_t is changed
struct histogram_stuct_t { struct histogram_stuct_t {
unsigned long frame; /// frame number correspoding to the current histogram unsigned long frame; /// frame number corresponding to the current histogram
/// Color gains for the frame of the histogram /// Color gains for the frame of the histogram
union { union {
unsigned long gains[4]; unsigned long gains[4];
......
...@@ -45,6 +45,11 @@ ...@@ -45,6 +45,11 @@
#define HUFFMAN_MINOR_CHN_2 0x42 #define HUFFMAN_MINOR_CHN_2 0x42
#define HUFFMAN_MINOR_CHN_3 0x43 #define HUFFMAN_MINOR_CHN_3 0x43
#define CMOSCAM_MINOR_FRAMEPARS_CHN_0 0x50
#define CMOSCAM_MINOR_FRAMEPARS_CHN_1 0x51
#define CMOSCAM_MINOR_FRAMEPARS_CHN_2 0x52
#define CMOSCAM_MINOR_FRAMEPARS_CHN_3 0x53
#define CMOSCAM_MINOR_RWTABLES 9 #define CMOSCAM_MINOR_RWTABLES 9
#define CMOSCAM_MINOR_CIRCBUF 11 #define CMOSCAM_MINOR_CIRCBUF 11
#define CMOSCAM_MINOR_HISTOGRAM 12 #define CMOSCAM_MINOR_HISTOGRAM 12
......
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