[sane-devel] CANOSCAN 8400F

Stef stef.dev at free.fr
Thu Oct 23 04:51:26 UTC 2014


On 30/09/2014 12:05, Myroslav Kavatsyuk wrote:
> Dear Stef,
>
> After a summer brake I got again some time to work on the driver for 
> canoscan 8400F. In order to simplify my task I have disconnected 
> transparency
> unit while taking logs. This made logs more clear. Here are my findings:
>
> 1) Sensor profiles: For all scan modes only two different sensor 
> profiles are used:
> /* scan 1600, 1200 dpi, average_bit=0, DPISET=4800
>     CKSEL=1 for all modes */
> {CCD_CS8400F, 1600, 14400, 0x1ff, 0x0, 0x24924, 5168, 
> 0,0x2a,0x0,0x0,0x0,0x0000,0x00,0x01,0x0000,0x0000,
>         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0c, 0x11, 0x2a, 
> 0x30, 0x00, 0x00, 0x84},
> {0x0b,0x0e,0x11,0x02,0x05,0x08,0x63,0x00,0x40,0x00,0x00,0x0000,0x82},
> },
>  /* scan 800, 600 dpi, average_bit=0, DPISET=4800
>      scan 300 dpi, average_bit=1, DPISET=2400
>      scan 100, 75 dpi, average_bit=1, DPISET=1200
>      CKSEL=3 for all modes*/
> {CCD_CS8400F,  800, 7200,  0xe3f, 0x0, 0x1b6db, 5168, 
> 0,0x2a,0x0,0x0,0x0,0x0000,0x01,0x02,0x0000,0x0000,
>         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0c, 0x13, 0x2a, 
> 0x30, 0x00, 0x00, 0x84},
> {0x0d,0x10,0x01,0x04,0x07,0x0a,0x6b,0x00,0x40,0x00,0x00,0x0000,0x85},
>  },
> Inside the comments you will find values of relevant registers 
> (DPIHW=4800 for all modes). When I tried to use SANE to make a scan at 
> 100 dpi, the actual
> scan was performed with ~ 70 dpi. According to the SANE logs, SANE was 
> using dpiset=400 while the canon driver uses DPISET=1200, average_bit=1...
> To be honest I am sucked with this puzzle.
>
> 2) Motor tables:
>    I found that for each movement scanner uses two tables. In most 
> cases one table is short, 512 bytes, another is long 2024 bytes. 
> During the test scans the scan head was making three types of movements:
>   I) from parking position to the beginning of the scan
>   II) scanning
>   III) return to parking position
>  I have identified all tables for all modes. I will not send them in 
> this mail since they are large.  Here is the summary:
>     * Tables of type III are same same for all modes: 75-100, 300, 
> 600-800, 1200-1600 dpi
>     * Tables of type II are same for 600-800, 1200 dpi
>     * All tables same for:  75 and 100 dpi; 600 and  800 dpi; 1200 and 
> 1600 dpi.
>     * For resolutions of 75 and 100 dpi all tables of type I and II 
> are short (512 bytes)
> The interesting finding is that the tables for different movements are 
> written to different addresses:
> * Type I:
> genesys_write_register(0x5b,0x40)        length 2048
>      genesys_write_register(0x5c,0x00)
>    genesys_write_register(0x5b,0x50)         length 512
>      genesys_write_register(0x5c,0x00)
> * Type II
>     genesys_write_register(0x5b,0x48)           length 2048
>      genesys_write_register(0x5c,0x00)
>
>     genesys_write_register(0x5b,0x58)            length 512
>      genesys_write_register(0x5c,0x00)
>
> Type III
>     genesys_write_register(0x5b,0x58)           length  2048
>      genesys_write_register(0x5c,0x00)
>
>     genesys_write_register(0x5b,0x40)          length 512
>      genesys_write_register(0x5c,0x00)
>
> At this point I have collected some information but it is not clear 
> how to implement it into the genesys backend. How to implement 
> different motor
> tables for two-table movement? I see implementation for the g4050. 
> There are few tables defined for it. But it is not clear which of them 
> will be
> selected for each movement...
>
> Please provide me more information or help me with the implementation.
>
> Thank you in advance,
> Best regards,
> Myroslav
> ------------------------------------------------------------------------
> *From:* Stef <stef.dev at free.fr>
> *To:* Myroslav Kavatsyuk <m.kavatsyuk at yahoo.com>; 
> "sane-devel at lists.alioth.debian.org" <sane-devel at lists.alioth.debian.org>
> *Sent:* Wednesday, June 25, 2014 6:41 AM
> *Subject:* Re: CANOSCAN 8400F
>
> On 23/06/2014 15:51, Myroslav Kavatsyuk wrote:
>> Dear Stef,
>>
>> Thanks a lot for your suggestions. I have studied genesys 
>> documentation, and indeed it is helpful :)
>>
>> I have collected usblogs for all useful scan modes. In case you would 
>> like to look at them, you can
>> download processed (with your script) logs at: CS8400F 
>> <https://www.dropbox.com/sh/6je6fz2tsjy0r6x/AAA1yr9P6RrlEWaqk5lWjLNSa>
>>
>>
>> 	
>> image 
>> <https://www.dropbox.com/sh/6je6fz2tsjy0r6x/AAA1yr9P6RrlEWaqk5lWjLNSa>
>> 	
>> 	
>> CS8400F 
>> <https://www.dropbox.com/sh/6je6fz2tsjy0r6x/AAA1yr9P6RrlEWaqk5lWjLNSa>
>> Shared with Dropbox
>> 	
>> View on www.dropbox.com 
>> <https://www.dropbox.com/sh/6je6fz2tsjy0r6x/AAA1yr9P6RrlEWaqk5lWjLNSa>
>> 	
>> Preview by Yahoo
>>
>> I made summary of all possible sensor profiles. For each profile I 
>> wrote at which "dpi" setting of windows driver
>> it is used, value of the DPISET register, value of the AVEENB bit 
>> (average over few pixels or drop pixels):
>>  /*
>>         {CCD_CS8400F, dpi, 22000, 0x0, 0xff, 0x0, 5168, 0,0x2a,0x 0, 
>> 0x 0, 0x 0, -1, 0x07, 0x08, -1, -1,
>>         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x0c, 0x10, 0x2a, 
>> 0x30, 0x00, 0x00, 0x9a},
>>         {0x01, 0x04, 0x07, 0x0a, 0x0d, 0x10, 0x1b, 0x00, 0x40, 0x00, 
>> 0x00, -1, 0x88},
>>         }, // Scanner init, DPISET=600; AVEENB=1
>>         {CCD_CS8400F, dpi, 10800, 0xe3f, 0x0, 0x1b6db, 5168, 
>> 0,0x2a,0x 0, 0x 0, 0x 0, -1, 0x01, 0x02, -1, -1,
>>         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0c, 0x13, 0x2a, 
>> 0x30, 0x00, 0x00, 0x84, },
>> {0x0d,0x10,0x01,0x04,0x07,0x0a,0x6b,0x00,0x40,0x00,0x00,-1,0x88,},
>>         }, // Scanner init DPISET=2400, most probably TPU, AVEENB=1
>>         {CCD_CS8400F, dpi, 7200, 0xe3f, 0x0, 0x1b6db, 5168, 
>> 0,-1,0xfffffffffffffeff, 0xfffffffffffffeff, 0xfffffffffffffeff, -1, 
>> 0x01, 0x02, -1, -1,
>>         {-1, -1, -1, -1, -1, -1, 0x33, 0x0c, 0x13, -1, 0x30, -1, 
>> 0x00, 0x84},
>> {0x0d,0x10,0x01,0x04,0x07,0x0a,0x6b,-1,0x40,0x00,0x00,-1,0x88},
>>         }, // 600 dpi DPISET=4800 (last value 0x88 -> 0x85); 400,300 
>> dpi DPISET=2400, last number 0x85; 100 dpi DPISET=1200
>>         {CCD_CS8400F, dpi, 7200, 0xe3f, 0x0, 0x1b6db, 5168, 0,0x2a,0x 
>> 0, 0x 0, 0x 0, -1, 0x01, 0x02, -1, -1,
>>         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0c, 0x13, 0x2a, 
>> 0x30, 0x00, 0x00, 0x84},
>>         {0x0d, 0x10, 0x01, 0x04, 0x07, 0x0a, 0x6b, 0x00, 0x40, 0x00, 
>> 0x00,   -1, 0x85},
>>         }, // 800 dpi, DPISET=4800
>>         {CCD_CS8400F, dpi, 14400, 0x1ff, 0x0, 0x24924, 5168, 
>> 0,0x2a,0x 0, 0x 0, 0x 0, -1, 0x00, 0x01, -1, -1,
>>         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0c, 0x11, 0x2a, 
>> 0x30, 0x00, 0x00, 0x84},
>>         {0x0b, 0x0e, 0x11, 0x02, 0x05, 0x08, 0x63, 0x00, 0x40, 0x00, 
>> 0x00,   -1, 0x82},
>>         }, // 1200, 1600 dpi; DPISET=4800
>>         {CCD_CS8400F, dpi, 28800,   0x0, 0x0, 0x24924, 5168, 
>> 0,0x2a,0x 0, 0x 0, 0x 0, -1, 0x09, 0x0a, -1, -1,
>>         {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x0c, 0x10, 0x2a, 
>> 0x30, 0x00, 0x20, 0x84, },
>>         {0x02, 0x05, 0x08, 0x0b, 0x0e, 0x11, 0x1b, 0x00, 0x40, 0x00, 
>> 0x00,   -1, 0x88},
>>         }, // 3200,2400 scan; DPISET=4800 (last value can be 0x88 -> 
>> 0x81)
>> //
>>       // AVEENB=1 for dpi from 100-400 range; AVEENB=0 for dpi 
>> 600-3200 range
>>          */
>> This values are almost ready to be plugged into the code. I have to 
>> replace at some places "-1" values. What is strange for me
>> that DPISET values are very high with respect to dpi setting reported 
>> by driver.
>>
>> My questions are:
>> 1) what does the second field (dpi) means in the scanner profile? Is 
>> this value of the DPISET register?
>> 2) I did not manage to follow where actually sane decides which 
>> profile to use, which DPISET value to select?
>> In other words how to make sure that the correct combination will be 
>> selected for scan if I pass resolution of dpi to scanimage.
>> 3) From the logs I do not see how to extract motor tables (like one 
>> in the genesys_gl843.h at line 678). In the logs
>> I have seen setting up of the MTRTBL bit for downloading table 
>> (genesys_write_register(0x5b,0x01)genesys_write_register(0x5c,0x00))
>> This statements are followed by data. Is that data a motor table?
>>
>> Best regards,
>> Myroslav
>     Hello,
>
>     1) the dpi value is the effective maximum dpi for the scan. Scan's 
> dpi is the result of DPISET, DPIHW and CKSET. In the simplest case it 
> is the hardware DPI set for the recorded scan.
>
>     2) for a given target resolution, exposure is chosen first 
> (gl843_compute_exposure which uses get_sensor_profile) by selecting 
> the sensor profile which has the lowest dpi value above or equal to 
> the target dpi.
>
>     3) data can be written to the GL843 by many slightly different 
> ways that the decoding scripts may not handle, so look for bulk writes 
> mostly shorter than 2048 bytes, which turned (little-endian) to 16 bit 
> values give a decreasing slope with end values becoming closer. In 
> such a situation, I look at semi-processed log generated by the 
> 'partial.sh' script. After writes to 5b/5c registers like you noticed.
>
> Example from a 4400F log:
> URB  2992  control  0x40 0x04 0x82 0x00 len     8 wrote 0x01 0x00 0x82 
> 0x00 0xfe 0x01 0x00 0x00
> URB  2993  bulk_out len   510  wrote 0x00 0x60 0x00 0x60 0xd4 0x3c 
> 0x32 0x2e 0x29 0x26 0xdb 0x20 0x1e 0x1d 0x41 0x1a 0x00 0x18 0x2e 0x16 
> 0xaf 0x14 0x61 0x13 0x49 0x12 0x5b 0x11 0x84 0x10 0xc0 0x0f 0x18 0x0f 
> 0x7d 0x0e 0xf6 0x0d 0x71 0x0d 0x04 0x0d 0x97 0x0c 0x36 0x0c 0xd6 0x0b 
> 0x81 0x0b 0x36 0x0b 0xe9 0x0a 0xa5 0x0a 0x65 0x0a 0x27 0x0a 0xec 0x09 
> 0xb4 0x09 0x82 0x09 0x4f 0x09 0x21 0x09 0xf4 0x08 0xca 0x08 0xa1 0x08 
> 0x79 0x08 0x53 0x08 0x31 0x08 0x0d 0x08 0xed 0x07 0xce 0x07 0xae 0x07 
> 0x91 0x07 0x74 0x07 0x5b 0x07 0x40 0x07 0x27 0x07 0x0d 0x07 0xf7 0x06 
> 0xdf 0x06 0xc9 0x06 0xb3 0x06 0x9e 0x06 0x8b 0x06 0x77 0x06 0x64 0x06 
> 0x52 0x06 0x40 0x06 0x2e 0x06 0x1d 0x06 0x0c 0x06 0xfb 0x05 0xec 0x05 
> 0xdc 0x05 0xce 0x05 0xbf 0x05 0xb1 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 
> 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05 0xaf 0x05
> URB  2994  control  0x40 0x04 0x83 0x00 len     2 wrote 0x5b 0x00
>
> which gives 0x6000, 0x6000, 0x3cd4, 0x2e32, ...., 0x05ce, 0x05bc, 
> 0x05b1, 0x05af, 0x05af .... 0x05af
>
> Regards,
>     Stef
>
>

     Hello,

     what i would recommend for a start is to reach 'first light' 
