[sane-devel] Back-end for CanoScan 3200F?

Lauri Pirttiaho lauri.pirttiaho@luukku.com
Mon, 27 Jun 2005 22:51:22 +0300 (EEST)


Gerald Murray:
> Quoting Lauri Pirttiaho <lauri.pirttiaho@luukku.com>:
>=20
> The genesys backend gl841 MAY be the closest to what=20
> you are describing here, but some details you mention
> show small variance from the gl841.  The backend for the
> gl841 probably best described as an early start, or a stalled
> project.  The project remains blocked due to access to the=20
> registers, and unknown vendor read/write commands.  From my
> tests on Canon LiDE 35 that scanner NAKs every attempt I have
> tried so far.

I took a look at the LiDE35 log that Pierre Willenbrock
had on his www page. That does not look anything like
the log of 3200F. There are few logs from 3200F on page
http://www.coriolys.org/Sane/index.html, for comparison.

> Providing details on what went down the usb bus would=20
> certainly help.  The log from a scan may provide some clues
> to what is currently unknown.

Example of the boot of 3200F looks like following (this
is abbreviated log of vendor specific control transfer
messages in format time-out/time-in:URB dir request-type/request value inde=
x length data):

000252/000252:0005 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dfe1f bl=3D0001 dt=3D26
000253/000253:0006 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dffef bl=3D0001 dt=3D00
000253/000254:0007 > rt/rq=3D40/04 vl=3D00e0 ix=3Dffef bl=3D0002 dt=3D20 00
000254/000254:0008 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dffb4 bl=3D0001 dt=3D8f
000254/000255:0009 > rt/rq=3D40/04 vl=3D00e0 ix=3Dffb4 bl=3D0002 dt=3Daf 00
000255/000255:0010 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dffed bl=3D0001 dt=3D03
000255/000256:0011 > rt/rq=3D40/04 vl=3D00e0 ix=3Dffed bl=3D0002 dt=3D03 00
000256/000256:0012 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dffe3 bl=3D0001 dt=3D05
000256/000257:0013 > rt/rq=3D40/04 vl=3D00e0 ix=3Dffe3 bl=3D0002 dt=3D05 00
000257/000257:0014 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dffe2 bl=3D0001 dt=3D00
000258/000259:0015 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000259/000259:0016 > rt/rq=3D40/04 vl=3D00f0 ix=3D0000 bl=3D0005 dt=3D00 00=
 00 00 00
000259/000260:0017 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000260/000260:0018 > rt/rq=3D40/04 vl=3D00f3 ix=3D0000 bl=3D0004 dt=3D00 4e=
 00 00
> bl=3D009c00
    00000000: 02 90 af 02 98 f0 d2 38 d2 34 22 02 86 e6 7e 00

First ten transfers are manipulations of the high addresses
in the MCU address space. I wrote a program to dump the
whole address space using these single byte accesses
and I find the downloaded blocks in the dump (including
the firmware) so I am confident about that. Address 0xffe2
contains an indicator about firmware upload so finding
0 there makes the driver to upload. If there is 0xbf the
driver assumes the firmware is already uploaded and checks
the version of the firmware. Write to value 0x00f0 indicates
32 bit address (in 16 bit words) for the following upload
and write to 0x00f3 indicates length (again in 16-bit words).
The data following is the MCS51 machine code. (The block
uploads must start at 16-byte boudary and be a multiple
of 16 bytes.)

After the upload the driver actually downloads the same
data, obviously for verification:

000268/000269:0020 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000269/000269:0021 > rt/rq=3D40/04 vl=3D00f0 ix=3D0000 bl=3D0005 dt=3D00 00=
 00 00 00
000269/000270:0022 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000270/000270:0023 > rt/rq=3D40/04 vl=3D00f4 ix=3D0000 bl=3D0004 dt=3D00 4e=
 00 00
< bl=3D009c00
    00000000: 02 90 af 02 98 f0 d2 38 d2 34 22 02 86 e6 7e 00
=20
Now the write of the transfer length to value 0x00f4
initiates download; the download length seems to have
to be multiple of 64 bytes.

After verification of the code there are further settings
like:
000282/000283:0025 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dfdf6 bl=3D0001 dt=3D3f
000283/000284:0026 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000284/000284:0027 > rt/rq=3D40/04 vl=3D00b0 ix=3D0000 bl=3D0003 dt=3D00 00=
 00
000284/000315:0028 < rt/rq=3Dc0/04 vl=3D002c ix=3D0001 bl=3D0002 dt=3Dff 00
000315/000315:0029 > rt/rq=3D40/04 vl=3D002b ix=3D0001 bl=3D0002 dt=3Dbe 00
000315/000316:0030 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000316/000317:0031 > rt/rq=3D40/04 vl=3D00d0 ix=3D0020 bl=3D0003 dt=3D00 80=
 00
000317/000317:0032 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000317/000318:0033 > rt/rq=3D40/04 vl=3D00d0 ix=3D0021 bl=3D0003 dt=3D00 80=
 00
