Loading src/drivers/elphel/mt9f002.c +99 −23 Original line number Original line Diff line number Diff line Loading @@ -51,7 +51,7 @@ #include "sensor_i2c.h" #include "sensor_i2c.h" //#include "detect_sensors.h" //#include "detect_sensors.h" // hact timeout in udelay(100)s // hact timeout in udelay(100)s - for data lanes' phase adjustment #define HACT_TIMEOUT 8192 #define HACT_TIMEOUT 8192 /** /** Loading Loading @@ -131,7 +131,7 @@ void mt9f002_set_device(struct device *dev) // do nothing, now it has it's own d struct sensor_t mt9f002 = { struct sensor_t mt9f002 = { // sensor constants // sensor constants .imageWidth = 4384, ///< nominal image width for final images .imageWidth = 4384, ///< nominal image width for final images .imageHeight = 3288, ///< nominal image height for final images .imageHeight = 3280, ///< nominal image height for final images .clearWidth = 4608, ///< maximal clear image width .clearWidth = 4608, ///< maximal clear image width .clearHeight = 3288, ///< maximal clear image height; .clearHeight = 3288, ///< maximal clear image height; .clearTop = 32-MT9F002_VACT_DELAY, ///< top margin to the first clear pixel .clearTop = 32-MT9F002_VACT_DELAY, ///< top margin to the first clear pixel Loading Loading @@ -160,9 +160,9 @@ struct sensor_t mt9f002 = { .maxGain256 = 4064, ///< (15.875) maximal analog gain times 0x100 .maxGain256 = 4064, ///< (15.875) maximal analog gain times 0x100 .minGain256 = 384, ///< 1.5 times 0x100 .minGain256 = 384, ///< 1.5 times 0x100 .minClockFreq= 20000000, ///< Minimal clock frequency .minClockFreq= 200000000, ///< Minimal clock frequency .maxClockFreq= 24444000, ///< Maximal clock frequency .maxClockFreq= 240000000, ///< Maximal clock frequency .nomClockFreq= 24444000, ///< nominal clock frequency .nomClockFreq= 220000000, ///< nominal clock frequency .sensorType = SENSOR_MT9F002, ///< sensor type (for Elphel cameras) .sensorType = SENSOR_MT9F002, ///< sensor type (for Elphel cameras) .i2c_addr = MT9F002_I2C_ADDR, ///< sensor i2c slave address (7 bits) .i2c_addr = MT9F002_I2C_ADDR, ///< sensor i2c slave address (7 bits) Loading Loading @@ -584,7 +584,7 @@ int mt9f002_pgm_initsensor (int sensor_port, ///< sensor port // soft reset // soft reset // sa7 is not used // sa7 is not used X3X3_I2C_SEND2_LUT_ASAP(sensor_port,0,P_REG_MT9F002_RESET_REGISTER,MT9F002_RESET_REGISTER_VALUE); X3X3_I2C_SEND2_LUT_ASAP(sensor_port,0,P_REG_MT9F002_RESET_REGISTER,MT9F002_RESET_REGISTER_VALUE); // delay (needed?) // delay is not needed, however if bit[0]=1 then it is needed //udelay(100); //udelay(100); // sensor is supposed to be streaming by now // sensor is supposed to be streaming by now Loading Loading @@ -696,6 +696,22 @@ int mt9f002_calc_frame_length_lines(struct framepars_t * thispars){ return v0; return v0; } } int mt9f002_calc_frame_length_lines_2(int whs, int whe,struct framepars_t * thispars){ int v0; int y_addr_start = whs; int y_addr_end = whe; int min_frame_blanking_lines = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_FRAME_BLANKING_LINES]; // TODO: do int subsampling_factor = 1; v0 = (y_addr_end - y_addr_start + 1)/subsampling_factor + min_frame_blanking_lines; return v0; } // also defines horizontal blanking // also defines horizontal blanking int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ Loading @@ -712,7 +728,7 @@ int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ // does not match with the default value // does not match with the default value //v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]; //v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]; v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]-2; v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]; // typo in the datasheet formula? // typo in the datasheet formula? //v1 = (x_addr_end-x_addr_start+x_odd_inc)/(1+x_odd_inc)+min_line_blanking_pck; //v1 = (x_addr_end-x_addr_start+x_odd_inc)/(1+x_odd_inc)+min_line_blanking_pck; //v1 = ((x_addr_end-x_addr_start+x_odd_inc)*2/(1+x_odd_inc)+min_line_blanking_pck)/2; //v1 = ((x_addr_end-x_addr_start+x_odd_inc)*2/(1+x_odd_inc)+min_line_blanking_pck)/2; Loading @@ -723,12 +739,12 @@ int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ //pr_info("x_addr_end=0x%08x x_addr_start=0x%08x x_odd_inc=0x%08x min_line_blanking_pck=0x%08x\n",x_addr_end,x_addr_start,x_odd_inc,min_line_blanking_pck); //pr_info("x_addr_end=0x%08x x_addr_start=0x%08x x_odd_inc=0x%08x min_line_blanking_pck=0x%08x\n",x_addr_end,x_addr_start,x_odd_inc,min_line_blanking_pck); v2 = MT9F002_VT_PIX_CLK/MT9F002_OP_PIX_CLK*x_output_size/4 + 0x5E; v2 = MT9F002_VT_PIX_CLK/MT9F002_OP_PIX_CLK*x_output_size/4 + 0x5E; //pr_info("v0=0x%08x v1=0x%08x v2=0x%08x\n",v0,v1,v2); pr_info("v0=0x%08x v1=0x%08x v2=0x%08x\n",v0,v1,v2); if (v0<v1) v0 = v1; if (v0<v1) v0 = v1; if (v0<v2) v0 = v2; if (v0<v2) v0 = v2; //pr_info("result = 0x%08x\n",v0); pr_info("result = 0x%08x\n",v0); return v0; return v0; } } Loading Loading @@ -900,7 +916,7 @@ int mt9f002_pgm_window_common (int sensor_port, ///< sensor port // recalc something after this one? // recalc something after this one? fll = mt9f002_calc_frame_length_lines(thispars); fll = mt9f002_calc_frame_length_lines(thispars); pr_info("old fll=0x%08x, new fll=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],fll); //fll = mt9f002_calc_frame_length_lines_2(whs,whe,thispars); if (fll!=thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]){ if (fll!=thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]){ pr_info("old fll=0x%08x, new fll=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],fll); pr_info("old fll=0x%08x, new fll=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],fll); SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_FRAME_LENGTH_LINES, fll); SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_FRAME_LENGTH_LINES, fll); Loading Loading @@ -1160,6 +1176,7 @@ int mt9f002_pgm_limitfps (int sensor_port, ///< sensor port numb // schedule updating P_VIRT_HEIGHT if it changed // schedule updating P_VIRT_HEIGHT if it changed dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_VIRT_HEIGHT] =%d(0x%x), virt_height=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_VIRT_HEIGHT],(int)thispars->pars[P_VIRT_HEIGHT ],virt_height,virt_height); dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_VIRT_HEIGHT] =%d(0x%x), virt_height=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_VIRT_HEIGHT],(int)thispars->pars[P_VIRT_HEIGHT ],virt_height,virt_height); if (thispars->pars[P_VIRT_HEIGHT ] != virt_height) { if (thispars->pars[P_VIRT_HEIGHT ] != virt_height) { pr_info("setting virt_height to %d\n",virt_height); SETFRAMEPARS_SET(P_VIRT_HEIGHT, virt_height); SETFRAMEPARS_SET(P_VIRT_HEIGHT, virt_height); } } // schedule updating P_PERIOD if it changed // schedule updating P_PERIOD if it changed Loading @@ -1184,7 +1201,7 @@ int mt9f002_pgm_limitfps (int sensor_port, ///< sensor port numb // Update period from external trigger (assuming internal/self trigger, we do not know real external trigger period) // Update period from external trigger (assuming internal/self trigger, we do not know real external trigger period) //pix_period = compare_to_trig_period(pix_period,thispars); //pix_period = compare_to_trig_period(pix_period,thispars); sclk = MT9F002_VT_PIX_CLK; sclk = thispars->pars[P_CLK_SENSOR]; ull_fp1000s=((long long) 1000)* ((long long) sclk); ull_fp1000s=((long long) 1000)* ((long long) sclk); __div64_32(&ull_fp1000s,pix_period); __div64_32(&ull_fp1000s,pix_period); Loading @@ -1196,6 +1213,13 @@ int mt9f002_pgm_limitfps (int sensor_port, ///< sensor port numb if (thispars->pars[P_FP1000S] != fp1000s) { if (thispars->pars[P_FP1000S] != fp1000s) { SETFRAMEPARS_SET(P_FP1000S, fp1000s); SETFRAMEPARS_SET(P_FP1000S, fp1000s); } } // this sets the vertical blanking if (virt_height!=thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]){ pr_info("limit fps, old frame_length_lines=0x%08x, new frame_length_lines=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],virt_height); SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_FRAME_LENGTH_LINES, virt_height); } /* /* // schedule updating P_MT9X001_VERTBLANK sensor register and shadow // schedule updating P_MT9X001_VERTBLANK sensor register and shadow dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK] =%d(0x%x), vert_blank=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],vert_blank,vert_blank); dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK] =%d(0x%x), vert_blank=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],vert_blank,vert_blank); Loading Loading @@ -1236,10 +1260,13 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number int coarse_exposure; int coarse_exposure; int fine_exposure; int fine_exposure; int frame_length_lines = thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]; int line_length_pck = thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]; // vt_pix_clk // vt_pix_clk // TODO: Do not forget this - add those div registers?! // TODO: Do not forget this - add those div registers?! //int sclk = thispars->pars[P_CLK_SENSOR]*MT9F002_PLL_MULTIPLIER_VALUE*0x2/0x6/0x6; // pixel clock in Hz before PLL, but PLL setting is ~240MHz? //int sclk = thispars->pars[P_CLK_SENSOR]*MT9F002_PLL_MULTIPLIER_VALUE*0x2/0x6/0x6; // pixel clock in Hz before PLL, but PLL setting is ~240MHz? int sclk = MT9F002_VT_PIX_CLK;// = (thispars->pars[P_CLK_SENSOR]/0x6/0x6)*0x2*MT9F002_PLL_MULTIPLIER_VALUE; int sclk = thispars->pars[P_CLK_SENSOR];// = (thispars->pars[P_CLK_SENSOR]/0x6/0x6)*0x2*MT9F002_PLL_MULTIPLIER_VALUE; int vert_blank; int vert_blank; Loading @@ -1247,7 +1274,6 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number int row_time_in_pixels=thispars->pars[P_VIRT_WIDTH]; int row_time_in_pixels=thispars->pars[P_VIRT_WIDTH]; int pix_period; int pix_period; int line_length_pck; // wrong frame // wrong frame if (frame16 >= PARS_FRAMES) return -1; if (frame16 >= PARS_FRAMES) return -1; Loading @@ -1260,12 +1286,22 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number // else : use P_EXPOS // else : use P_EXPOS if ((video_exposure>0)&&(FRAMEPAR_MODIFIED(P_VEXPOS)||!(FRAMEPAR_MODIFIED(P_EXPOS)||FRAMEPAR_MODIFIED(P_VIRT_WIDTH)))) { if ((video_exposure>0)&&(FRAMEPAR_MODIFIED(P_VEXPOS)||!(FRAMEPAR_MODIFIED(P_EXPOS)||FRAMEPAR_MODIFIED(P_VIRT_WIDTH)))) { pr_info("using P_VEXPOS\n"); pr_info("using P_VEXPOS\n"); coarse_exposure = video_exposure; ull_exposure = ((long long)(video_exposure * line_length_pck)) * ((long long) 1000000); __div64_32(&ull_exposure,sclk); exposure = ull_exposure; }else{ }else{ pr_info("using P_EXPOS\n"); pr_info("using P_EXPOS\n"); // exposure is in microseconds // exposure is in microseconds exposure = thispars->pars[P_EXPOS]; exposure = thispars->pars[P_EXPOS]; line_length_pck = thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]; //line_length_pck = thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]; // always start with min line_length_pck for the current window line_length_pck = mt9f002_calc_line_length_pck(thispars); pr_info("exposure = 0x%08x, line_length_pck = 0x%08x\n",exposure,line_length_pck); pr_info("exposure = 0x%08x, line_length_pck = 0x%08x\n",exposure,line_length_pck); Loading @@ -1275,8 +1311,20 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number __div64_32(&ull_video_exposure,line_length_pck); __div64_32(&ull_video_exposure,line_length_pck); coarse_exposure = ull_video_exposure; coarse_exposure = ull_video_exposure; //frame_length_lines = thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]; pr_info("coarse exposure = 0x%08x vs 0x%08x = frame_length_lines \n",coarse_exposure,frame_length_lines); if (coarse_exposure>(frame_length_lines-1)){ pr_info("COARSE IS GREATER THAN FRAME LENGTH"); // set coarse to max coarse_exposure = frame_length_lines-1; ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; __div64_32(&ull_video_exposure,coarse_exposure); // extend line length line_length_pck = ull_video_exposure; } pr_info("coarse exposure = %d (0x%08x)\n",coarse_exposure,coarse_exposure); // at the same time the fine exposure will be: // at the same time the fine exposure will be: ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; Loading @@ -1287,10 +1335,36 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number } } if (exposure <1) exposure=1; if (exposure <1) exposure=1; if (video_exposure <1) video_exposure=1; if (coarse_exposure <1) coarse_exposure=1; // check against max shutter? // check against max shutter? // is exposure longer then maximal period (specified for constant fps? pix_period = line_length_pck*frame_length_lines; // IMPORTANT: inserted here by myself for testing //pix_period = compare_to_trig_period(sensor_port,pix_period,thispars); // 0x2 == keep frame rate // 0x1 == limit frame rate if (thispars->pars[P_FPSFLAGS] & 0x2) { if (pix_period > thispars->pars[P_PERIOD_MAX]) { // already done this?! coarse_exposure = frame_length_lines-1; ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; __div64_32(&ull_video_exposure,coarse_exposure); // extend line length line_length_pck = ull_video_exposure; } }else{ // update fps here SETFRAMEPARS_SET(P_PERIOD, pix_period); ull_fp1000s=((long long) 1000)* ((long long) sclk); __div64_32(&ull_fp1000s,pix_period); fp1000s= ull_fp1000s; if (thispars->pars[P_FP1000S] != fp1000s) { SETFRAMEPARS_SET(P_FP1000S, fp1000s); } } /* /* Loading Loading @@ -1434,6 +1508,10 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number sensor_port, sensor_port, frame16,(int) sensor->i2c_addr,(int)P_MT9F002_COARSE_INTEGRATION_TIME,(int)coarse_exposure); sensor_port, sensor_port, frame16,(int) sensor->i2c_addr,(int)P_MT9F002_COARSE_INTEGRATION_TIME,(int)coarse_exposure); } } if (line_length_pck != thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]){ SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_LINE_LENGTH_PCK, line_length_pck); } // fine integration time // fine integration time /* /* if (fine_exposure != thispars->pars[P_SENSOR_REGS+P_MT9F002_FINE_INTEGRATION_TIME]) { if (fine_exposure != thispars->pars[P_SENSOR_REGS+P_MT9F002_FINE_INTEGRATION_TIME]) { Loading @@ -1445,8 +1523,8 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to gains and sensor register shadows if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to gains and sensor register shadows dev_dbg(g_dev_ptr,"{%d} coarse exposure = %d (0x%x), fine exposure = %d (0x%x) OK!\n", dev_dbg(g_dev_ptr,"{%d} coarse exposure = %d (0x%x), line_length_pck = %d (0x%08x), fine exposure = %d (0x%x)\n", sensor_port, (int) coarse_exposure, (int) coarse_exposure, (int) fine_exposure, (int) fine_exposure); sensor_port, (int) coarse_exposure, (int) coarse_exposure, (int) line_length_pck, (int) line_length_pck, (int) fine_exposure, (int) fine_exposure); return 0; return 0; } } Loading Loading @@ -1636,8 +1714,6 @@ int mt9f002_pgm_gains (int sensor_port, ///< sensor port numb ///< @return 0 - OK, negative - error ///< @return 0 - OK, negative - error { { int reg; struct frameparspair_t pars_to_update[38]; // 22+12 needed struct frameparspair_t pars_to_update[38]; // 22+12 needed int nupdate=0; int nupdate=0; Loading src/drivers/elphel/mt9f002.h +7 −5 Original line number Original line Diff line number Diff line Loading @@ -21,7 +21,9 @@ #define MT9F002_I2C_ADDR 0x10 ///< MT9P I2C slave address (7 bit) #define MT9F002_I2C_ADDR 0x10 ///< MT9P I2C slave address (7 bit) // bit 9 should have set masking for broken frames // bit 9 should have set masking for broken frames #define MT9F002_RESET_REGISTER_VALUE 0x001c // cleared bit 3 allows writing to some RO registers //#define MT9F002_RESET_REGISTER_VALUE 0x001c #define MT9F002_RESET_REGISTER_VALUE 0x0014 // number of lines to sacrifice before generating Frame Valid // number of lines to sacrifice before generating Frame Valid #define MT9F002_VACT_DELAY 2 #define MT9F002_VACT_DELAY 2 Loading Loading @@ -58,7 +60,8 @@ // Sensor clock dividers and multiplier // Sensor clock dividers and multiplier // These should be calculated based on the clocks above // These should be calculated based on the clocks above // pll multiplier, default is 0xa5 (165), also tried 0xa2 (162) // pll multiplier, default is 0xa5 (165) for 24MHz // is set to 0xb4 (180) becuase clock is 22MHz (not 24) #define MT9F002_PLL_MULTIPLIER_VALUE 0xb4 #define MT9F002_PLL_MULTIPLIER_VALUE 0xb4 // pre_pll_clk_div (0x0304), default value is 0x6 // pre_pll_clk_div (0x0304), default value is 0x6 #define MT9F002_PRE_PLL_CLK_DIV_VALUE 0x6 #define MT9F002_PRE_PLL_CLK_DIV_VALUE 0x6 Loading @@ -68,13 +71,12 @@ #define MT9F002_VT_SYS_CLK_DIV_VALUE 0x1 #define MT9F002_VT_SYS_CLK_DIV_VALUE 0x1 // shift_vt_pix_clk_div, default value is 0x1 // shift_vt_pix_clk_div, default value is 0x1 #define MT9F002_SHIFT_VT_PIX_CLK_DIV 0x1 #define MT9F002_SHIFT_VT_PIX_CLK_DIV 0x1 // op_pix_clk divider #define MT9F002_OP_PIX_CLK_DIV 0xc // Coarse Integration Time Margin // Coarse Integration Time Margin #define MT9F002_COARSE_EXPOS_MARGIN 0x1 #define MT9F002_COARSE_EXPOS_MARGIN 0x1 /* ON Semi MT9F002 i2c register addresses */ /* ON Semi MT9F002 i2c register addresses */ /* /* Loading src/drivers/elphel/pgm_functions.c +15 −1 Original line number Original line Diff line number Diff line Loading @@ -512,7 +512,7 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( // Freqs for sensors // Freqs for sensors if ((thispars->pars[P_SENSOR]==0) && if ((thispars->pars[P_SENSOR]==0) && ((sens & SENSOR_MASK) == SENSOR_MT9F002)){ ((sens & SENSOR_MASK) == SENSOR_MT9F002)){ setFramePar(sensor_port, thispars, P_CLK_SENSOR, 24444000); setFramePar(sensor_port, thispars, P_CLK_SENSOR, MT9F002_VT_PIX_CLK); }else{ }else{ // this handles MT9x001 & MUX // this handles MT9x001 & MUX setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000); setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000); Loading Loading @@ -1335,6 +1335,7 @@ int pgm_limitfps (int sensor_port, ///< sensor port number (0..3 if (min_period != thispars->pars[P_PERIOD_MIN]) { if (min_period != thispars->pars[P_PERIOD_MIN]) { SETFRAMEPARS_SET(P_PERIOD_MIN, min_period); // set it (and propagate to the later frames) SETFRAMEPARS_SET(P_PERIOD_MIN, min_period); // set it (and propagate to the later frames) dev_dbg(g_dev_ptr,"{%d} SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", sensor_port, min_period); dev_dbg(g_dev_ptr,"{%d} SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", sensor_port, min_period); pr_info("{%d} min period got updated to 0x%x (clk_sensor=%d, clk_fpga=%d)\n", sensor_port, min_period,clk_sensor,clk_fpga); MDP(DBGB_PADD, sensor_port,"SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", min_period) MDP(DBGB_PADD, sensor_port,"SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", min_period) } } if (((thispars->pars[P_FPSFLAGS] & 2)==0) || (period < min_period)) period=0x7fffffff; // no upper limit if (((thispars->pars[P_FPSFLAGS] & 2)==0) || (period < min_period)) period=0x7fffffff; // no upper limit Loading Loading @@ -2225,6 +2226,19 @@ int pgm_memcompressor (int sensor_port, ///< sensor port number ( (cmprs_frame_format.num_macro_cols_m1+1)*(cmprs_frame_format.num_macro_rows_m1+1) (cmprs_frame_format.num_macro_cols_m1+1)*(cmprs_frame_format.num_macro_rows_m1+1) ); ); pr_info("PGM_MEMCOMPRESSOR: sport=%d width_bursts=%d width_marg=%d height_marg=%d num_macro_rows_m1=%d tile_width=%d tile_height=%d margin_left=%d margin_top=%d P_TILES=%d\n", sensor_port, width_bursts, width_marg, height_marg, (cmprs_frame_format.num_macro_rows_m1 + 1) << 4, tile_width, tile_height, 0, cmprs_top, (cmprs_frame_format.num_macro_cols_m1+1)*(cmprs_frame_format.num_macro_rows_m1+1) ); setup_compressor_memory (sensor_port, // sensor port number (0..3) setup_compressor_memory (sensor_port, // sensor port number (0..3) width_bursts, // 13-bit - in 8*16=128 bit bursts width_bursts, // 13-bit - in 8*16=128 bit bursts (cmprs_frame_format.num_macro_rows_m1 + 1) << 4, (cmprs_frame_format.num_macro_rows_m1 + 1) << 4, Loading Loading
src/drivers/elphel/mt9f002.c +99 −23 Original line number Original line Diff line number Diff line Loading @@ -51,7 +51,7 @@ #include "sensor_i2c.h" #include "sensor_i2c.h" //#include "detect_sensors.h" //#include "detect_sensors.h" // hact timeout in udelay(100)s // hact timeout in udelay(100)s - for data lanes' phase adjustment #define HACT_TIMEOUT 8192 #define HACT_TIMEOUT 8192 /** /** Loading Loading @@ -131,7 +131,7 @@ void mt9f002_set_device(struct device *dev) // do nothing, now it has it's own d struct sensor_t mt9f002 = { struct sensor_t mt9f002 = { // sensor constants // sensor constants .imageWidth = 4384, ///< nominal image width for final images .imageWidth = 4384, ///< nominal image width for final images .imageHeight = 3288, ///< nominal image height for final images .imageHeight = 3280, ///< nominal image height for final images .clearWidth = 4608, ///< maximal clear image width .clearWidth = 4608, ///< maximal clear image width .clearHeight = 3288, ///< maximal clear image height; .clearHeight = 3288, ///< maximal clear image height; .clearTop = 32-MT9F002_VACT_DELAY, ///< top margin to the first clear pixel .clearTop = 32-MT9F002_VACT_DELAY, ///< top margin to the first clear pixel Loading Loading @@ -160,9 +160,9 @@ struct sensor_t mt9f002 = { .maxGain256 = 4064, ///< (15.875) maximal analog gain times 0x100 .maxGain256 = 4064, ///< (15.875) maximal analog gain times 0x100 .minGain256 = 384, ///< 1.5 times 0x100 .minGain256 = 384, ///< 1.5 times 0x100 .minClockFreq= 20000000, ///< Minimal clock frequency .minClockFreq= 200000000, ///< Minimal clock frequency .maxClockFreq= 24444000, ///< Maximal clock frequency .maxClockFreq= 240000000, ///< Maximal clock frequency .nomClockFreq= 24444000, ///< nominal clock frequency .nomClockFreq= 220000000, ///< nominal clock frequency .sensorType = SENSOR_MT9F002, ///< sensor type (for Elphel cameras) .sensorType = SENSOR_MT9F002, ///< sensor type (for Elphel cameras) .i2c_addr = MT9F002_I2C_ADDR, ///< sensor i2c slave address (7 bits) .i2c_addr = MT9F002_I2C_ADDR, ///< sensor i2c slave address (7 bits) Loading Loading @@ -584,7 +584,7 @@ int mt9f002_pgm_initsensor (int sensor_port, ///< sensor port // soft reset // soft reset // sa7 is not used // sa7 is not used X3X3_I2C_SEND2_LUT_ASAP(sensor_port,0,P_REG_MT9F002_RESET_REGISTER,MT9F002_RESET_REGISTER_VALUE); X3X3_I2C_SEND2_LUT_ASAP(sensor_port,0,P_REG_MT9F002_RESET_REGISTER,MT9F002_RESET_REGISTER_VALUE); // delay (needed?) // delay is not needed, however if bit[0]=1 then it is needed //udelay(100); //udelay(100); // sensor is supposed to be streaming by now // sensor is supposed to be streaming by now Loading Loading @@ -696,6 +696,22 @@ int mt9f002_calc_frame_length_lines(struct framepars_t * thispars){ return v0; return v0; } } int mt9f002_calc_frame_length_lines_2(int whs, int whe,struct framepars_t * thispars){ int v0; int y_addr_start = whs; int y_addr_end = whe; int min_frame_blanking_lines = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_FRAME_BLANKING_LINES]; // TODO: do int subsampling_factor = 1; v0 = (y_addr_end - y_addr_start + 1)/subsampling_factor + min_frame_blanking_lines; return v0; } // also defines horizontal blanking // also defines horizontal blanking int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ Loading @@ -712,7 +728,7 @@ int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ // does not match with the default value // does not match with the default value //v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]; //v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]; v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]-2; v0 = thispars->pars[P_SENSOR_REGS+P_MT9F002_MIN_LINE_LENGTH_PCK]; // typo in the datasheet formula? // typo in the datasheet formula? //v1 = (x_addr_end-x_addr_start+x_odd_inc)/(1+x_odd_inc)+min_line_blanking_pck; //v1 = (x_addr_end-x_addr_start+x_odd_inc)/(1+x_odd_inc)+min_line_blanking_pck; //v1 = ((x_addr_end-x_addr_start+x_odd_inc)*2/(1+x_odd_inc)+min_line_blanking_pck)/2; //v1 = ((x_addr_end-x_addr_start+x_odd_inc)*2/(1+x_odd_inc)+min_line_blanking_pck)/2; Loading @@ -723,12 +739,12 @@ int mt9f002_calc_line_length_pck(struct framepars_t * thispars){ //pr_info("x_addr_end=0x%08x x_addr_start=0x%08x x_odd_inc=0x%08x min_line_blanking_pck=0x%08x\n",x_addr_end,x_addr_start,x_odd_inc,min_line_blanking_pck); //pr_info("x_addr_end=0x%08x x_addr_start=0x%08x x_odd_inc=0x%08x min_line_blanking_pck=0x%08x\n",x_addr_end,x_addr_start,x_odd_inc,min_line_blanking_pck); v2 = MT9F002_VT_PIX_CLK/MT9F002_OP_PIX_CLK*x_output_size/4 + 0x5E; v2 = MT9F002_VT_PIX_CLK/MT9F002_OP_PIX_CLK*x_output_size/4 + 0x5E; //pr_info("v0=0x%08x v1=0x%08x v2=0x%08x\n",v0,v1,v2); pr_info("v0=0x%08x v1=0x%08x v2=0x%08x\n",v0,v1,v2); if (v0<v1) v0 = v1; if (v0<v1) v0 = v1; if (v0<v2) v0 = v2; if (v0<v2) v0 = v2; //pr_info("result = 0x%08x\n",v0); pr_info("result = 0x%08x\n",v0); return v0; return v0; } } Loading Loading @@ -900,7 +916,7 @@ int mt9f002_pgm_window_common (int sensor_port, ///< sensor port // recalc something after this one? // recalc something after this one? fll = mt9f002_calc_frame_length_lines(thispars); fll = mt9f002_calc_frame_length_lines(thispars); pr_info("old fll=0x%08x, new fll=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],fll); //fll = mt9f002_calc_frame_length_lines_2(whs,whe,thispars); if (fll!=thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]){ if (fll!=thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]){ pr_info("old fll=0x%08x, new fll=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],fll); pr_info("old fll=0x%08x, new fll=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],fll); SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_FRAME_LENGTH_LINES, fll); SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_FRAME_LENGTH_LINES, fll); Loading Loading @@ -1160,6 +1176,7 @@ int mt9f002_pgm_limitfps (int sensor_port, ///< sensor port numb // schedule updating P_VIRT_HEIGHT if it changed // schedule updating P_VIRT_HEIGHT if it changed dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_VIRT_HEIGHT] =%d(0x%x), virt_height=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_VIRT_HEIGHT],(int)thispars->pars[P_VIRT_HEIGHT ],virt_height,virt_height); dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_VIRT_HEIGHT] =%d(0x%x), virt_height=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_VIRT_HEIGHT],(int)thispars->pars[P_VIRT_HEIGHT ],virt_height,virt_height); if (thispars->pars[P_VIRT_HEIGHT ] != virt_height) { if (thispars->pars[P_VIRT_HEIGHT ] != virt_height) { pr_info("setting virt_height to %d\n",virt_height); SETFRAMEPARS_SET(P_VIRT_HEIGHT, virt_height); SETFRAMEPARS_SET(P_VIRT_HEIGHT, virt_height); } } // schedule updating P_PERIOD if it changed // schedule updating P_PERIOD if it changed Loading @@ -1184,7 +1201,7 @@ int mt9f002_pgm_limitfps (int sensor_port, ///< sensor port numb // Update period from external trigger (assuming internal/self trigger, we do not know real external trigger period) // Update period from external trigger (assuming internal/self trigger, we do not know real external trigger period) //pix_period = compare_to_trig_period(pix_period,thispars); //pix_period = compare_to_trig_period(pix_period,thispars); sclk = MT9F002_VT_PIX_CLK; sclk = thispars->pars[P_CLK_SENSOR]; ull_fp1000s=((long long) 1000)* ((long long) sclk); ull_fp1000s=((long long) 1000)* ((long long) sclk); __div64_32(&ull_fp1000s,pix_period); __div64_32(&ull_fp1000s,pix_period); Loading @@ -1196,6 +1213,13 @@ int mt9f002_pgm_limitfps (int sensor_port, ///< sensor port numb if (thispars->pars[P_FP1000S] != fp1000s) { if (thispars->pars[P_FP1000S] != fp1000s) { SETFRAMEPARS_SET(P_FP1000S, fp1000s); SETFRAMEPARS_SET(P_FP1000S, fp1000s); } } // this sets the vertical blanking if (virt_height!=thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]){ pr_info("limit fps, old frame_length_lines=0x%08x, new frame_length_lines=0x%08x\n",thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES],virt_height); SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_FRAME_LENGTH_LINES, virt_height); } /* /* // schedule updating P_MT9X001_VERTBLANK sensor register and shadow // schedule updating P_MT9X001_VERTBLANK sensor register and shadow dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK] =%d(0x%x), vert_blank=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],vert_blank,vert_blank); dev_dbg(g_dev_ptr,"{%d} thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK] =%d(0x%x), vert_blank=%d(0x%x)\n",sensor_port,(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],(int)thispars->pars[P_SENSOR_REGS+P_MT9X001_VERTBLANK],vert_blank,vert_blank); Loading Loading @@ -1236,10 +1260,13 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number int coarse_exposure; int coarse_exposure; int fine_exposure; int fine_exposure; int frame_length_lines = thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]; int line_length_pck = thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]; // vt_pix_clk // vt_pix_clk // TODO: Do not forget this - add those div registers?! // TODO: Do not forget this - add those div registers?! //int sclk = thispars->pars[P_CLK_SENSOR]*MT9F002_PLL_MULTIPLIER_VALUE*0x2/0x6/0x6; // pixel clock in Hz before PLL, but PLL setting is ~240MHz? //int sclk = thispars->pars[P_CLK_SENSOR]*MT9F002_PLL_MULTIPLIER_VALUE*0x2/0x6/0x6; // pixel clock in Hz before PLL, but PLL setting is ~240MHz? int sclk = MT9F002_VT_PIX_CLK;// = (thispars->pars[P_CLK_SENSOR]/0x6/0x6)*0x2*MT9F002_PLL_MULTIPLIER_VALUE; int sclk = thispars->pars[P_CLK_SENSOR];// = (thispars->pars[P_CLK_SENSOR]/0x6/0x6)*0x2*MT9F002_PLL_MULTIPLIER_VALUE; int vert_blank; int vert_blank; Loading @@ -1247,7 +1274,6 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number int row_time_in_pixels=thispars->pars[P_VIRT_WIDTH]; int row_time_in_pixels=thispars->pars[P_VIRT_WIDTH]; int pix_period; int pix_period; int line_length_pck; // wrong frame // wrong frame if (frame16 >= PARS_FRAMES) return -1; if (frame16 >= PARS_FRAMES) return -1; Loading @@ -1260,12 +1286,22 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number // else : use P_EXPOS // else : use P_EXPOS if ((video_exposure>0)&&(FRAMEPAR_MODIFIED(P_VEXPOS)||!(FRAMEPAR_MODIFIED(P_EXPOS)||FRAMEPAR_MODIFIED(P_VIRT_WIDTH)))) { if ((video_exposure>0)&&(FRAMEPAR_MODIFIED(P_VEXPOS)||!(FRAMEPAR_MODIFIED(P_EXPOS)||FRAMEPAR_MODIFIED(P_VIRT_WIDTH)))) { pr_info("using P_VEXPOS\n"); pr_info("using P_VEXPOS\n"); coarse_exposure = video_exposure; ull_exposure = ((long long)(video_exposure * line_length_pck)) * ((long long) 1000000); __div64_32(&ull_exposure,sclk); exposure = ull_exposure; }else{ }else{ pr_info("using P_EXPOS\n"); pr_info("using P_EXPOS\n"); // exposure is in microseconds // exposure is in microseconds exposure = thispars->pars[P_EXPOS]; exposure = thispars->pars[P_EXPOS]; line_length_pck = thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]; //line_length_pck = thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]; // always start with min line_length_pck for the current window line_length_pck = mt9f002_calc_line_length_pck(thispars); pr_info("exposure = 0x%08x, line_length_pck = 0x%08x\n",exposure,line_length_pck); pr_info("exposure = 0x%08x, line_length_pck = 0x%08x\n",exposure,line_length_pck); Loading @@ -1275,8 +1311,20 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number __div64_32(&ull_video_exposure,line_length_pck); __div64_32(&ull_video_exposure,line_length_pck); coarse_exposure = ull_video_exposure; coarse_exposure = ull_video_exposure; //frame_length_lines = thispars->pars[P_SENSOR_REGS+P_MT9F002_FRAME_LENGTH_LINES]; pr_info("coarse exposure = 0x%08x vs 0x%08x = frame_length_lines \n",coarse_exposure,frame_length_lines); if (coarse_exposure>(frame_length_lines-1)){ pr_info("COARSE IS GREATER THAN FRAME LENGTH"); // set coarse to max coarse_exposure = frame_length_lines-1; ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; __div64_32(&ull_video_exposure,coarse_exposure); // extend line length line_length_pck = ull_video_exposure; } pr_info("coarse exposure = %d (0x%08x)\n",coarse_exposure,coarse_exposure); // at the same time the fine exposure will be: // at the same time the fine exposure will be: ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; Loading @@ -1287,10 +1335,36 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number } } if (exposure <1) exposure=1; if (exposure <1) exposure=1; if (video_exposure <1) video_exposure=1; if (coarse_exposure <1) coarse_exposure=1; // check against max shutter? // check against max shutter? // is exposure longer then maximal period (specified for constant fps? pix_period = line_length_pck*frame_length_lines; // IMPORTANT: inserted here by myself for testing //pix_period = compare_to_trig_period(sensor_port,pix_period,thispars); // 0x2 == keep frame rate // 0x1 == limit frame rate if (thispars->pars[P_FPSFLAGS] & 0x2) { if (pix_period > thispars->pars[P_PERIOD_MAX]) { // already done this?! coarse_exposure = frame_length_lines-1; ull_video_exposure = (long long) (sclk / 1000000) * (long long) exposure; __div64_32(&ull_video_exposure,coarse_exposure); // extend line length line_length_pck = ull_video_exposure; } }else{ // update fps here SETFRAMEPARS_SET(P_PERIOD, pix_period); ull_fp1000s=((long long) 1000)* ((long long) sclk); __div64_32(&ull_fp1000s,pix_period); fp1000s= ull_fp1000s; if (thispars->pars[P_FP1000S] != fp1000s) { SETFRAMEPARS_SET(P_FP1000S, fp1000s); } } /* /* Loading Loading @@ -1434,6 +1508,10 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number sensor_port, sensor_port, frame16,(int) sensor->i2c_addr,(int)P_MT9F002_COARSE_INTEGRATION_TIME,(int)coarse_exposure); sensor_port, sensor_port, frame16,(int) sensor->i2c_addr,(int)P_MT9F002_COARSE_INTEGRATION_TIME,(int)coarse_exposure); } } if (line_length_pck != thispars->pars[P_SENSOR_REGS+P_MT9F002_LINE_LENGTH_PCK]){ SET_SENSOR_MBPAR_LUT(sensor_port, frame16, P_MT9F002_LINE_LENGTH_PCK, line_length_pck); } // fine integration time // fine integration time /* /* if (fine_exposure != thispars->pars[P_SENSOR_REGS+P_MT9F002_FINE_INTEGRATION_TIME]) { if (fine_exposure != thispars->pars[P_SENSOR_REGS+P_MT9F002_FINE_INTEGRATION_TIME]) { Loading @@ -1445,8 +1523,8 @@ int mt9f002_pgm_exposure (int sensor_port, ///< sensor port number if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to gains and sensor register shadows if (nupdate) setFramePars(sensor_port,thispars, nupdate, pars_to_update); // save changes to gains and sensor register shadows dev_dbg(g_dev_ptr,"{%d} coarse exposure = %d (0x%x), fine exposure = %d (0x%x) OK!\n", dev_dbg(g_dev_ptr,"{%d} coarse exposure = %d (0x%x), line_length_pck = %d (0x%08x), fine exposure = %d (0x%x)\n", sensor_port, (int) coarse_exposure, (int) coarse_exposure, (int) fine_exposure, (int) fine_exposure); sensor_port, (int) coarse_exposure, (int) coarse_exposure, (int) line_length_pck, (int) line_length_pck, (int) fine_exposure, (int) fine_exposure); return 0; return 0; } } Loading Loading @@ -1636,8 +1714,6 @@ int mt9f002_pgm_gains (int sensor_port, ///< sensor port numb ///< @return 0 - OK, negative - error ///< @return 0 - OK, negative - error { { int reg; struct frameparspair_t pars_to_update[38]; // 22+12 needed struct frameparspair_t pars_to_update[38]; // 22+12 needed int nupdate=0; int nupdate=0; Loading
src/drivers/elphel/mt9f002.h +7 −5 Original line number Original line Diff line number Diff line Loading @@ -21,7 +21,9 @@ #define MT9F002_I2C_ADDR 0x10 ///< MT9P I2C slave address (7 bit) #define MT9F002_I2C_ADDR 0x10 ///< MT9P I2C slave address (7 bit) // bit 9 should have set masking for broken frames // bit 9 should have set masking for broken frames #define MT9F002_RESET_REGISTER_VALUE 0x001c // cleared bit 3 allows writing to some RO registers //#define MT9F002_RESET_REGISTER_VALUE 0x001c #define MT9F002_RESET_REGISTER_VALUE 0x0014 // number of lines to sacrifice before generating Frame Valid // number of lines to sacrifice before generating Frame Valid #define MT9F002_VACT_DELAY 2 #define MT9F002_VACT_DELAY 2 Loading Loading @@ -58,7 +60,8 @@ // Sensor clock dividers and multiplier // Sensor clock dividers and multiplier // These should be calculated based on the clocks above // These should be calculated based on the clocks above // pll multiplier, default is 0xa5 (165), also tried 0xa2 (162) // pll multiplier, default is 0xa5 (165) for 24MHz // is set to 0xb4 (180) becuase clock is 22MHz (not 24) #define MT9F002_PLL_MULTIPLIER_VALUE 0xb4 #define MT9F002_PLL_MULTIPLIER_VALUE 0xb4 // pre_pll_clk_div (0x0304), default value is 0x6 // pre_pll_clk_div (0x0304), default value is 0x6 #define MT9F002_PRE_PLL_CLK_DIV_VALUE 0x6 #define MT9F002_PRE_PLL_CLK_DIV_VALUE 0x6 Loading @@ -68,13 +71,12 @@ #define MT9F002_VT_SYS_CLK_DIV_VALUE 0x1 #define MT9F002_VT_SYS_CLK_DIV_VALUE 0x1 // shift_vt_pix_clk_div, default value is 0x1 // shift_vt_pix_clk_div, default value is 0x1 #define MT9F002_SHIFT_VT_PIX_CLK_DIV 0x1 #define MT9F002_SHIFT_VT_PIX_CLK_DIV 0x1 // op_pix_clk divider #define MT9F002_OP_PIX_CLK_DIV 0xc // Coarse Integration Time Margin // Coarse Integration Time Margin #define MT9F002_COARSE_EXPOS_MARGIN 0x1 #define MT9F002_COARSE_EXPOS_MARGIN 0x1 /* ON Semi MT9F002 i2c register addresses */ /* ON Semi MT9F002 i2c register addresses */ /* /* Loading
src/drivers/elphel/pgm_functions.c +15 −1 Original line number Original line Diff line number Diff line Loading @@ -512,7 +512,7 @@ int pgm_detectsensor (int sensor_port, ///< sensor port number ( // Freqs for sensors // Freqs for sensors if ((thispars->pars[P_SENSOR]==0) && if ((thispars->pars[P_SENSOR]==0) && ((sens & SENSOR_MASK) == SENSOR_MT9F002)){ ((sens & SENSOR_MASK) == SENSOR_MT9F002)){ setFramePar(sensor_port, thispars, P_CLK_SENSOR, 24444000); setFramePar(sensor_port, thispars, P_CLK_SENSOR, MT9F002_VT_PIX_CLK); }else{ }else{ // this handles MT9x001 & MUX // this handles MT9x001 & MUX setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000); setFramePar(sensor_port, thispars, P_CLK_SENSOR, 48000000); Loading Loading @@ -1335,6 +1335,7 @@ int pgm_limitfps (int sensor_port, ///< sensor port number (0..3 if (min_period != thispars->pars[P_PERIOD_MIN]) { if (min_period != thispars->pars[P_PERIOD_MIN]) { SETFRAMEPARS_SET(P_PERIOD_MIN, min_period); // set it (and propagate to the later frames) SETFRAMEPARS_SET(P_PERIOD_MIN, min_period); // set it (and propagate to the later frames) dev_dbg(g_dev_ptr,"{%d} SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", sensor_port, min_period); dev_dbg(g_dev_ptr,"{%d} SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", sensor_port, min_period); pr_info("{%d} min period got updated to 0x%x (clk_sensor=%d, clk_fpga=%d)\n", sensor_port, min_period,clk_sensor,clk_fpga); MDP(DBGB_PADD, sensor_port,"SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", min_period) MDP(DBGB_PADD, sensor_port,"SETFRAMEPARS_SET(P_PERIOD_MIN, 0x%x)\n", min_period) } } if (((thispars->pars[P_FPSFLAGS] & 2)==0) || (period < min_period)) period=0x7fffffff; // no upper limit if (((thispars->pars[P_FPSFLAGS] & 2)==0) || (period < min_period)) period=0x7fffffff; // no upper limit Loading Loading @@ -2225,6 +2226,19 @@ int pgm_memcompressor (int sensor_port, ///< sensor port number ( (cmprs_frame_format.num_macro_cols_m1+1)*(cmprs_frame_format.num_macro_rows_m1+1) (cmprs_frame_format.num_macro_cols_m1+1)*(cmprs_frame_format.num_macro_rows_m1+1) ); ); pr_info("PGM_MEMCOMPRESSOR: sport=%d width_bursts=%d width_marg=%d height_marg=%d num_macro_rows_m1=%d tile_width=%d tile_height=%d margin_left=%d margin_top=%d P_TILES=%d\n", sensor_port, width_bursts, width_marg, height_marg, (cmprs_frame_format.num_macro_rows_m1 + 1) << 4, tile_width, tile_height, 0, cmprs_top, (cmprs_frame_format.num_macro_cols_m1+1)*(cmprs_frame_format.num_macro_rows_m1+1) ); setup_compressor_memory (sensor_port, // sensor port number (0..3) setup_compressor_memory (sensor_port, // sensor port number (0..3) width_bursts, // 13-bit - in 8*16=128 bit bursts width_bursts, // 13-bit - in 8*16=128 bit bursts (cmprs_frame_format.num_macro_rows_m1 + 1) << 4, (cmprs_frame_format.num_macro_rows_m1 + 1) << 4, Loading