Commit af248eb3 authored by Andrey Filippov's avatar Andrey Filippov

working on histograms code

parent 8697a0d7
This diff is collapsed.
...@@ -18,14 +18,14 @@ void gamma_encode_fpga(unsigned short * gamma_in, unsigned long * gamma_out);/// ...@@ -18,14 +18,14 @@ void gamma_encode_fpga(unsigned short * gamma_in, unsigned long * gamma_out);///
void gamma_calc_scaled (unsigned short scale,unsigned short * gamma_in, unsigned short * gamma_out);/// scale gamma table by (scale>>GAMMA_SCALE_SHIFT), saturate to 0..0xffff void gamma_calc_scaled (unsigned short scale,unsigned short * gamma_in, unsigned short * gamma_out);/// scale gamma table by (scale>>GAMMA_SCALE_SHIFT), saturate to 0..0xffff
//void gamma_calc_reverse(unsigned short * gamma_in, unsigned short * gamma_out);/// calculate reverse gamma table (16-bit output) that matches 1-byte gamma-converted data to the input data (in the 0..ffff range) //void gamma_calc_reverse(unsigned short * gamma_in, unsigned short * gamma_out);/// calculate reverse gamma table (16-bit output) that matches 1-byte gamma-converted data to the input data (in the 0..ffff range)
void gamma_calc_reverse(unsigned short * gamma_in, unsigned char * gamma_out);/// calculate reverse gamma table (8-bit output) that matches 1-byte gamma-converted data to the input data (in the 0..ffff range) void gamma_calc_reverse(unsigned short * gamma_in, unsigned char * gamma_out);/// calculate reverse gamma table (8-bit output) that matches 1-byte gamma-converted data to the input data (in the 0..ffff range)
/// return index of the specified hash/scale, insert new table (gamma_proto) if needed // return index of the specified hash/scale, insert new table (gamma_proto) if needed
/// If no table is specified (null) - return 0 if no prototype is found // If no table is specified (null) - return 0 if no prototype is found
/// if (not_nice) - don't re-enable interrupts between atomic actions (may fail) // if (not_nice) - don't re-enable interrupts between atomic actions (may fail)
/// if "hardware" is non-zero, color/frame pair will be used to lock node to it, fpga-encoded table will be calculated (if not done so earlier) // if "hardware" is non-zero, color/frame pair will be used to lock node to it, fpga-encoded table will be calculated (if not done so earlier)
// #define GAMMA_MODE_NOT_NICE 1 // if set, no interrupts will be enabled between steps, whole operation is atomic // #define GAMMA_MODE_NOT_NICE 1 // if set, no interrupts will be enabled between steps, whole operation is atomic
// #define GAMMA_MODE_NEED_REVERSE 2 // reverse gamma table is needed // #define GAMMA_MODE_NEED_REVERSE 2 // reverse gamma table is needed
// #define GAMMA_MODE_HARDWARE 4 // the table is needed to program FPGA: fpga-encoded table will be calculated (if not yet), node will be locked for specified // #define GAMMA_MODE_HARDWARE 4 // the table is needed to program FPGA: fpga-encoded table will be calculated (if not yet), node will be locked for specified
// color/frame pair // color/frame pair
int set_gamma_table (unsigned short hash16, unsigned short scale, unsigned short * gamma_proto, unsigned char mode, int color); int set_gamma_table (unsigned short hash16, unsigned short scale, unsigned short * gamma_proto, unsigned char mode, int color, int sensor_port, int sensor_subchn);
unsigned long get_locked_hash32(int color); unsigned long get_locked_hash32(int color);
#endif #endif
This diff is collapsed.
...@@ -6,8 +6,11 @@ ...@@ -6,8 +6,11 @@
extern wait_queue_head_t hist_y_wait_queue; /// wait queue for the G1 histogram (used as Y) extern wait_queue_head_t hist_y_wait_queue; /// wait queue for the G1 histogram (used as Y)
extern wait_queue_head_t hist_c_wait_queue; /// wait queue for all the other (R,G2,B) histograms (color) extern wait_queue_head_t hist_c_wait_queue; /// wait queue for all the other (R,G2,B) histograms (color)
void init_histograms(void); void init_histograms(int chn_mask);
int set_histograms (unsigned long frame, int needed, unsigned long * gammaHash, unsigned long * framep);
int get_hist_index (int sensor_port, int sensor_chn);
int set_histograms (int sensor_port, int sensor_chn, unsigned long frame, int needed, unsigned long * gammaHash, unsigned long * framep);
/** /**
* @brief Get histograms from the FPGA (called as tasklet?) and/or calculate derivatives (if needed) * @brief Get histograms from the FPGA (called as tasklet?) and/or calculate derivatives (if needed)
...@@ -15,11 +18,11 @@ int set_histograms (unsigned long frame, int needed, unsigned long * gammaHash, ...@@ -15,11 +18,11 @@ int set_histograms (unsigned long frame, int needed, unsigned long * gammaHash,
* TODO: should it be one frame behind current? * TODO: should it be one frame behind current?
* @param needed bits specify what histograms (color, type) are requested * @param needed bits specify what histograms (color, type) are requested
* TODO: Add P_* parameter - what to read from tasklet, turn colors it off for high FPS/small window * TODO: Add P_* parameter - what to read from tasklet, turn colors it off for high FPS/small window
* each group of 4 bits cover 4 colors of the same type: * each group of 4 bits covers 4 colors of the same type:
* - bits 0..3 - read raw histograms from the FPGA - normally called from IRQ/tasklet (use just 1 color for autoexposure to speed up?) * - bits 0..3 - read raw histograms from the FPGA - normally called from IRQ/tasklet (use just 1 color for autoexposure to speed up?)
* - bits 4..7 - calculate cumulative histograms (sum of raw ones) - normally called from applications * - bits 4..7 - calculate cumulative histograms (sum of raw ones) - normally called from applications
* - bits 8..11 - calculate percentiles (reverse cumulative histograms) - normally called from applications * - bits 8..11 - calculate percentiles (reverse cumulative histograms) - normally called from applications
* "needed" for raw histograms should be specified explicitely (can not be read from FPGA later), * "needed" for raw histograms should be specified explicitly (can not be read from FPGA later),
* "needed" for cumul_hist will be added automatically if percentiles are requested * "needed" for cumul_hist will be added automatically if percentiles are requested
* @return index of the histogram (>=0) if OK, otherwise: * @return index of the histogram (>=0) if OK, otherwise:
* - -1 not reading FPGA and frame number stored is different from the requested (too late - histogram buffer overrun?) * - -1 not reading FPGA and frame number stored is different from the requested (too late - histogram buffer overrun?)
...@@ -27,3 +30,5 @@ int set_histograms (unsigned long frame, int needed, unsigned long * gammaHash, ...@@ -27,3 +30,5 @@ int set_histograms (unsigned long frame, int needed, unsigned long * gammaHash,
*/ */
int get_histograms (unsigned long frame, int needed); int get_histograms (unsigned long frame, int needed);
int histograms_init_hardware(void);
void histograms_dma_ctrl(int mode); // 0 - reset, 1 - disable, 2 - enable
...@@ -74,7 +74,53 @@ ...@@ -74,7 +74,53 @@
void x313_dma_init(){} void x313_dma_init(){}
void reset_compressor(){} void reset_compressor(){}
// if ((gtable= get_gamma_fpga(color))) fpga_table_write_nice (CX313_FPGA_TABLES_GAMMA + (color * 256), 256, gtable);
// X3X3_SEQ_SEND1(frame16, X313_WA_DCR0, X353_DCR0(SENSTRIGEN,async)); // X3X3_SEQ_SEND1(frame16, X313_WA_DCR0, X353_DCR0(SENSTRIGEN,async));
#ifdef NC353
/// IRQ-safe "nice" FPGA table write and histogram read functions - they split the data in chunks of fixed size,
/// disable IRQ, transfer a chunk, then reenable interrupt before proceedg to the next chunk
#define FPGA_TABLE_CHUNK 64 // up to 64 words to send to the table/from histogram on a single IRQ-off transfer
void fpga_table_write_nice (int addr, int len, unsigned long * data) {
unsigned long flags;
int l,i;
MDF12(printk("addr=0x%x, len=0x%x, data=0x%08lx 0x%08lx 0x%08lx 0x%08lx...\n", addr, len, data[0], data[1], data[2], data[3]));
while (len>0) {
l=(len < FPGA_TABLE_CHUNK)?len:FPGA_TABLE_CHUNK;
local_irq_save(flags);
port_csp0_addr[X313_WA_COMP_TA]=addr; // open fpga for writing table(s)
for (i=0; i<l; i++) port_csp0_addr[X313_WA_COMP_TD]=data[i]; /// will autoincrement FPGA table address
local_irq_restore(flags);
len -=l;
addr +=l;
data +=l;
}
}
///
/// reading histograms really does not need disabling IRQs - they only could interfere with other process, reading histograms
///
void fpga_hist_read_nice (int addr, int len, unsigned long * data) {
unsigned long flags;
int l,i;
MDF13(printk("addr=0x%x, len=0x%x, ",addr, len));
while (len>0) {
l=(len < FPGA_TABLE_CHUNK)?len:FPGA_TABLE_CHUNK;
local_irq_save(flags);
// #define X313_WA_HIST_ADDR 0x44
// #define X313_RA_HIST_DATA 0x45 /// use CSP4 with wait cycles to have a pulse
port_csp0_addr[X313_WA_HIST_ADDR]=addr; /// Write start address, read first word from the memory to the output buffer (will be read out during next read)
X3X3_AFTERWRITE ; //! needed before reading from FPGA after writing to it (for the writes that influence reads only)
for (i=0; i<l; i++) data[i]=port_csp4_addr[X313_RA_HIST_DATA]; /// will autoincrement FPGA table address)
local_irq_restore(flags);
len -=l;
addr +=l;
data +=l;
}
D13(printk("data=0x%08lx 0x%08lx 0x%08lx 0x%08lx...\n", data[0], data[1], data[2], data[3]));
}
#endif
...@@ -1250,7 +1250,12 @@ get_locked_hash32(0),get_locked_hash32(1),get_locked_hash32(2),get_locked_hash32 ...@@ -1250,7 +1250,12 @@ get_locked_hash32(0),get_locked_hash32(1),get_locked_hash32(2),get_locked_hash32
if (get_locked_hash32(color)!=thispars->pars[P_GTAB_R+color]) { // modified for this color if (get_locked_hash32(color)!=thispars->pars[P_GTAB_R+color]) { // modified for this color
*pgamma32=thispars->pars[P_GTAB_R+color]; *pgamma32=thispars->pars[P_GTAB_R+color];
rslt=set_gamma_table (gamma32.hash16, gamma32.scale, NULL, GAMMA_MODE_HARDWARE, color); // frame16 - one ahead of the current do not lock yet rslt=set_gamma_table (gamma32.hash16,
gamma32.scale, NULL,
GAMMA_MODE_HARDWARE,
color,
sensor_port,
0); // frame16 - one ahead of the current do not lock yet TODO 393 multisensor - split gamma tables to subchannels
if (rslt<=0) SETFRAMEPARS_SET(P_GTAB_R+color, get_locked_hash32(color)); // increases nupdate if (rslt<=0) SETFRAMEPARS_SET(P_GTAB_R+color, get_locked_hash32(color)); // increases nupdate
} }
} }
...@@ -2011,7 +2016,13 @@ int pgm_gammaload (int sensor_port, ///< sensor port number (0..3 ...@@ -2011,7 +2016,13 @@ int pgm_gammaload (int sensor_port, ///< sensor port number (0..3
for (color=0; color<4; color++) { for (color=0; color<4; color++) {
*pgamma32=thispars->pars[P_GTAB_R+color]; *pgamma32=thispars->pars[P_GTAB_R+color];
// Normally, nothing will be calculated in the next set_gamma_table() call // Normally, nothing will be calculated in the next set_gamma_table() call
rslt=set_gamma_table (gamma32.hash16, gamma32.scale, NULL, GAMMA_MODE_HARDWARE | GAMMA_MODE_LOCK, color); // frame16 - one ahead of the current rslt=set_gamma_table (gamma32.hash16,
gamma32.scale,
NULL,
GAMMA_MODE_HARDWARE | GAMMA_MODE_LOCK,
color,
sensor_port,
0); // frame16 - one ahead of the current TODO 393 multisensor - split gamma tables to subchannels
// now gtable will be old one if result <=0 get_gamma_fpga(color) can return 0 only if nothing yet was programmed // now gtable will be old one if result <=0 get_gamma_fpga(color) can return 0 only if nothing yet was programmed
if ((gtable= get_gamma_fpga(color))) fpga_table_write_nice (CX313_FPGA_TABLES_GAMMA + (color * 256), 256, gtable); if ((gtable= get_gamma_fpga(color))) fpga_table_write_nice (CX313_FPGA_TABLES_GAMMA + (color * 256), 256, gtable);
if (rslt <= 0) SETFRAMEPARS_SET(P_GTAB_R+color, get_locked_hash32(color)); // restore to the locked table if (rslt <= 0) SETFRAMEPARS_SET(P_GTAB_R+color, get_locked_hash32(color)); // restore to the locked table
......
This diff is collapsed.
This diff is collapsed.
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