Hi, On Fri, Jun 25, 2004 at 12:16:27PM +0100, Ioan-Cosmin Pop wrote: > Henning, you keep telling me about the "protocol of > the scanner", "commands" and "registers". Can you > please tell me what they mean? OK, I know this sounds > stupid. I know what a protocol, command or register > is. Back in the good ol' DOS days (well, not so good, > but old for sure) I used to read/write to a specific > port and mess with the device registers (an aquisition > device in my case). I can only make some suppositions. > Please tell me if I'm correct and if I'm on the right > way. > - for the "protocol", I think this is something like: > buffered or direct;
No. What I mean by "protocol" is how the driver/backend communicates with the scanner. As an example, I'll describe the protocol of the GrandTech GT6801 chipset. Your scanner's protocol will be completely different most probably. Commands and data are sent to the scanner as USB control messages with a data size of 64 bytes. The request, request_type, value etc. depend on the type of command. E.g. you can send commands, receive results from commands, write data to scanner's RAM (firmware) and read from the RAM. This is an example for a command sent to the scanner (from a sniffusb log of a Mustek BearPaw 2400 TA Plus: | >>> URB 525 going down >>> | -- URB_FUNCTION_VENDOR_DEVICE: | TransferFlags = 00000000 | (USBD_TRANSFER_DIRECTION_OUT, ~USBD_SHORT_TRANSFER The data is sent from the host to the scanner. | TransferBufferLength = 00000040 64 bytes of data. | TransferBuffer = c1b6b000 | TransferBufferMDL = 00000000 | 0000: 20 01 0f 01 29 05 a4 00 58 02 82 20 64 00 01 00 The data itself. For the gt6801, the first byte is the command code. 0x20 means "setup scan". The second byte is alway 01. Bytes 2+3 and 3+4 are the Y coordinates of the scan widow (Y0 + height). The first byte is the low byte. In this case the height is 0x0529 = 1321. As these coordinates are based on 1200 dpi, the height is 1.1 inches in this case. Byte 0x0a ("82") means gray mode. Byte 0x0c ("64") and 0x0d ("00") are the resolution: 0x0064 = 100 dpi. | 0010: 64 00 73 00 0b 00 64 00 3c 00 00 00 00 00 00 00 | 0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | 0030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 More settings like lamp, backtracking, bytes per line etc. | UrbLink = 00000000 | RequestTypeReservedBits = 00 | Request = 01 | Value = 2010 That means "send a command". For writing firmware "200b" would be used. | Index = 3f40 Not used here but for firmware writes that would be the memory address to write to. Now the data is sent. As confirmation you get the URB back from the (Windows) operating system (see the same URB number): | <<< URB 525 coming back <<< | -- URB_FUNCTION_CONTROL_TRANSFER: | PipeHandle = C1AD431C | TransferFlags = 00000002 | (USBD_TRANSFER_DIRECTION_OUT, USBD_SHORT_TRANSFER_OK) | TransferBufferLength = 00000040 | TransferBuffer = c1b6b000 | TransferBufferMDL = c1800880 | UrbLink = 00000000 | SetupPacket : 40 01 10 20 40 3f 40 00 The setup packet is the same as above but this time it's not split in request, value etc. See the USB spec for details. Now we ask for the result of the command we just sent: | >>> URB 526 going down >>> | -- URB_FUNCTION_VENDOR_DEVICE: | TransferFlags = 00000001 | (USBD_TRANSFER_DIRECTION_IN, ~USBD_SHORT_TRANSFER_ We want to receive data from the scanner (DIRECTION_IN). | TransferBufferLength = 00000040 We want to get 64 bytes. | TransferBuffer = e3c09d1c | TransferBufferMDL = 00000000 | UrbLink = 00000000 | RequestTypeReservedBits = 00 | Request = 01 | Value = 2011 That means: "Read result of command". | Index = 3f00 See above. Ok, now the result: | <<< URB 526 coming back <<< | -- URB_FUNCTION_CONTROL_TRANSFER: | PipeHandle = C1AD431C | TransferFlags = 00000003 | (USBD_TRANSFER_DIRECTION_IN, USBD_SHORT_TRANSFER_OK) | TransferBufferLength = 00000040 | TransferBuffer = e3c09d1c | TransferBufferMDL = c1800880 | 0000: 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 The first 00 means that the command succeeded. The second byte "20" repeats the command we sent ("setup scan"). Other commands may return more data (e.g. the status of scan buttons or a flag if the scan head is at its home position). The actual scan data is read by bulk reads. That's what I mean by a "protocol". Other chipsets don't use commands (or functions) like in this case but you can set registers. E.g. you could use a three byte block of data sent by bulk messages: 01 02 03 01 --> type = write register 02 --> register number 03 --> value to write to the register That's just a protocolo I made up :-) > - for commands, I have some "IOCTL functions" > - as for "registers", I really have no idea. The scanner's chipset may have a buch of registers to which you can write data. E.g. One register may contain the resolution. When setting a bit in another register you could start scanning. Think of registers as processor registers. > What I have so far, are some macros (taken from the > windows sources), like IOCTL_GET_VERSION, > IOCTL_WRITE_REGISTERS, IOCTL_READ_REGISTERS and so on. Probably that's how the Windows low level scanner driver is accessed. This low level driver is able to do basic stuff like writing the scaynners registers. The higher level software talks to it via ioctls. (Just a guess but that's similar to how it works with Linux). > I think I really need some help, somebody to talk > to. Ronald Humphries, do you read this? If you do have > some spare time, can you please send me a message? I > can't send you the windows sources because I am bound > by an NDA (non-disclosure agreement) with Mustek, but > I'm sure we can cut a deal with them to offer you the > same info they gave me...:) Try to go down to the lowest level of the Windows source code. Look for functions that actually write to the scanner. Bye, Henning