ERNST Hard- & Software-Entwicklung HomepageÜber unsKontaktInformationServiceLinksNewsJobs
Hard- & Software-EntwicklungInformation: SANE backend for
Service: Kundenlogin


Information: SANE backend for "CanoScan LiDE 600F"

Developing the SANE backend

The programming of the backend has been started. It will support scanners CanoScan LiDE 600F and CanoScan LiDE 70 as well. No code is published at the moment because everything is highly in flux.

Now it's possible to do scans in 300 dpi (without gamma correction) via XSane frontend.

So stay tuned...

Help

If you want to help this project please send an email to me (Jürgen Ernst).

The SANE project

SANE stands for "Scanner Access Now Easy" and is an application programming interface (API) that provides standardized access to any raster image scanner hardware (flatbed scanner, hand-held scanner, video- and still-cameras, frame-grabbers, etc.).

The SANE API is public domain and its discussion and development is open to everybody.

You can find more information regarding the SANE project on its official homepage at http://www.sane-project.org.

The flatbed scanner

Features: Ergonomic, 3-Way design, Film Adapter Unit for 35mm transparencies, FARE and QARE Level 3 dust/scratch removal, 4800 x 9600dpi*, 48 bit colour depth, USB 2.0 Hi-Speed, Scan to PDF, Multi-photo mode, 7 EZ buttons, Comprehensive software package.

The CanoScan LiDE 600F is a very good scanner. But it has the disadvantage that Canon is unwilling to release the necessary documentation to enable a Linux driver and SANE backend to be written.

So I decided to write a SANE backend for linux on my own.

Identification of the protocol

The CanoScan LiDE 600F is compatible to the CanoScan LiDE 600 and the difference is simply an additional Film Adapter Unit. So the chips for the LiDE 600F are known, but are not known to be compatible with SANE-supported chips. You can find this information and more here.

On my computer SANE (v1.0.18) reported this (13.8 kB) after starting the command "sane-find-scanner -v -v".

As this scanner has an USB interface a good start would be to complete a small scan with an USB sniffer to log the traffic on the USB bus for that device. That may allow identification of the protocol.

To do this I had to create a partition with Win XP on my hard drive. Then I installed the Canon software from CD. After verifying that the scanner is working as it should I downloaded an USB sniffer. I used benoit's USB sniffer.

Here are some original log files from the sniffer:

Simply plugged the scanner in, calibration process recorded
usbsnoop1.zip (196 kB)

Preview scan with empty white page
usbsnoop2.zip (3.9 MB)

Scan with 150 dpi (colour, 1276 x 1384 pixel)
usbsnoop3.zip (4.9 MB)

Scan with 150 dpi (grey, 1276 x 1384 pixel)
usbsnoop4.zip (8.8 MB)

Scan with 150 dpi (colour , 248 x 267 pixel)
usbsnoop5.zip (2.0 MB)

To simplify the work with the log files above I wrote "parselog1.pl" and "parselog2.pl" to convert them into a format for better parsing and human reading. A conversion of "usbsnoop1.zip" can be found in "snoop1.zip". And "usbsnoop2.zip" is in "snoop2.zip" and so on.

