From c31eb26d1e5e934e38c107c36f81f71e13e62f9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Voltz?= Date: Sun, 5 Jun 2011 08:25:56 +0200 Subject: [PATCH] LiDE 200 almost OK - 1200 dpi scans hang after calibration - 4800 dpi shding data is incorrect - move to scan area needs tuning --- backend/genesys.c | 106 +++++++++++++++++++------------------- backend/genesys_devices.c | 2 +- backend/genesys_gl124.c | 7 --- backend/genesys_gl847.c | 83 +++++++++++++++++++---------- backend/genesys_gl847.h | 4 ++ backend/genesys_low.c | 28 +++++++--- 6 files changed, 135 insertions(+), 95 deletions(-) diff --git a/backend/genesys.c b/backend/genesys.c index c129626bd..0b4879d09 100644 --- a/backend/genesys.c +++ b/backend/genesys.c @@ -3314,10 +3314,11 @@ genesys_restore_calibration (Genesys_Device * dev) if (status == SANE_STATUS_GOOD) { memcpy (&dev->frontend, &cache->frontend, sizeof (dev->frontend)); - /* don't restore the gamma fields */ - memcpy (&dev->sensor, &cache->sensor, - offsetof (Genesys_Sensor, red_gamma)); - + /* we don't restore the gamma fields */ + /* XXX STEF XXX + memcpy (&dev->sensor, &cache->sensor, offsetof (Genesys_Sensor, red_gamma)); + */ + memcpy (dev->sensor.regs_0x10_0x1d, cache->sensor.regs_0x10_0x1d, 6); free (dev->dark_average_data); free (dev->white_average_data); @@ -3425,11 +3426,11 @@ genesys_save_calibration (Genesys_Device * dev) } else { - cache = malloc (sizeof (*cache)); + cache = malloc (sizeof (Genesys_Calibration_Cache)); if (!cache) return SANE_STATUS_NO_MEM; - memset (cache, 0, sizeof (*cache)); + memset (cache, 0, sizeof (Genesys_Calibration_Cache)); cache->next = dev->calibration_cache; dev->calibration_cache = cache; @@ -5237,7 +5238,7 @@ genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination, { if (!(dev->model->flags & GENESYS_FLAG_SIS_SENSOR)) fprintf (rawfile, - "P%c\n%d %d\n%d\n", + "P%c\n%05d %05d\n%d\n", dev->current_setup.channels == 1 ? (dev->current_setup.depth == 1 ? '4' : '5') : '6', dev->current_setup.pixels, @@ -5246,7 +5247,7 @@ genesys_read_ordered_data (Genesys_Device * dev, SANE_Byte * destination, else { fprintf (rawfile, - "P5\n%d %d\n%d\n", + "P5\n%05d %05d\n%d\n", (dev->sensor.sensor_pixels*3*dev->settings.xres)/dev->sensor.optical_res, dev->current_setup.lines, (1 << dev->current_setup.depth) - 1); @@ -6640,28 +6641,34 @@ probe_genesys_devices (void) return status; } -/* this should be changed if one of the substructures of +/** + * This should be changed if one of the substructures of Genesys_Calibration_Cache change, but it must be changed if there are changes that don't change size -- at least for now, as we store most of Genesys_Calibration_Cache as is. */ #define CALIBRATION_VERSION 1 -static void -read_calibration (Genesys_Device * dev) +/** + * reads previously cached calibration data + * from file + */ +SANE_Status +sanei_genesys_read_calibration (Genesys_Device * dev) { FILE *fp; uint8_t vers = 0; uint32_t size = 0; struct Genesys_Calibration_Cache *cache; + SANE_Status status=SANE_STATUS_GOOD; - DBG (DBG_proc, "read_calibration: enter\n"); + DBG (DBG_proc, "sanei_genesys_read_calibration: enter\n"); fp = fopen (dev->calib_file, "rb"); if (!fp) { DBG (DBG_info, "Calibration: Cannot open %s\n", dev->calib_file); - DBG (DBG_proc, "read_calibration: exit\n"); - return; + DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n"); + return SANE_STATUS_IO_ERROR; } /* these two checks ensure that most bad things cannot happen */ @@ -6670,8 +6677,8 @@ read_calibration (Genesys_Device * dev) { DBG (DBG_info, "Calibration: Bad version\n"); fclose (fp); - DBG (DBG_proc, "read_calibration: exit\n"); - return; + DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n"); + return SANE_STATUS_INVAL; } fread (&size, 4, 1, fp); if (size != sizeof (struct Genesys_Calibration_Cache)) @@ -6679,19 +6686,19 @@ read_calibration (Genesys_Device * dev) DBG (DBG_info, "Calibration: Size of calibration cache struct differs\n"); fclose (fp); - DBG (DBG_proc, "read_calibration: exit\n"); - return; + DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n"); + return SANE_STATUS_INVAL; } - while (!feof (fp)) + while (!feof (fp) && status==SANE_STATUS_GOOD) { - DBG (DBG_info, "read_calibration: reading one record\n"); + DBG (DBG_info, "sanei_genesys_read_calibration: reading one record\n"); cache = (struct Genesys_Calibration_Cache *) malloc (sizeof (*cache)); if (!cache) { DBG (DBG_error, - "read_calibration: could not allocate cache struct\n"); + "sanei_genesys_read_calibration: could not allocate cache struct\n"); break; } @@ -6701,7 +6708,8 @@ read_calibration (Genesys_Device * dev) if ((x) < 1) \ { \ free(cache); \ - DBG (DBG_warn, "read_calibration: partial calibration record\n"); \ + DBG (DBG_warn, "sanei_genesys_read_calibration: partial calibration record\n"); \ + status=SANE_STATUS_EOF; \ break; \ } \ } while(0) @@ -6710,49 +6718,35 @@ read_calibration (Genesys_Device * dev) if (fread (&cache->used_setup, sizeof (cache->used_setup), 1, fp) < 1) { /* eof is only detected here */ free (cache); + status=SANE_STATUS_GOOD; break; } - BILT1 (fread - (&cache->last_calibration, sizeof (cache->last_calibration), 1, - fp)); + BILT1 (fread (&cache->last_calibration, sizeof (cache->last_calibration), 1, fp)); BILT1 (fread (&cache->frontend, sizeof (cache->frontend), 1, fp)); /* the gamma (and later) fields are not stored */ - BILT1 (fread - (&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp)); - BILT1 (fread - (&cache->calib_pixels, sizeof (cache->calib_pixels), 1, fp)); - BILT1 (fread - (&cache->calib_channels, sizeof (cache->calib_channels), 1, fp)); - BILT1 (fread - (&cache->average_size, sizeof (cache->average_size), 1, fp)); - - /* Make sure we don't do bad things if someone feeds us a forged/ - sufficiently corrupted calibration file. - gl843 can do up to 0x5800 pixels. add some slack for the - dummy/blank pixel mess */ - if (cache->average_size > 0x5800 * 2 * 3 * 2 + 0x100) - { - DBG (DBG_error, "read_calibration: bad size of calibration data\n"); - free (cache); - break; - } + BILT1 (fread (&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp)); + BILT1 (fread (&cache->calib_pixels, sizeof (cache->calib_pixels), 1, fp)); + BILT1 (fread (&cache->calib_channels, sizeof (cache->calib_channels), 1, fp)); + BILT1 (fread (&cache->average_size, sizeof (cache->average_size), 1, fp)); cache->white_average_data = (uint8_t *) malloc (cache->average_size); cache->dark_average_data = (uint8_t *) malloc (cache->average_size); if (!cache->white_average_data || !cache->dark_average_data) { + status=SANE_STATUS_NO_MEM; FREE_IFNOT_NULL (cache->white_average_data); FREE_IFNOT_NULL (cache->dark_average_data); free (cache); DBG (DBG_error, - "read_calibration: could not allocate space for average data\n"); + "sanei_genesys_read_calibration: could not allocate space for average data\n"); break; } if (fread (cache->white_average_data, cache->average_size, 1, fp) < 1) { - DBG (DBG_warn, "read_calibration: partial calibration record\n"); + status=SANE_STATUS_EOF; + DBG (DBG_warn, "sanei_genesys_read_calibration: partial calibration record\n"); free (cache->white_average_data); free (cache->dark_average_data); free (cache); @@ -6760,20 +6754,22 @@ read_calibration (Genesys_Device * dev) } if (fread (cache->dark_average_data, cache->average_size, 1, fp) < 1) { - DBG (DBG_warn, "read_calibration: partial calibration record\n"); + DBG (DBG_warn, "sanei_genesys_read_calibration: partial calibration record\n"); free (cache->white_average_data); free (cache->dark_average_data); free (cache); + status=SANE_STATUS_EOF; break; } #undef BILT1 - DBG (DBG_info, "read_calibration: adding record to list\n"); + DBG (DBG_info, "sanei_genesys_read_calibration: adding record to list\n"); cache->next = dev->calibration_cache; dev->calibration_cache = cache; } fclose (fp); - DBG (DBG_proc, "read_calibration: exit\n"); + DBG (DBG_proc, "sanei_genesys_read_calibration: exit\n"); + return status; } static void @@ -6783,10 +6779,12 @@ write_calibration (Genesys_Device * dev) uint8_t vers = 0; uint32_t size = 0; struct Genesys_Calibration_Cache *cache; + + DBGSTART; fp = fopen (dev->calib_file, "wb"); if (!fp) { - DBG (DBG_info, "Calibration: Cannot open %s\n", dev->calib_file); + DBG (DBG_info, "write_calibration: Cannot open %s for writing\n", dev->calib_file); return; } @@ -6798,18 +6796,18 @@ write_calibration (Genesys_Device * dev) for (cache = dev->calibration_cache; cache; cache = cache->next) { fwrite (&cache->used_setup, sizeof (cache->used_setup), 1, fp); - fwrite (&cache->last_calibration, sizeof (cache->last_calibration), 1, - fp); + fwrite (&cache->last_calibration, sizeof (cache->last_calibration), 1, fp); fwrite (&cache->frontend, sizeof (cache->frontend), 1, fp); /* the gamma (and later) fields are not stored */ fwrite (&cache->sensor, offsetof (Genesys_Sensor, red_gamma), 1, fp); + fwrite (&cache->calib_pixels, sizeof (cache->calib_pixels), 1, fp); fwrite (&cache->calib_channels, sizeof (cache->calib_channels), 1, fp); fwrite (&cache->average_size, sizeof (cache->average_size), 1, fp); fwrite (cache->white_average_data, cache->average_size, 1, fp); fwrite (cache->dark_average_data, cache->average_size, 1, fp); } - + DBGCOMPLETED; fclose (fp); } @@ -7182,7 +7180,7 @@ sane_open (SANE_String_Const devicename, SANE_Handle * handle) /* now open file, fetch calibration records */ - read_calibration (s->dev); + sanei_genesys_read_calibration (s->dev); DBG (DBG_proc, "sane_open: exit\n"); return SANE_STATUS_GOOD; diff --git a/backend/genesys_devices.c b/backend/genesys_devices.c index 4d39981db..6456b721c 100644 --- a/backend/genesys_devices.c +++ b/backend/genesys_devices.c @@ -1565,7 +1565,7 @@ static Genesys_Model canon_lide_200_model = { | GENESYS_FLAG_DARK_CALIBRATION | GENESYS_FLAG_CUSTOM_GAMMA, GENESYS_HAS_SCAN_SW | GENESYS_HAS_COPY_SW | GENESYS_HAS_EMAIL_SW | GENESYS_HAS_FILE_SW, - 60, + 40, 400 }; diff --git a/backend/genesys_gl124.c b/backend/genesys_gl124.c index 38f8ab4d1..fc67e17fb 100644 --- a/backend/genesys_gl124.c +++ b/backend/genesys_gl124.c @@ -2753,13 +2753,6 @@ gl124_init_regs_for_scan (Genesys_Device * dev) } move=0; } - else - { - if(channels==1) - { - move-=0; - } - } DBG (DBG_info, "gl124_init_regs_for_scan: move=%f steps\n", move); /* start */ diff --git a/backend/genesys_gl847.c b/backend/genesys_gl847.c index 5e3e842dd..387a5d999 100644 --- a/backend/genesys_gl847.c +++ b/backend/genesys_gl847.c @@ -869,6 +869,8 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, unsigned int min_restep = 0x20; uint8_t val, effective; int fast_step_type; + int acdcdis; + unsigned int ccdlmt,tgtime; DBGSTART; DBG (DBG_proc, "gl847_init_motor_regs_scan : scan_exposure_time=%d, " @@ -882,12 +884,8 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, /* get step multiplier */ factor = gl847_get_step_multiplier (reg); + /* we never use fast fed since we do manual feed for the scans */ use_fast_fed=0; - if(scan_yres>600 && feed_steps>900) - use_fast_fed=1; - /* we are doing custom feeding at high resolution */ - if(scan_step_type>2) - use_fast_fed=0; sanei_genesys_set_triple(reg, REG_LINCNT, scan_lines); DBG (DBG_io, "%s: lincnt=%d\n", __FUNCTION__, scan_lines); @@ -905,8 +903,12 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, if (flags & MOTOR_FLAG_AUTO_GO_HOME) r->value |= REG02_AGOHOME; - if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE || scan_yres>=2400) - r->value |= REG02_ACDCDIS; + acdcdis=0; + if (flags & MOTOR_FLAG_DISABLE_BUFFER_FULL_MOVE) + { + r->value |= REG02_ACDCDIS; + acdcdis=1; + } /* scan and backtracking slope table */ slow_time=sanei_genesys_slope_table(scan_table, @@ -945,13 +947,17 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, /* substract acceleration distance from feedl XXX STEF XXX : 2 different step type */ feedl=feed_steps; - feedl<<=fast_step_type; dist = scan_steps; if (use_fast_fed) { + feedl<<=fast_step_type; dist += fast_steps*2; } + else + { + feedl<<=scan_step_type; + } dist *=factor; DBG (DBG_io2, "%s: acceleration distance=%d\n", __FUNCTION__, dist); @@ -964,14 +970,11 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, sanei_genesys_set_triple(reg,REG_FEEDL,feedl); DBG (DBG_io ,"%s: feedl=%d\n",__FUNCTION__,feedl); - sanei_genesys_calculate_zmode2 (use_fast_fed, - scan_exposure_time, - scan_table, - scan_steps*factor, - feedl, - fast_steps*factor, - &z1, - &z2); + r = sanei_genesys_get_address (reg, REG0C); + ccdlmt=(r->value & REG0C_CCDLMT)+1; + + r = sanei_genesys_get_address (reg, REG1C); + tgtime=1<<(r->value & REG1C_TGTIME); /* hi res motor speed GPIO */ RIE (sanei_genesys_read_register (dev, REG6C, &effective)); @@ -1007,6 +1010,15 @@ gl847_init_motor_regs_scan (Genesys_Device * dev, r = sanei_genesys_get_address (reg, REG_BWDSTEP); r->value = min_restep; + sanei_genesys_calculate_zmode2(use_fast_fed, + scan_exposure_time*ccdlmt*tgtime, + scan_table, + scan_steps*factor, + feedl, + min_restep*factor, + &z1, + &z2); + DBG (DBG_info, "gl847_init_motor_regs_scan: z1 = %d\n", z1); r = sanei_genesys_get_address (reg, REG60); r->value = ((z1 >> 16) & REG60_Z1MOD) | (scan_step_type << REG60S_STEPSEL); @@ -1348,7 +1360,8 @@ gl847_init_scan_regs (Genesys_Device * dev, float lines, unsigned int depth, unsigned int channels, - int color_filter, unsigned int flags) + int color_filter, + unsigned int flags) { int used_res; int start, used_pixels; @@ -1381,6 +1394,23 @@ gl847_init_scan_regs (Genesys_Device * dev, "Flags : %x\n\n", xres, yres, lines, pixels, startx, starty, depth, channels, flags); +#ifdef SANE_DEBUG_LOG_RAW_DATA + /* for raw data debug, we know here the exact raw image + * attributes */ + if (rawfile == NULL && DBG_LEVEL >= DBG_data) + { + if (rawfile != NULL) + { + rewind(rawfile); + fprintf (rawfile, + "P5\n%05d %05d\n%d\n", + pixels*channel, + lines, + (1 << depth) - 1); + } + } +#endif + /* we may have 2 domains for ccd: xres below or above half ccd max dpi */ if (dev->sensor.optical_res < 2 * xres || !(dev->model->flags & GENESYS_FLAG_HALF_CCD_MODE)) @@ -2112,7 +2142,6 @@ gl847_slow_back_home (Genesys_Device * dev, SANE_Bool wait_until_home) SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_GAMMA | SCAN_FLAG_FEEDING | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | SCAN_FLAG_IGNORE_LINE_DISTANCE); sanei_genesys_set_double(local_reg,REG_EXPR,0); sanei_genesys_set_double(local_reg,REG_EXPG,0); @@ -2206,8 +2235,7 @@ gl847_search_start_position (Genesys_Device * dev) 600, dev->model->search_lines, 8, 1, 1, /*green */ SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_GAMMA | - SCAN_FLAG_IGNORE_LINE_DISTANCE | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE); + SCAN_FLAG_IGNORE_LINE_DISTANCE); /* send to scanner */ status = gl847_bulk_write_register (dev, local_reg, GENESYS_GL847_MAX_REGS); @@ -2435,7 +2463,7 @@ gl847_feed (Genesys_Device * dev, unsigned int steps) memset (local_reg, 0, sizeof (local_reg)); memcpy (local_reg, dev->reg, GENESYS_GL847_MAX_REGS * sizeof (Genesys_Register_Set)); - resolution=300; + resolution=200; gl847_init_scan_regs (dev, local_reg, resolution, @@ -2450,7 +2478,6 @@ gl847_feed (Genesys_Device * dev, unsigned int steps) SCAN_FLAG_DISABLE_SHADING | SCAN_FLAG_DISABLE_GAMMA | SCAN_FLAG_FEEDING | - SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE | SCAN_FLAG_IGNORE_LINE_DISTANCE); sanei_genesys_set_triple(local_reg,REG_EXPR,0); sanei_genesys_set_triple(local_reg,REG_EXPG,0); @@ -2549,11 +2576,11 @@ gl847_init_regs_for_scan (Genesys_Device * dev) move = SANE_UNFIX (dev->model->y_offset); move += dev->settings.tl_y; move = (move * move_dpi) / MM_PER_INCH; - DBG (DBG_info, "gl847_init_regs_for_scan: move=%f steps\n", move); + DBG (DBG_info, "%s: move=%f steps\n",__FUNCTION__, move); - /* at high res we do fast move to scan area */ - if(dev->settings.xres>1200 && move > 900) + if(dev->settings.yres>=1200) { + move -= 90; /* [90,80] */ status = gl847_feed (dev, move); if (status != SANE_STATUS_GOOD) { @@ -2562,6 +2589,7 @@ gl847_init_regs_for_scan (Genesys_Device * dev) } move=0; } + DBG (DBG_info, "%s: move=%f steps\n", __FUNCTION__, move); /* clear scancnt and fedcnt */ val = REG0D_CLRLNCNT; @@ -2579,6 +2607,9 @@ gl847_init_regs_for_scan (Genesys_Device * dev) /* emulated lineart from gray data is required for now */ flags |= SCAN_FLAG_DYNAMIC_LINEART; + /* backtracking isn't handled well, so don't enable it */ + flags |= SCAN_FLAG_DISABLE_BUFFER_FULL_MOVE; + status = gl847_init_scan_regs (dev, dev->reg, dev->settings.xres, @@ -2594,7 +2625,7 @@ gl847_init_regs_for_scan (Genesys_Device * dev) if (status != SANE_STATUS_GOOD) return status; - + DBGCOMPLETED; return SANE_STATUS_GOOD; } diff --git a/backend/genesys_gl847.h b/backend/genesys_gl847.h index 28882f8c7..3114d921d 100644 --- a/backend/genesys_gl847.h +++ b/backend/genesys_gl847.h @@ -152,6 +152,9 @@ #define REG0B_48MHZ 0x60 #define REG0B_60MHZ 0x80 +#define REG0C 0x0c +#define REG0C_CCDLMT 0x0f + #define REG0D 0x0d #define REG0D_FULLSTP 0x10 #define REG0D_SEND 0x80 @@ -192,6 +195,7 @@ #define REG1A_CK3INV 0x04 #define REG1A_LINECLP 0x02 +#define REG1C 0x1c #define REG1C_TGTIME 0x07 #define REG1D_CK4LOW 0x80 diff --git a/backend/genesys_low.c b/backend/genesys_low.c index 86d8c3cfa..4cc7306d0 100644 --- a/backend/genesys_low.c +++ b/backend/genesys_low.c @@ -1009,7 +1009,7 @@ SANE_Status sanei_genesys_write_ahb (SANE_Int dn, uint32_t addr, uint32_t size, uint8_t * data) { uint8_t outdata[8]; - size_t written; + size_t written,blksize; SANE_Status status = SANE_STATUS_GOOD; int i; char msg[60]="AHB="; @@ -1045,14 +1045,28 @@ sanei_genesys_write_ahb (SANE_Int dn, uint32_t addr, uint32_t size, uint8_t * da } /* write actual data */ - written = size; - status = sanei_usb_write_bulk (dn, data, &written); - if (status != SANE_STATUS_GOOD) + written = 0; + do { - DBG (DBG_error, "sanei_genesys_write_ahb: failed while writing bulk data: %s\n", - sane_strstatus (status)); - return status; + if (size - written > BULKOUT_MAXSIZE) + { + blksize = BULKOUT_MAXSIZE; + } + else + { + blksize = size - written; + } + status = sanei_usb_write_bulk (dn, data + written, &blksize); + if (status != SANE_STATUS_GOOD) + { + DBG (DBG_error, + "sanei_genesys_write_ahb: failed while writing bulk data: %s\n", + sane_strstatus (status)); + return status; + } + written += blksize; } + while (written < size); return status; }