status. Focus on getting a ~100 dpi color scan working. To ease and 
speed up develoment, write a simple unit test program and compile the 
backend with UNIT_TESTING defined. So you can tinker with registers 
values easily and focus on a particular thing without requiring 
everything to work.
     Also, stick to one motor table scan at first. Once you have 
something working, you can improve it. Some sample code for unit test 
program to quick-start yours:

  DBG_INIT();

   /* backend init */
   status = sane_genesys_init (&vc, cb);
   if (status != SANE_STATUS_GOOD)

     {
       printf ("sane_init()=%s\n", sane_strstatus (status));
       return 1;
     }
   status = sane_genesys_open ("genesys", &handle);
   if (status != SANE_STATUS_GOOD)

     {
       printf ("sane_open()=%s\n", sane_strstatus (status));
       sane_genesys_exit ();
       return 1;
     }
   session = (Genesys_Scanner *) handle;
   dev = session->dev;

   /* zone de test */
   dev->settings.scan_method=SCAN_METHOD_TRANSPARENCY;
   status = dev->model->cmd_set->move_to_ta (dev);
   if (status != SANE_STATUS_GOOD)
     {
       DBG (DBG_error, "move_to_ta failed: %s\n", sane_strstatus (status));
     }

   /* scan */
   dpi = 1200;
   dpihw = sanei_genesys_compute_dpihw (dev, dpi);
   channels = 3;
   depth=8;
   lines = 1200;
   startx = (SANE_UNFIX(dev->model->x_offset_ta)*dpihw)/MM_PER_INCH;
   pixels = (SANE_UNFIX(dev->model->x_size_ta)*dpihw)/MM_PER_INCH;

   size=pixels*channels*lines*(depth/8);
   data = malloc (size);

   /* round down pixel number */
   factor=pixels;
   factor=(factor/2)&0xfffe;
   pixels=factor;

   gl843_init_scan_regs (dev,
             dev->reg,
             dpi,
             dpi,
             startx,
             0,
             pixels,
             lines,
             depth,
             channels,
                         SCAN_MODE_COLOR,
             0,
             SCAN_FLAG_USE_XPA |
             SCAN_FLAG_DISABLE_SHADING |
             SCAN_FLAG_DISABLE_GAMMA |
             SCAN_FLAG_IGNORE_LINE_DISTANCE);

