The HP4470C is a USB/Parallel flatbed scanner. This scanner is
based on the RealTek RTS8891
scanner chip. I haven't been able to obtain the data sheets for this
chip so far so the following document outlines observations made
about the operations of the device by looking at the USB dumps
produced by USBSnoop as well as reverse engineering (disassembly) of
the windows drivers supplied by HP.
Thanks for the first general
information's from Michael
Cohen . But the first source don't work with my scanner, the lamp
doesn't switch on. My first investigation shows that HP using
different boards in the scanner. The Windows driver reads a
MainboardID and use it for different values by init the scanner. I
have now updated the sources with the init and the calibration
sequence from my scanner.
I'm using for disassemble the Windows
DLL's hpg4400.dll and rts8891u.dll. The HP-setup use the same DLL's
for this two scanners. The Windows driver (rts8891u.dll) reads a
MainboardID and use it for different values by init the scanner.
All
investigation's based at the moment on USB. I think, after
understand the chipset, it is easy to implement the parallel
interface.
Here the general HW, what i found (bold = my scanner):
Model |
Vendor |
ID |
Mainboard_ID |
ASIC /IC's |
Analog front-end |
hp4400c |
03F0 |
0705 |
? |
ASIC 13010070-5011 (RealTek RTS8891) |
built-in |
hp4470c |
03F0 |
0805 |
0x00 |
ASIC 13010070-5011 (RealTek RTS8891) |
built-in |
The 4470c has one configuration (1) with a single interface (0), the interface in turn has 3 end points:
ep |
Type |
Direction |
0x81 |
Bulk |
IN |
0x02 |
Bulk |
Out |
0x83 |
Interrupt |
|
This scanner does not use control pipes at all - all communications to the device occur using bulk mode. The device has 244 registers. These can be accesses one at the time or a whole sequence of registers may be accessed simultaneously.
The general command sent over the bus has the following format:
Byte offset |
Number of bytes |
Meaning |
00 |
01 |
Command |
01 |
01 |
Register |
02 |
02 |
Count |
03 |
||
04- |
Variable |
Optional Data |
The command ID and register are each 1 byte. The count is two bytes and is given with the most significant byte first. For write commands with a count of 0, or for any read command, the size of the command block is 4 bytes.
The following commands have been observed:
Command ID |
Read/Write |
Purpose |
Description |
0x80 |
Read |
Read register |
This command is issued with an OUT transfer on ep 0x81. The count specifies how may bytes are required to be returned from the device. In order to actually read those the host needs to initiate a transfer for the required number of bytes for the IN direction: example: > transfer type=bulk size=4 ep=0x02 dir=OUT |
0x81 |
Read |
Read some calibration data |
|
0x88 |
Write |
Set register |
This command sets the register or group of registers specified. There is no need to read any data after issuing this command so only one transfer is required. It seems that the maximum packet size is 0xb4 registers to be set at once. So if you need to write all 0xf4 registers its necessary to split into two packets. |
0x89 |
Write |
Write data to calibration |
This command is used to write 2072 (0x818) bytes of a sequentially increasing pattern to the scanner. used for calibration. |
0x8A |
Write |
Unknown |
|
0x90 |
Read |
Read qty of bytes in the download buffer |
(read 3 bytes. eg. 0x90 0x00 0x00 0x03) this command queries the buffer as to how many bytes are present for download during getting at image. Note that the maximum USB transfer size per request appears to be 0xffc0. |
0x91 |
Read |
Read download buffer |
Read this many bytes from the scanner buffers. Maximum 0xffc0. |
example:
The following resets the button state after reading it (above).
>
transfer type=bulk size=5 ep=0x02 dir=OUT
> 88 25 00 01 00
Note that it seems to be possible to combine packets. Hence if we
want to set
a variable and immediately read another:
> transfer type=bulk size=9 ep=0x02
dir=OUT
> 88 da 00 01 a0 80 10 00 02
> transfer
type=bulk size=2 ep=0x81 dir=IN
< 68 1a
The following registers have been identified:
|
Mainboard ID |
0 |
0 |
0 |
0 |
0 |
0 |
||
REG adress |
description |
Write REG set myinit32, init for scan 300dpi
|
Write REG set myinit33, scan grayscale 300dpi
|
Write REG set pv300dpi_24
|
Write REG set pv300dpi_20
|
Write REG set pv300dpi_21
|
_300_true_2_30
|
||
0x00 |
1 Byte WRITE: This register is normally set to 0xf5, but before reading any actual image data it needs to be set to 0xe5 otherwise all data will be 0x90 (maybe its enabling the CCD?) |
0xE5 |
0xE5 |
0xE5 |
0xE5 |
0xE5 |
0xE5 |
||
0x01 |
1 Byte WRITE: every time 0x41 |
0x41 |
0x41 |
0x41 |
0x41 |
0x41 |
0x41 |
||
0x02..03 |
1 Word WRITE: |
0x1F1F |
0x7F7F |
0xFAFA |
0x8682 |
0x8682 |
0x8682 |
||
0x04..05 |
1 Word WRITE: |
0x1F1F |
0x7F7F |
0xFAFA |
0x8686 |
0x8686 |
0x8686 |
||
0x06..07 |
1 Word WRITE: |
0x1F1F |
0x7F7F |
0xFAFA |
0x8286 |
0x8286 |
0x8286 |
||
0x08 |
1 Byte WRITE: Brightness for eatch color? Normaly 0x10. A higher value gives more brightness. (0..0x20) |
0x0A |
0x10 |
0x00 |
0x06 |
0x06 |
0x06 |
||
0x09 |
1 Byte WRITE: Brightness for eatch color? Normaly 0x10. A higher value gives more brightness. (0..0x20) |
0x0A |
0x10 |
0x00 |
0x05 |
0x05 |
0x05 |
||
0x0A |
1 Byte WRITE: Brightness for eatch color? Normaly 0x10. A higher value gives more brightness. (0..0x20) |
0x0A |
0x10 |
0x00 |
0x0A |
0x0A |
0x0A |
||
0x0B |
1 Byte WRITE: every time 0x70 |
0x70 |
0x70 |
0x70 |
0x70 |
0x70 |
0x70 |
||
0x0C..0x0F |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x10,0x11 |
2 Byte WRITE: Controls little green LED's for color selector 0x10: (0x20 - color) (0x10- B/W) bit 7 controls how many bits per color to produce. e.g. 0x20 1 bit per pixel, 0x28 2 bits per pixel? 0x11:
Values : 28, 3b, 3f |
0x283F |
0x283F |
0x203B |
0x203B |
0x203F |
0x203B |
||
0x12 |
1 Byte WRITE: every time 0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
||
0x13 |
1 Byte WRITE: bit 1 if on- the resulting scan has a zero for each other pixel, every time 0x20 |
0x20 |
0x20 |
0x20 |
0x20 |
0x20 |
0x20 |
||
0x14..0x15 |
2 bytes WRITE, every time 0xF8 ,0x28 |
0xF828 |
0xF828 |
0xF828 |
0xF828 |
0xF828 |
0xF828 |
||
0x16 |
1 Byte WRITE: |
0x07 |
0x07 |
0x07 |
0x07 |
0x07 |
0x01 |
||
0x17 |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x18 |
1 Byte WRITE: every time 0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
||
0x19 |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x1A |
1 Byte READ: Buttons: Some more button registers like 0x25: |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
button icon |
mask |
|
|||||||
Red triangle |
0x01 |
||||||||
spanner |
0x02 |
||||||||
color |
0x04 |
||||||||
|
|||||||||
0x1B..0x1C |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x1D |
1 Byte READ: Micro
switch 1 Byte WRITE: every time 0x20 |
0x20 |
0x20 |
0x20 |
0x20 |
0x20 |
0x20 |
||
0x1E..0x1F |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x20-0x22 |
3 Byte WRITE : LCD-Display |
0x3AF200 |
0x3AF200 |
0x3AF200 |
0x3AF200 |
0x3AF200 |
0x3AF200 |
||
0x23 |
1 Byte WRITE: |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0x80 |
||
0x24 |
1 Byte WRITE: |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
||
0x25 |
1 Byte Read: Buttons Button-icon mask power 0x80 scanner 0x40 www 0x20 copy 0x10 email 0x08 print 0x04 - 0x02 + 0x01 1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x26..0x31 |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x32..0x33 |
Movement two Byte. Values 0x8081(myinit33), 0x2083 (pv600dpi_11), 0x0003(pv300dpi_02..12), 0x0000(myinit30) 0x33: |
0x0000 |
0x8081 |
0x0003 |
0x2083 |
0x2083 |
0x2083 |
||
0x34 |
1 Byte WRITE: every time 0x10 |
0x10 |
0x10 |
0x10 |
0x10 |
0x10 |
0x10 |
||
0x35 |
1 Byte WRITE: values 0x00(pvinit10), 0x0e(pvinit11), 0x1b(myinit33), 0x45(pvinit13), 0x47 (pv600dpi_12) |
0x00 |
0x1B (scan) |
0x0E (move) |
0x47 |
0x47 |
0x47 |
||
0x36 |
1 Byte WRITE: Movement, controls the direction of movement 0x24 reverse, 0x2c forward. Note that when rewinding the values in 0x60,0x62 are ignored, the scanner always goes back to the home position and stops. Note that there are a number of step sizes: 0x2c is half the step size of 0x29. 0000 D000, D = direction. |
0x07 |
0x29 |
0x22 |
0x2C |
0x2C |
0x2C |
||
0x37, 0x38 |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x39 |
1 Byte WRITE: after init (0x00) everytime 0x02 |
0x00 |
0x02 |
0x02 |
0x02 |
0x02 |
0x02 |
||
0x3A |
1 Byte WRITE: Movement,
values 0x00(pvinit10),
0x0e(pvinit12),0x1b(myinit33),
0x43(pvinit13) |
0x00 |
0x1B |
0x0E |
0x43 |
0x43 |
0x43 |
||
0x3B..0x3E |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x40 |
1 Byte WRITE: values 0x20(normaly), 0x2c(pv300dpi_20 / 21, pv600dpi_11 / 12) |
0x20 |
0x20 |
0x20 |
0x2C |
0x2C |
0x2C |
||
0x41..0x43 |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x44 |
1 Byte WRITE: every time 0x8c |
0x8C |
0x8C |
0x8C |
0x8C |
0x8C |
0x8C |
||
0x45 |
1 Byte WRITE: every time 0x76 |
0x76 |
0x76 |
0x76 |
0x76 |
0x76 |
0x76 |
||
0x46..0x5F |
1 Byte WRITE: every time 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x60, 0x62 |
2 Byte WRITE : (each
LSB first): |
xxxx |
xxxx |
xxxx |
xxxx |
xxxx |
xxxx |
||
0x64 |
1 Byte WRITE : after init (0x00) everytime 0x01 |
0x00 |
0x01 |
0x01 |
0x01 |
0x01 |
0x01 |
||
0x65 |
1 Byte WRITE : Scan control, must be 0x20 to enable for scanning, 0x00 for just moving. |
0x00 |
0x20 |
0x20 |
0x20 |
0x20 |
0x20 |
||
0x66 |
2 bytes: WRITE : Scan from this horizontal pixel(high byte, low byte). Only in normal mode? |
0x0000 |
xxxx |
xxxx |
0010 |
0010 |
0010 |
||
0x68..0x6B |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x6C..0x6D |
2 bytes: WRITE : Scan to this horizontal pixel. Only in normal mode? |
0x0000 |
xxxx |
xxxx |
xxxx |
xxx (028E) |
xxx (028E) |
||
0x6E..0x71 |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x72 |
1 Byte WRITE : |
0xE1 |
0xE1 |
0xE1 |
0xE1 |
0xE1 |
0xE1 |
||
0x73 |
1 Byte WRITE : |
0x14 |
0x14 |
0x14 |
0x14 |
0x14 |
0x14 |
||
0x74 |
1 Byte WRITE : |
0x18 |
0x18 |
0x18 |
0x18 |
0x18 |
0x18 |
||
0x75 |
1 Byte WRITE : |
0x15 |
0x15 |
0x15 |
0x14 |
0x15 |
0x15 |
||
0x76..0x78 |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x79..0x7A |
2 bytes, WRITE : values 0x0000(myinit32), 0x2001(myinit33) |
0x0000 |
0x0000 |
0x2001 |
0x2001 |
0x2001 |
0x2001 |
||
0x7B..0x7F |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x80..0x83 |
4 Byte WRITE : two words values 0x0000 0x0000(myinit32), 0x3200 0x3300(myinit33), 0xaf00 0xb000(pv300dpi_20/21), 0xb000 0xb100(pv300dpi_22/23) |
0x0000 0x0000 |
0x3200 0x3300 |
0xB000 0xB100 |
0xAF00 0xB000 |
0xAF00 0xB000 |
0xAF00 0xB000 |
||
0x84 |
1 Byte READ : The software reads 0xb (11) bytes from this register on. Disassembly shows that only the last byte is used with 0x60 mask. If not set the lamp needs warming, If set, lamp is ready. 1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x85 |
1 Byte WRITE, values 0x00(myinit32), 0x06(myinit33), 0x0b(pv300dpi_20/21) |
0x00 |
0x00 |
0x46 |
0x46 |
0x46 |
0x46 |
||
0x86 |
1 Byte WRITE, values 0x00(myinit32), 0x06(myinit33), 0x0b(pv300dpi_20/21) |
0x00 |
0x06 |
0x0B |
0x0B |
0x0B |
0x0B |
||
0x87 |
1 Byte WRITE, values 0x00(myinit32/33), 0x8c(pv300dpi_20/21) |
0x00 |
0x00 |
0x8C |
0x8C |
0x8C |
0x8C |
||
0x88 |
1 Byte WRITE, values 0x00(myinit32), 0x06(myinit33), 0x10(pv300dpi_20/21) |
0x00 |
0x06 |
0x10 |
0x10 |
0x10 |
0x10 |
||
0x89 |
1 Byte WRITE, values 0x00(myinit32), 0x34(myinit33), 0xb1(pv300dpi_20/21), 0xb2(pv300dpi_24) |
0x00 |
0x34 |
0xB2 |
0xB1 |
0xB1 |
0xB1 |
||
0x8A |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x8B |
1 Byte WRITE : everytime 0xff |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
||
0x8C |
1 Byte WRITE : everytime 0x3f |
0x3F |
0x3F |
0x3F |
0x3F |
0x3F |
0x3F |
||
0x8D..0x8E |
1 Word WRITE, values 0x8068(myinit32), 0x3b60(pv300dpi_20) |
0x8086 |
0x8086 |
0x3B60 |
0x3B60 |
0x3B60 |
0x3B60 |
||
0x8F |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0x90 |
1 Byte WRITE, values 0x00(myinit32), 0x1c(myinit33), 0x18(pv300dpi_21,pv600dpi_11/12) |
0x00 |
0x1C |
0x1C |
0x18 |
0x18 |
0x18 |
||
0x91..0x92 |
2 bytes WRITE: Horizontal calibration goes here. WRITE_REGS : everytime 0x00 |
0x0000 |
0x0000 |
0x0000 |
0x0000 |
x00000 |
x00000 |
||
0x93 |
Vertical calibration goes here (number of lines to shift each color by) |
0x01 |
0x01 |
0x01 |
0x01 |
0x01 |
0x01 |
||
0x94 |
1 Byte WRITE: everytime 0x0e |
0x0E |
0x0E |
0x0E |
0x0E |
0x0E |
0x0E |
||
0x95..0xA2 |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xA3 |
1 Byte WRITE: Controls the clock? everytime 0xcc |
0xCC |
0xCC |
0xCC |
0xCC |
0xCC |
0xCC |
||
0xA4 |
1 Byte WRITE: everytime 0x27 |
0x27 |
0x27 |
0x27 |
0x27 |
0x27 |
0x27 |
||
0xA5 |
1 Byte WRITE: everytime 0x64 |
0x64 |
0x64 |
0x64 |
0x64 |
0x64 |
0x64 |
||
0xA6..0xAF |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xB0 |
1 Byte READ: this register is called from the function RT_CheckScannerLinked. It seems to always return 0x80. Test for b3 to go from 08 to 00 when the scanner finished moving and is ready. WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xB1 |
1 Byte WRITE: Mainboard ID (0..3). The windows driver read this register and use it to modify the values and is setting the CCDType, (1,2,3,4,6). WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xB2 |
1 Byte WRITE: used for moving: values 0x02(myinit32), 0x06(pv600dpi_02),switch on/off the green power LED |
0x02 |
0x02 |
0x02 |
0x02 |
0x02 |
0x02 |
||
0xB3 |
1 Byte WRITE: controls movement. The software seems to issue the sequence 02 00 08 to this register to start with movement. It then checks 08 to see if still moving. When the scanner stops moving it becomes 0. It is also possible to set it to 0 to stop the scanner. The register also need to be set to 0x04 before the button can be read. |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xB4..0xBD |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xBE |
1 Byte WRITE: values 0xff(myinit32), 0x06(myinit34,pv300dpi_20) |
0xFF |
0xFF |
0xFF |
0x06 |
0x06 |
0x06 |
||
0xBF |
1 Byte WRITE: values 0x0f(myinit32), 0xe6(myinit34,pv300dpi_20) |
0x0F |
0x0F |
0x0F |
0xE6 |
0xE6 |
0xE6 |
||
0xC0 |
1 Byte WRITE: values 0x00(myinit32), 0x67(myinit34,pv300dpi_20) |
0x00 |
0x00 |
0x00 |
0x67 |
0x67 |
0x67 |
||
0xC1..0xC8 |
1 Byte WRITE : |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
0xFF |
||
0xC9 |
1 Byte WRITE: values 0x00(myinit32), 0x07(myinit34,pv300dpi_20) |
0x00 |
0x00 |
0x00 |
0x07 |
0x07 |
0x07 |
||
0xCA |
1 Byte WRITE: values 0x0e(myinit32), 0x00(pv300dpi_20/21), 0x0e(pv300dpi_22) |
0x0E |
0x0E |
0x0E |
0x00 |
0x00 |
0x00 |
||
0xCB |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0xFE |
0xFE |
0xFE |
||
0xCC |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0xF9 |
0xF9 |
0xF9 |
||
0xCD |
1 Byte WRITE |
0xF0 |
0xF0 |
0xF0 |
0x19 |
0x19 |
0x19 |
||
0xCE |
1 Byte WRITE |
0xFF |
0xFF |
0xFF |
0x98 |
0x98 |
0x98 |
||
0xCF |
1 Byte WRITE |
0xF5 |
0xF5 |
0xF5 |
0xE8 |
0xE8 |
0xE8 |
||
0xD0..0xD1 |
2 Byte WRITE: Signed chars black level and white level. These control the intensities at which (FIX ME)? |
0xF7EA |
0xF7EA |
0xF7EA |
0xEAF3 |
0xEAF3 |
0xEAF3 |
||
0xD2 |
1 Byte WRITE |
0x0B |
0x0B |
0x0B |
0x14 |
0x14 |
0x14 |
||
0xD3 |
1 Byte WRITE |
0x03 |
0x03 |
0x17 |
0x02 |
0x02 |
0x02 |
||
0xD4 |
1 Byte WRITE |
0x05 |
0x05 |
0x01 |
0x04 |
0x04 |
0x04 |
||
0xD5 |
1 Byte WRITE: everytime 0x86 |
0x86 |
0x86 |
0x86 |
0x86 |
0x86 |
0x86 |
||
0xD6 |
1 Byte WRITE |
0x1B |
0xAB |
0x0F |
0x0F |
0x0F |
0x0F |
||
0xD7 |
1 Byte WRITE: everytime 0x30 |
0x30 |
0x30 |
0x30 |
0x30 |
0x30 |
0x30 |
||
0xD8 |
1 Byte WRITE |
0xF6 |
0xF6 |
0x52 |
0x52 |
0x52 |
0x52 |
||
0xD9 |
1 Byte WRITE: Turns on the lamp, with its MSB (Set to 0x80 for lamp on 0x00 for off).everytime 0xAD |
0xAD |
0xAD |
0xAD |
0xAD |
0xAD |
0xAD |
||
0xDA |
1 Byte WRITE: Controls
lamp brightness. Values (0xa0, 0xa7). |
0xA7 |
0xA7 |
0xA7 |
0xA7 |
0xA7 |
0xA7 |
||
0xDB..0xE1 |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xE2 |
1 Byte WRITE: Step
Size |
0x01 |
0x01 |
0x07 |
0x0F |
0x0F |
0x0F |
||
0xE3 |
1 Byte WRITE: values 0x00, 0x85(pv300dpi_20), 0x0d |
0x00 |
0x00 |
0x00 |
0x85 |
0x85 |
0x85 |
||
0xE4 |
1 Byte WRITE: values 0x00, 0x03(pv300dpi_20), 0x06 |
0x00 |
0x00 |
0x00 |
0x03 |
0x03 |
0x03 |
||
0xE5 |
1 Byte WRITE |
0x14 |
0x1C |
0x56 |
0x52 |
0x52 |
0x52 |
||
0xE6 |
1 Byte WRITE |
0x00 |
0x10 |
0x01 |
0x00 |
0x00 |
0x00 |
||
0xE7 |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0x75 |
0x75 |
0x75 |
||
0xE8 |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0x01 |
0x01 |
0x01 |
||
0xE9 |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0x0B |
0x0B |
0x0B |
||
0xEA |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0c54 |
0c54 |
0c54 |
||
0xEB |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0x01 |
0x01 |
0x01 |
||
0xEC |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0x04 |
0x04 |
0x04 |
||
0xED |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0xB8 |
0xB8 |
0xB8 |
||
0xEE |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xEF |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0x03 |
0x03 |
0x03 |
||
0xF0 |
1 Byte WRITE |
0x00 |
0x00 |
0x00 |
0x70 |
0x70 |
0x70 |
||
0xF1 |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
||
0xF2 |
1 Byte WRITE: switch on the burst mode? |
0x00 |
0x00 |
0x00 |
0x01 |
0x01 |
0x01 |
||
0xF3 |
1 Byte WRITE : everytime 0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
0x00 |
LCD display
In order to set the numbers on the
LCD:
transfer type=bulk size=5 ep=0x02 dir=OUT
88 b3 00 01
00
transfer type=bulk size=5 ep=0x02 dir=OUT
88 da 00 01
a7
transfer type=bulk size=6 ep=0x02 dir=OUT
88 20 00 02 ef df
Registers 0x20 and 0x21 control 7 bits each of the LCD. The 8'th
bit of 0x21
enables/disables the entire display:
Legend :
0x20 HGFEDCBA
0x21 76543210 (7 -enable)
5 6 4 0 |
|
2 3 F G |
1 D E |
|
H B C |
Last update Oct. 25, 2004 Johannes Hub