Script to convert the log files to simple format
(you have to give the log filename as parameter. Output is displayed to STDOUT so you'll have to redirect it to a file)
parselog1.pl (3.6 kB)
(as parselog1.pl but it omits dummy bulk data transmissions -> smaller file)
parselog2.pl (3.9 kB)

New simplified log files (output from parselog2.pl)
snoop1.zip (67 kB)
snoop2.zip (2.3 MB)
snoop3.zip (1.7 MB)
snoop4.zip (6.2 MB)
snoop5.zip (1.4 MB)

Next is a method to send data to and receive data from the scanner. I'm using perl as my favorite programming language and so I installed the package Device::USB from CPAN to get easy access to libusb.

I programmed the script "canonusb3.pl" to load a log file and send the same data to the scanner. The first result is: it works! I managed to access the scanner. It made some moves forth and back, turned on the light and moved about 1 inch forward. An I/O-Error stopped the script but as a first result this is great!

Script to access scanner and replay log file
(you have to give the log filename as parameter, tries to replay whole log)
canonusb3.pl (4.4 kB)

I modified the script to replay sections of the log. Now you can specify start URB and end URB as additional parameters.

Script to access scanner and replay log file (start URB + end URB)
canonusb4.pl (4.7 kB)

CP2155 scanner chip

The scanner chip has a page with 256 registers. Each byte can be set and read with a single command. At calibration there is a command sequence to get the content of the whole page. I made a script to get this bytes too.

Script to get whole registerpage 0x00..0xfe
registerpage.pl (3.0 kB)
Here is the output you'll get for LiDE 600F and LiDE 70
registerpage.txt (1.7 kB)

Script to poll one single register
pollregister.pl (3.3 kB)
Parameter is register in hex. (e.g. 91)

My current knowledge of CP2155 registers can be found in register.txt.

Problems

To replay the log the scan head has to be put to it's start position. I can't do this with my script at the moment. You must use your scanner software (Windows) to move the head back to the start position.

The script has to be run as root. Otherwise it gets no access to the device. Okay you can set permissions but it's silly to do this. If you unplug and replug the scanner frequently, hotplug will set up a new usb device and your changes are gone.

While testing I noticed a weird error code from libusb (v0.1.12). When I made a bulk_write to endpoint 0x03 I always received error code -ENOENT (-2) "no such file or directory". First I thought it's a problem with the device permissions but we are running as root and mode 0644 is okay. And as we are running a perl script there can't be timing problems. It's USB 2.0 so the response is ready in a few µ seconds. Perl needs more time to go to the next usb command than this. And yes I have tested with an additional delay of about 10 ms with no change on the error code. So I simply ignored that error. The next bulk_read from endpoint 0x83 nevertheless brought the correct result.

Let me know your results, if you made a test with your scanner. Every help is highly appreciated.

Results

Scanner protocol is very high level. With a structural analysis it is possible to see functional blocks of driver code.

I managed to figure out the start sequence for scanning and I know how to read the buttons of the scanner.

More details of my analysis can be found in the text file analysis.txt (25.3 kB).

Here is my first successful decoding of scan data. The first picture is what I've calculated. The second picture is what has been saved by vendor software. Yes I know, I'll have to perform some gamma correction.

The scan data is simply returned line by line. First a line with blue colour bytes, then a line with green colour bytes and last a line with red colour bytes. This sequence is repeated until the last scan line. Width is padded to a multiple of 128. You can see it as a black column on the right.

To decode the scan data some preprocessing has to be done.

Script to extract scan data
(you have to give the log filename as parameter. Output is displayed to STDOUT so you'll have to redirect it to a file)
image-get.pl (4.2 kB)

To extract scan data try perl image-get.pl snoop5.txt >image-data5.txt

Extracted scan data (output from image-get.pl)
image-data1.zip (28.9 kB)
image-data2.zip (1.4 MB)
image-data3.zip (1.2 MB)
image-data4.zip (4.3 MB)
image-data5.zip (1.0 MB)

Script to display scan data
(you have to give the previously generated image data file as parameter, second parameter is the width of the image, third parameter is count of lines to skip)
image-show.pl (2.6 kB)

To display the image try
perl image-show.pl image-data5.txt 256 234 1 (german post stamp) or
perl image-show.pl image-data4.txt 1280 37 (O'Reilly perl book) or
perl image-show.pl image-data2.txt 640 234 (blank white page)

The parameters of image-show.pl are:
- first the image data file output from image-get.pl
- second the image width padded to a multiple of 8 (LiDE70: multiple of 16)
- third the amount of lines to skip calibration data
- fourth amount of pixels to skip to roll image horizontally.

There is also an image of the calibration process.
Try perl image-show.pl image-data5.txt 128 0

Canon LiDE 600F vs. Canon LiDE 70

As reported from sane project Canon LiDE 70 has the same chip (Philips CP2155BE) as Canon LiDE 600F inside. It was supposed that they will behave mostly the same. I got reports from users with Canon LiDE 70 and the above scripts worked with Canon LiDE 70 as well. So this backend has a good chance to support them both.