000318/000319:0034 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000319/000319:0035 > rt/rq=3D40/04 vl=3D00d0 ix=3D0022 bl=3D0003 dt=3D00 80=
 00
000319/000320:0036 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000320/000321:0037 > rt/rq=3D40/04 vl=3D00d0 ix=3D0028 bl=3D0003 dt=3D00 4b=
 00
000321/000321:0038 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000321/000322:0039 > rt/rq=3D40/04 vl=3D00d0 ix=3D0029 bl=3D0003 dt=3D00 4b=
 00
000322/000323:0040 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000323/000323:0041 > rt/rq=3D40/04 vl=3D00d0 ix=3D002a bl=3D0003 dt=3D00 4b=
 00
000323/000324:0042 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dfe00 bl=3D0001 dt=3D01
000324/000324:0043 < rt/rq=3Dc0/0c vl=3D002c ix=3D0006 bl=3D0001 dt=3D00
000342/000343:0044 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dffb0 bl=3D0001 dt=3D30
000343/000343:0045 > rt/rq=3D40/04 vl=3D00e0 ix=3Dffb0 bl=3D0002 dt=3D30 00
000344/000344:0046 < rt/rq=3Dc0/0c vl=3D00e1 ix=3Dffb1 bl=3D0001 dt=3D3b
000344/000345:0047 > rt/rq=3D40/04 vl=3D00e0 ix=3Dffb1 bl=3D0002 dt=3D3b 00
000345/000345:0048 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000345/000346:0049 > rt/rq=3D40/04 vl=3D002b ix=3D0008 bl=3D000b dt=3D00 1f=
 00 a7 01 cf 01 cf 03 ff 00
000346/000347:0050 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000347/000347:0051 > rt/rq=3D40/04 vl=3D00f0 ix=3D0000 bl=3D0005 dt=3D80 6e=
 00 00 00
000347/000348:0052 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000348/000349:0053 > rt/rq=3D40/04 vl=3D00f3 ix=3D0000 bl=3D0004 dt=3D00 0f=
 00 00
> bl=3D001e00
    00000000: 07 07 07 07 07 07 07 07 06 06 06 06 06 06 06 06

The first read from address 0xfdf6 is some kind of
counter ticking up at 1.1 counts per second and
saturating to 200 (0xc8). The following write to=20
value 0x002b seems to be obtained by subtracting
that counter, first adjusted by truncating multiplication
by 25/24, from the value read from 0x002c. Meaning of
this is yet unknown to me. Next writes to value 0x00d0
with various indices seem to be similar found in
ScanMaker SM3840, a S&Q SCAN08 device, and they set
the scanner black and gain values.

Next there are reads and writes that are mystery, as well
as the write to value 0x002b index 8 and the following
upload to (byte) address 0xdd00. The upload has some
structure in it, some 15 different kind of blocks.
I have not deciphered their meaning, but the driver
uploads different blocks for different purposes and
the blocks seem to affect how the scans come out and
how fast the head moves.

I have more, but I think that shows that the procedure
is unlike that found in Genesys based devices. I took
a look at GL841 spec and there are several items that
do not match, like the length of the gamma curve which
for the 3200F seems to be 8kB (13-bit -> 8-bit map).

My question is, has anybody seen this kind of protocol
in other devices? That would give some hint about the
Chip.

> My read of the gl841 registers show that the home position
> sensor would be in register 0x0041
>=20
> > values 0x0023 and 0x0024 index 0 which move the
>=20
> Here the gl841 seems to show register 0x0022 and 0x0023
> for this, probably.

What you see from the value 0x0040 index 0 looks like

000486/000487:0097 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 00
000487/000488:0099 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D20 00
000589/000590:0104 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D21 ff
000855/000856:0121 < rt/rq=3Dc0/04 vl=3D0040 ix=3D0000 bl=3D0002 dt=3D00 ff

The first you see when the head is home, the second when
the head has started moving out, third when it is moving
further out ad the last when the head is out but stopped.

The move-forward commad looks like
000487/000487:0098 > rt/rq=3D40/04 vl=3D0023 ix=3D0000 bl=3D0005 dt=3D00 02=
 26 02 00

Where the first word (two bytes, LSB first) is the
distance to move and the fourth byte seems to affect
the speed (2 for low speed, 4 for high). Move-backward
seems similar but has value 0x0024.

> The logs that would show data being written to the address
> of a MPU are of interest, as the gl841 still has some=20
> unknown problems that stall that backend.

I am currently in process of crawling through the
disassembled firmware (typical compiler output
of loop type scheduled control program, with
c-init, hw-initialization code and an event loop,
events of which seem to be generated by interrupts).
I hope from that I can get more hint on how the
system is controlled and what the mystery uploads
to 0xdd00 do (or it may also be that the HW other than
the MCU actually uses those blocks).

I will keep you posted when I get more publishable
results.

With best regards,

Lauri Pirttiaho
Oulu
Finland


...................................................................
Luukku Plus paketilla p=E4=E4set eroon tila- ja turvallisuusongelmista.
Hanki Luukku Plus ja helpotat el=E4m=E4=E4si. http://www.mtv3.fi/luukku