[sane-devel] Reflecta Crystalscan / ProScan 7200 update
Vleeshouwers, J.M.
J.M.Vleeshouwers at tue.nl
Tue Dec 20 22:26:52 UTC 2011
We have a working backend for Reflecta CrystalScan & ProScan 7200, but we
did not succeed in interpreting all the data from the Windows logs. I have
analysed the firmware provided by Reflecta to get a bit further. The firmware
is an older version of the one currently available in the scanners, but
probably not that different. It is regular 8052-code. The disassembly
confirms what we already thought, but there are some new conclusions:
1. There really is no option to download gamma-tables. (However: there is a
call in the firmware that generates 4096 values (from 0 to FFF) for each
color and stores it in RAM. And there is also a command (0x3B) that allows
writing to RAM. So maybe...)
2. MODE SELECT (0x15) has a couple of additional settings, in bytes 10 and
up, mostly still quite mysterious. One of the bits enters a SCAN mode in
which each line is scanned and read individually, by command 0xF4. It also
looks like we have a "fast" scan mode next to the "normal" and "quality"
scan mode.
3. The SET GAIN OFFSET (0xDC) sets gain and offset values for RGBI, and also
has three other bytes (15-17) which are active. But that's about all I can
say about them;)
4. The INQUIRY command returns even more than the 184 bytes specified in its
header. The additional data is the specification of how the scanner scans a
line, with color masks and scan times (see below).
5. The scan frame WRITE (0x0A) and READ (0x08) commands allow to define at
most 8 different windows. It's not clear to me how that might be used or be
useful.
6. In the logs, the PARAM (0x15) command only returns 0 for "Period". In the
firmware it is not 0: it is set to something proportional to the total scan
time of a line, but more or less inversely proportional to resolution.
I cannot make sense of this. The "ScsiTransferRate" value is proportional to
line size and inversely proportional to the time it took to scan it.
7. The READ GAIN OFFSET command (0xD7) returns current gain and offset
values, as we already concluded, but also full-scale values resulting from
the auto-calibration performed by the scanner. The strange valued
bytes which puzzled us so far (78-97), appear to be uninitialised RAM.
8. The READ STATUS command (0xDD) contains only a minimal amount of data:
flags for button pushed, warmed up, SCAN executing, motor direction, and
post-warming-up code running (probably).
9. There are 22 commands available which are not used by the Windows driver;
see the list below. Some of them are regular, but most of them I named after
the function I'm more or less guessing they perform. I did not yet give
these new commands a try.
I would like to make more sense of the MODE SELECT scan quality options
("quality", "normal", and possibly also "fast"). These MODE SELECT bits
affect a table which defines how a line is scanned. (From its location in
memory, I'm calling it the BADF-table.) The BADF-table contains a variable
amount of 4-byte entries. Each entry consists of
a) a 2-byte counter value for 8052-timer 1, which determines when the next
interrupt happens, so how long this entry is active;
b) a byte which contains a color mask;
c) a byte which contains a bit indicating the last entry, and another bit
which function is unclear to me.
The Timer-1 interrupt handler accesses 8052-port 1 and several memory
locations which must be ports to hardware. I have probably identified the
external RAM port, the motor control port(s?), the USB-ports, and part of
the scanner controller, but still most of the action remains unclear.
Two questions with respect to that:
a. Would it be possible to identify the scanner controller hardware from
how the ports are used? For example, offset values appear to be set with a
separate sign bit. A GL846 doesn't have that as far as I can see, but are
there any known controllers which do? The controller gain/offset appears to
be set through registers 0x20/0x30/0x40 (red/green/blue gain), 0x50/0x60/0x70
(red/green/blue positive offsets), 0x51/0x61/0x71 (red/green/blue negative
offsets). Might this be an indication?
b. Is there any description available of the scanning process of a CCD-
scanner in full detail? I have seen a couple of data-sheets which give a
rough idea, but I wonder if there is anything more detailed?
That's it for today - hope some of you experts can help us with this.
Jan
=============================================
Command list - settings & operation commands
=============================================
WRITE (0x0A/0x01)
(not logged)
-------------------------------------
Unclear, may initiate post warm-up code
WRITE (0x0A/0x11)
(not logged)
-------------------------------------
Write custom halftone pattern data
WRITE (0x0A/0x12)
(not logged)
-------------------------------------
Define up to 8 scan frame windows
WRITE (0x0A/0x13)
-------------------------------------
Set exposure time (but that setting remains unused)
WRITE (0x0A/0x14)
-------------------------------------
Set highlight/shadow (but that setting remains unused)
WRITE (0x0A/0x16)
-------------------------------------
Write 2 x 5430 bytes, for each color
(WRITE can be without data, just a code & X bytes, to set code for subsequent READ)
MODE SELECT (0x15)
-------------------------------------
Sets scan parameters
Byte
0- 1 MODE SELECT data size
2- 3 Resolution
4 Bit 0 if set: Neutral (not supported)
Bit 1 if set: Red
Bit 2 if set: Green
Bit 3 if set: Blue
Bit 4 if set: Infrared
Bit 5-6: unused
Bit 7 if set: one pass color (if not one pass color, max 1 col bit may be set)
5 Bit 0 if set: 1 bit color depth (max res 3600)
Bit 1 if set: 4 bit color depth
Bit 2 if set: 8 bit color depth
Bit 3 if set: 10 bit color depth
Bit 4 if set: 12 bit color depth
Bit 5 if set: 16 bit color depth
Bit 6-7: unused
6 Bit 0 if set: Pixel color format
Bit 1 if set: Line color format
Bit 2 if set: Index color format
Bit 3-7: unused
7 (unused)
8 Bit 0: unused
Bit 1: byte order (although logged value 0x01)
Bit 2-7: unused
9 Bit 0: unused
Bit 1: “quality” scan flag (adds entry to BADF-table)
Bit 2: unused
Bit 3: “normal” scan flag (version dependent if bit should or shouldn't be set together with bit 1)
Bit 4-6: unused
Bit 7 if set: possibly a low quality flag (related to infrared)
10 Bit 0-2: unused
Bit 3 if set: number of lines = 14
Bit 4: unused
Bit 5 if set: single step operation after SCAN command
Bit 6 if set: use y0 = 3000, y1 = 4000, filter offsets 0
Bit 7: unused
11 Bit 1: overrides byte 8 bit 1 (byte order)
12 Halftone pattern
13 Line threshold
14 Bit 0 if set: additional action after READ
Bit 4-7 if >= 2: skip specific initialisation
15- 31 unused
WRITE RAM DATA (0x3B)
(not logged)
-------------------------------------
Input data to RAM
RELEASE SCANNER (0xD2)
-------------------------------------
Several reset actions
FIRMWARE UPDATE? (0xDB, 0xE5)
(not logged)
-------------------------------------
Write data to RAM and call ROM routine 014E (unknown)
SET GAIN OFFSET (0xDC)
-------------------------------------
Set values for gan and offset
Byte
0- 1 Timer 1 count for Red
2- 3 Timer 1 count for Green
4- 5 Timer 1 count for Blue
6 Offset Red
7 Offset Green
8 Offset Blue
9- 11 (unused, 0)
12 Gain Red
13 Gain Green
14 Gain Blue
15 Port 1 setting (values 0/6/7/other)
16 Number of entries to add to BADF table (logs show value>0 at higher resolutions)
17 If set (>0) double T1 count (exposure) - may be a switch between 8 and 16 bit processing
18- 19 Timer 1 count value Infrared
20 Infrared offset
21 (unused)
22 Infrared gain
UNKNOWN (0xDF)
(not logged)
-------------------------------------
Execute Timer 1 interrupt handler functions 0x12 & 0x18 & 0x1B
RESET (0xE1)
-------------------------------------
(not logged)
Seems to reset the device
SET NON-DEFAULT T1 (0xF0)
(not logged)
-------------------------------------
Specifies a different default Timer 1 count setting
ENABLE MAIN 4 (0xF1)
(not logged)
-------------------------------------
Enables MAIN section 4
WARMUP (0xF2)
(not logged)
-------------------------------------
Start warmup sequence
SCAN (0x1B)
-------------------------------------
SCAN(1) scans, SCAN(0) does nothing
SCAN (0x1B)
-------------------------------------
Abort SCAN command (if SCAN executing)
CONTINUE (0xF6)
-------------------------------------
(not logged)
In single step mode: exits single step mode
=============================================
Command list - commands that return data
=============================================
TEST UNIT READY
-------------------------------------
No data returned, but command response (OK/BUSY/SENSE, as already described)
REQUEST SENSE
-------------------------------------
Regular sense data (14 bytes)
Byte
2 Sense code
12 Additional sense code
13 Additional sense code qualifier
INQUIRY (0x12)
-------------------------------------
Standard and non-standard device data
Byte
0-183 As described already; most of the data is simply copied from memory
184-185 B4D1/0 = *17/6 a line count during scanning?
186 Number of entries in BADF-table
187-214 7 4-byte entries from BADF-table
READ (0x08/0x11)
-------------------------------------
(not logged)
Read static halftone pattern data from memory
Byte
0-var Halftone pattern data
READ (0x08/0x12)
-------------------------------------
(not logged)
Read current scan frame (x0,y0,x1,y1)
Byte
0- 8 Scan frame (x0,y0,x1,y1)
READ (0x08/0x13)
-------------------------------------
(not logged)
Read exposure times (seems unused, always returns 0x0064)
Byte
0-var Exposure times
READ (0x08/0x14)
-------------------------------------
(not logged)
Highlight/shadow settings (seems unused, static, 0x00/0x64)
Byte
0-var Highlight/shadow settings
READ (0x08/0x15&0x95)
-------------------------------------
Read calibration data as already described (mostly static data)
Byte
0- 29 Calibration data
READ (in SCAN context)
-------------------------------------
Read scanned lines (regular scan or calibration data)
Byte
0-var Scanned data, number of lines as specified
PARAM (0x0F)
-------------------------------------
Read current scan parameters
0- 1 Pixels on a scan line
2- 3 Number of lines to scan
4- 5 Bytes on a scan line (=width*depth)
6 Filter offset 1
7 Filter offset 2
8- 11 Period ( 3600*T / n0*res )
12- 13 ScsiTransferRate ( L / ( delta(T)/1024 ) ), delta taken at each READ
14- 15 Available lines
16 Bit 7-1: unused (not initialised)
Bit 0: motor direction
17 Unused (0)
CHECK SENSE (0x16, 0x17, 0x1D)
-------------------------------------
(not logged)
Returns “Check Condition” response if there is a sense
MODE SENSE (0x1A)
-------------------------------------
(not logged)
Read current MODE SELECT data (15 bytes)
READ RAM DATA (0x28)
-------------------------------------
(not logged)
Seems to read directly from RAM memory (number of bytes as specified, but seems incomplete)
READ GAIN OFFSET (0xD7)
-------------------------------------
Read data which may be used to determine scanner settings
Byte
0- 53 (unused, all 0)
54- 55 Auto-tuned full-scale-level for Red
56- 57 Auto-tuned full-scale-level for Green
58- 59 Auto-tuned full-scale-level for Red
60- 61 Timer 1 count for Red
62- 63 Timer 1 count for Green
64- 65 Timer 1 count for Blue
66 Offset Red
67 Offset Green
68 Offset Blue
69- 71 (unused, 0)
72 Gain Red
73 Gain Green
74 Gain Blue
75 Port 1 setting (values 0/6/7/other), value is set by SET GAIN OFFSET
76- 77 Fixed 0x0B79 (often used as default or reference)
78- 97 (unused, uninitialised)
98- 99 Timer 1 count for Infrared
100 Offset Infrared
101 (unused, set to 0 but not immediately)
102 Gain Infrared
SCAN LINE & READ (0xDA, 0xE0)
-------------------------------------
(not logged)
Probably scans a line and presents data to host
READ STATUS (0xDD)
-------------------------------------
Read status data
Byte
0 Bit 0 if set: button pushed
Bit 1-7: unused
1 (unused, 0)
2 (unused, may be unitialised)
3 (unused, may be unitialised)
4 (unused, may be unitialised)
5 Bit 0 if set: unit not warmed up
Bit 1-7: unused, 0
6 Bit 0-5: unused, set to 10 00 00
Bit 6 if set: SCAN command executing
Bit 7: motor direction
7 (unused, may be unitialised)
8 Bit 0 if set: post warming-up code running
Bit 1-7: unused, 0
9 (unused, 0)
10 (unused, 0)
READ RAM DATA 8000 0xF3
-------------------------------------
(not logged)
Reads data from 0x8000-port (access to current CCD-mask)
COPY (0x18)
-------------------------------------
Output CCD-pattern (when SCAN active)
SCAN/READ LINE & STEP (0xF4)
-------------------------------------
(not logged)
In single step mode: read a line and step
COMMAND OK (0xF5)
-------------------------------------
(not logged)
In single step mode: only returns an OK response
More information about the sane-devel
mailing list