......

   r = sanei_genesys_get_address (dev->reg, 0x98);
   r->value = 0x02;
   r = sanei_genesys_get_address (dev->reg, 0x99);
   r->value = 0xe0;
   r = sanei_genesys_get_address (dev->reg, 0x9b);
   r->value = 0x90;

   RIE (dev->model->cmd_set->bulk_write_register (dev, dev->reg, 
GENESYS_GL843_MAX_REGS));

   RIE (gl843_begin_scan (dev, dev->reg, SANE_FALSE));
   DBG (DBG_proc, "XXX STEF XXX\n");
   DBG (DBG_proc, "sanei_genesys_start_motor\n");
   DBG (DBG_proc, "ZZZ STEF ZZZ\n");
   sanei_genesys_read_data_from_scanner (dev, data, size);
   RIE (gl843_end_scan (dev, dev->reg, SANE_TRUE));
   sanei_genesys_write_pnm_file ("image.pnm", data, depth, channels, 
pixels, lines);

   /* on gare et on ferme */
   status = dev->model->cmd_set->slow_back_home (dev, SANE_TRUE);
   sane_genesys_close (handle);
   sane_genesys_exit ();
   return 0;


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.alioth.debian.org/pipermail/sane-devel/attachments/20141023/9e96282e/attachment-0001.html>


More information about the sane-devel mailing list