#------------------------------------------ # Analysis of USB log file #------------------------------------------ The USB log is simply a sequence of commands send data from host to scanner and to read data from scanner to host. There are commands to set or get a single byte. And there are commands to read or write blocks of data. The first byte identifies 5 different commands. Possible command values are 00, 01, 02, 04 and 05. (Values are always written as hexadecimal number) The second byte defines the source or target address. The third (LO) and fourth (HI) byte defines the length of data. Length is calculated as dec(LO)+256*dec(HI) where dec() means a functions to convert the value from hexadecimal to decimal number. From the fifth byte on there is data if needed. To simplify reading I made some basic definitions. See next chapter below. Examples: 00 71 01 00 12 ( set 71 12 ) This is command 00 which sets register 71 to the value of 12. First shown is the byte sequence. The second line shows my function definition. Length of data is always one byte. Sequence is sent via endpoint 0x02. 01 34 01 00 ( get 34 ) This is command 01 which gets the value of register 34. No data byte added. But the length is 01 00 = 1 because command wants to read one byte from register. Sequence is sent via endpoint 0x02. Then a dummy block of N times 0x80 bytes is sent via endpoint 0x83. I investigated that this output is not necessary. A defined delay is also okay. The scanner then responds with one single byte at endpoint 0x03. The second line again shows my function definition. At the moment there is no variable assignment. Only structural analysis of log is discussed here. Note: The block sent is padded to a multiple of 128 bytes. It's always 0x200 bytes. I think it's for delaying. So the scanner has enough time to calculate the response. USB timing is used as reliable time base. 02 30 01 00 11 (set2 71 12 ) This is command 02 which sets register 30 to the value of 11. But this must be another register page or special command sequences. I don't know exactly at the moment. The difference to command 00 is more obvious if you count the appearences of that commands. Whereas command 00 is very frequently used with many different registers command 02 appears with only 5 different sequences. 02 30 01 00 11 02 38 01 00 89 02 39 01 00 40 02 3c 01 00 2f 02 64 01 00 20 04 70 00 01 00 01 02 03 04 05 06 07 08 09 0a 0b ... ( write "00 01 02 03 04 05 06 07 08 09 0a 0b ..." ) This is command 04 which writes a block of data to the scanner. This sequence is sent via endpoint 0x02. Probably this goes to the scanner RAM. Before this command is stated there can be seen many set commands. I think this is for selecting the target address. Note: the length of data is 00 01 means 0x100 = 256 byte. Block is padded to a multiple of 16 bytes. Here in this example it fits exactly. If data would be 60 bytes then length would be 3c 00 but the block transferred would be nevertheless 64 bytes with 4 bytes dummy data to pad the block. Function (write) calculates all this correctly and adds padding. 05 70 00 01 ( read 00 01 ) This is command 05 which reads a block of data from the scanner. No data byte added. But the length is 00 01 = 256 because command wants to read 256 bytes from scanner. Sequence is sent via endpoint 0x02. Then a dummy block of N x 0x80 bytes is sent via endpoint 0x83. (Dummy data not necessary as stated before). The scanner then responds with a block of bytes at endpoint 0x03. Every block is padded to a multiple of 128 bytes. The dummy block is never shorter than 0x200 bytes. I think it's for delay. The response data block could be as long as requested but it can be cut in shorter parts. If there are 0x680 bytes requested the response can for example return first 0x600 bytes and then 0x80 bytes. I think it's for speed. Always large block is transmitted and at the end the odd part with 0x80 bytes. #------------------------------------------ # FAQ #------------------------------------------ Q: The fourth parameter - the roll parameter (see image-show.pl) - have you found it to only be needed on preview images, or do some scans require it too? (Is it simply required as part of the way the image display tool works?) A: It's only for the display tool. Image data is not aligned correct and sometime data starts with false offset. This results in false colored pictures. Mostly it works with roll=0 what means parameter can be omitted. I used it only once to display my german post stamp scan. Q: In your analysis document, you refer to "slope tables" - what are these? A: The motor is not controlled directly. There are 5 curves to drive it smoothly. There's a curve for slow and fast moving. You set the number of the table you want to use and the chip does all the process automatically. Other scanner backends have to worry about all that low level things. This low level things are hidden behind the philips CP2155BE chip inside LiDE70/600F. What's behind is not known. Maybe there's something like a GL841, GL842, GL843 or GL845 from genesys logic because they also have 5 motor curve tables. Only GL842, GL843 and GL845 seem possible because they are ready for supporting CIS or CCD image sensors with 4800 dpi resolution. Look at the functions send_slope_tableXX where XX = 01..10. You'll remark an alternating pattern every two bytes. I show the log data here so you'll get the whole context. In send_slope_tableXX only the curve data is shown. _CMD_ _LEN_ LO HI LO HI LO HI LO HI ... 00000000: 04 70 48 00 80 25 58 25 32 25 0b 25 e5 24 c0 24 00000010: 9a 24 75 24 50 24 2b 24 07 24 e3 23 bf 23 9c 23 00000020: 79 23 56 23 33 23 11 23 ee 22 cd 22 ab 22 8a 22 00000030: 68 22 48 22 27 22 07 22 e6 21 c7 21 a7 21 87 21 00000040: 68 21 49 21 2a 21 0c 21 ee 20 d0 20 48 49 4a 4b 00000050: 4c 4d 4e 4f ^^^^^ _CMD_ is the command to transfer a block of data. _LEN_ is the length of data block. 80 25 means 0x2580 58 25 means 0x2558 32 25 means 0x2532 ... Where's the last word? It's this: d0 20 means 0x20d0 Okay 0x48 = 72 byte -> 72/2 = 36 words. And there is "48 49 4a 4b 4c 4d 4e 4f" which means 8 bytes trash. This is padding to a multiple of 0x10 bytes. And so _LEN_ = 0x0048 means that there has to be 8 bytes padding to get 0x0050 bytes which is tranferred in this block. You can convert this numbers to decimal and put them in a spreadsheet (eg. excel) and let the program draw a diagram of this values. You'll see a curve. This is the motor curve with which the DACs of the motor drivers are fed. Something based on 1/exp(...) or similar. You can look in the doku of other projects. Motor curves are described there. But the tables are not complete curves. They are just dots of a polygon and must be linear interpolated to get all values to set the motor table memory. But this is done by the chip in the scanner. We have not to do this. That's good with this scanner. The other backends have to calculate this :-) Okay, another example: _CMD_ _LEN_ LO HI LO HI ...trash... 00000000: 04 70 04 00 80 25 01 00 04 05 06 07 08 09 0a 0b 00000010: 0c 0d 0e 0f _LEN_ = 4 Okay 0x0004 = 4 bytes -> 4/2 = 2 words Hey ho, only 2 points! Yes, right. This is the minimum to set a polynom. Just start and end point given. So this is just a line. And 4 bytes mean 16-4 = 12 bytes trash. #------------------------------------------ # Basic function definitions #------------------------------------------ def set ( reg val ) { 00 reg 01 00 val } def get ( reg ) { 01 reg 01 00 } def set2 ( reg val ) { 02 reg 01 00 val } def write ( @data ) { LO = @data & 0xff HI = @data >> 8 @pad = padding to fit xxx0 04 70 LO HI @data @pad } def read ( LO HI ) { 05 70 LO HI } #------------------------------------------ # High level function definitions #------------------------------------------ def block1 ( v001 v004 v005 @data ) { LO = @data & 0xff HI = @data >> 8 pgLO,pgHI = LO,HI + padding to fit xxx0 ( set 71 01 ) (set2 30 11 ) ( set 71 v001 ) ( set 72 pgHI ) ( set 73 pgLO ) ( set 74 v004 ) ( set 75 v005 ) ( set 76 00 ) (set2 39 40 ) (set2 38 89 ) (set2 3c 2f ) (set2 64 20 ) ( write @data ) } def block2 ( v001 ) { ( block1 16 00 v001 "00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d 8e 8f 90 91 92 93 94 95 96 97 98 99 9a 9b 9c 9d 9e 9f a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 ca cb cc cd ce cf d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 da db dc dd de df e0 e1 e2 e3 e4 e5 e6 e7 e8 e9 ea eb ec ed ee ef f0 f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb fc fd fe ff" ) } def send_slope_table01 ( v001 ) { ( block1 14 03 v001 "80 25 74 25 68 25 5c 25 51 25 45 25 3a 25 2e 25 23 25 17 25 0c 25 00 25 f5 24 ea 24 de 24 d3 24 c8 24 bc 24 b1 24 a6 24 9b 24 90 24 85 24 79 24 6e 24 63 24 58 24 4d 24 42 24 37 24 2c 24 22 24 17 24 0c 24 01 24 f6 23 ec 23 e1 23 d6 23 cb 23 c1 23 b6 23 ab 23 a1 23 96 23 8c 23 81 23 77 23 6c 23 62 23 57 23 4d 23 43 23 38 23 2e 23 24 23 19 23 0f 23 05 23 fb 22 f1 22 e6 22 dc 22 d2 22 c8 22 be 22 b4 22 aa 22 a0 22 96 22 8c 22 82 22 78 22 6e 22 64 22 5b 22 51 22 47 22 3d 22 33 22 2a 22 20 22 16 22 0d 22 03 22 f9 21 f0 21 e6 21 dd 21 d3 21 c9 21 c0 21 b7 21 ad 21 a4 21 9a 21 91 21 87 21 7e 21 75 21 6b 21 62 21 59 21 50 21 46 21 3d 21 34 21 2b 21 22 21 18 21 0f 21 06 21 fd 20 f4 20 eb 20 e2 20 d9 20 d0 20 c7 20 be 20 b5 20 ac 20 a3 20 9b 20 92 20 89 20 80 20 77 20 6f 20 66 20 5d 20 54 20 4c 20 43 20 3a 20 32 20 29 20 20 20 18 20 0f 20 07 20 fe 1f f6 1f ed 1f e5 1f dc 1f d4 1f cb 1f c3 1f bb 1f b2 1f aa 1f a1 1f 99 1f 91 1f 89 1f 80 1f 78 1f 70 1f 68 1f" ) } def send_slope_table02 ( v001 ) { ( block1 14 03 v001 "80 25 d9 24 38 24 9d 23 07 23 75 22 e9 21 60 21 dc 20 5c 20 e0 1f 68 1f" ) } def send_slope_table03 ( v001 ) { ( block1 14 03 v001 "80 25 01 00" ) } def send_slope_table04 ( v001 ) { ( block1 14 03 v001 "80 25 0a 00 05 00 03 00 02 00 02 00 01 00 01 00 01 00 01 00 01 00 01 00" ) } def send_slope_table05 ( v001 ) { ( block1 14 03 v001 "80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25 80 25" ) } def send_slope_table06 ( v001 ) { ( block1 14 03 v001 "80 25 93 21 65 1e c3 1b 8d 19 ab 17 0a 16 a0 14 61 13 46 12 4a 11 68 10" ) } def send_slope_table07 ( v001 ) { ( block1 14 03 v001 "00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 00 32 bc 30 89 2f 64 2e 4d 2d 43 2c 45 2b 52 2a 69 29 8a 28 b5 27 e8 26 23 26 66 25 af 24 00 24 57 23 b5 22 17 22 80 21 ee 20 60 20 d7 1f 53 1f d3 1e 57 1e de 1d 6a 1d f9 1c 8b 1c 20 1c b9 1b 54 1b f3 1a 93 1a 37 1a dd 19 85 19 30 19 dd 18 8c 18 3d 18 f0 17 a5 17 5c 17 14 17 ce 16 8a 16 47 16 06 16 c7 15 88 15 4b 15 10 15 d6 14 9d 14 65 14 2e 14 f9 13 c4 13 91 13 5f 13 2d 13 fd 12 ce 12 9f 12 72 12 45 12 19 12 ee 11 c4 11 9a 11 71 11 49 11 22 11 fb 10 d5 10 b0 10 8c 10 68 10" ) } def send_slope_table08 ( v001 ) { ( block1 14 03 v001 "00 32 27 2a 6f 24 15 20 a8 1c e5 19 9e 17 b5 15 16 14 b0 12 79 11 68 10" ) } def send_slope_table09 ( v001 ) { ( block1 14 03 v001 "80 25 00 25 84 24 0b 24 96 23 23 23 b3 22 46 22 db 21 73 21 0e 21 ab 20 4a 20 eb 1f 8f 1f 34 1f dc 1e 85 1e 31 1e de 1d 8d 1d 3e 1d f0 1c a4 1c 59 1c 10 1c c9 1b 83 1b 3e 1b fa 1a b8 1a 77 1a 38 1a f9 19 bc 19 80 19 44 19 0a 19 d1 18 99 18 62 18 2c 18 f7 17 c3 17 8f 17 5d 17 2b 17 fa 16 ca 16 9b 16 6c 16 3e 16 11 16 e5 15 b9 15 8e 15 64 15 3a 15 11 15 e9 14 c1 14 9a 14 73 14 4d 14 27 14 02 14 de 13 ba 13 96 13 74 13 51 13 2f 13 0d 13 ec 12 cc 12 ab 12 8c 12 6c 12 4d 12 2f 12 11 12 f3 11 d5 11 b8 11 9c 11 80 11 64 11 48 11 2d 11 12 11 f7 10 dd 10 c3 10 a9 10 90 10 77 10 5e 10 46 10 2e 10 16 10 fe 0f e7 0f d0 0f b9 0f a2 0f 8c 0f 76 0f 60 0f 4b 0f 35 0f 20 0f 0b 0f f7 0e e2 0e ce 0e ba 0e a6 0e 92 0e 7f 0e 6c 0e 59 0e 46 0e 33 0e 21 0e 0f 0e fd 0d eb 0d d9 0d c8 0d b6 0d a5 0d 94 0d 83 0d 73 0d 62 0d 52 0d 41 0d 31 0d 22 0d 12 0d 02 0d f3 0c e3 0c d4 0c c5 0c b6 0c a7 0c 99 0c 8a 0c 7c 0c 6e 0c 60 0c 52 0c 44 0c 36 0c 28 0c 1b 0c 0d 0c 00 0c f3 0b e6 0b d9 0b cc 0b bf 0b b3 0b a6 0b 9a 0b 8e 0b 81 0b 75 0b 69 0b 5d 0b 52 0b 46 0b 3a 0b 2f 0b 23 0b 18 0b 0d 0b 02 0b f6 0a eb 0a e1 0a d6 0a cb 0a c0 0a b6 0a ab 0a a1 0a 97 0a 8c 0a 82 0a 78 0a 6e 0a 64 0a 5a 0a 50 0a 47 0a 3d 0a 33 0a 2a 0a 20 0a 17 0a 0e 0a 04 0a fb 09 f2 09 e9 09 e0 09 d7 09 ce 09 c6 09 bd 09 b4 09 ab 09 a3 09 9a 09 92 09 8a 09 81 09 79 09 71 09 69 09 61 09 59 09 51 09 49 09 41 09 39 09 31 09 29 09 22 09 1a 09 12 09 0b 09 03 09 fc 08 f5 08 ed 08 e6 08 df 08 d8 08 d0 08 c9 08 c2 08 bb 08 b4 08 ad 08 a6 08 a0 08" ) } def send_slope_table10 ( v001 ) { ( block1 14 03 v001 "80 25 c0 1c 4f 17 9a 13 e9 10 de 0e 44 0d fa 0b ea 0a 07 0a 46 09 a0 08" ) } def set_regs ( v001..v120 ) { # Variations of values ( set 07 v001 ) # 00 ( set 07 v002 ) # 00 ( set 08 v003 ) # 01 0b ( set 09 v004 ) # 3b b3 e3 ( set 0a v005 ) # 01 02 0c ( set 0b v006 ) # 22 32 3a d2 ( set a0 v007 ) # 04 05 1d ( set a1 v008 ) # 00 ( set a2 v009 ) # 00 01 03 ( set a3 v010 ) # 10 70 90 ( set 64 v011 ) # 00 ( set 65 v012 ) # 00 ( set 61 v013 ) # 00 ( set 62 v014 ) # 15 29 2e ( set 63 v015 ) # 00 e0 ( set 50 v016 ) # 00 04 ( set 50 v017 ) # 00 04 ( set 90 v018 ) # 27 b8 e8 ea f0 f8 fa ( set 51 v019 ) # 07 ( set 5a v020 ) # ff ( set 5b v021 ) # ff ( set 5c v022 ) # ff ( set 5d v023 ) # ff ( set 52 v024 ) # 00 0a ( set 53 v025 ) # 01 f0 ( set 54 v026 ) # 00 0a ( set 55 v027 ) # 01 f0 ( set 56 v028 ) # 00 0a ( set 57 v029 ) # 01 f0 ( set 58 v030 ) # 00 ( set 59 v031 ) # 01 ( set 5e v032 ) # 02 ( set 5f v033 ) # 00 03 ( set 5f v034 ) # 00 03 ( set 60 v035 ) # 00 01 ( set 60 v036 ) # 00 01 ( set 60 v037 ) # 00 01 ( set 60 v038 ) # 00 01 ( set 50 v039 ) # 00 04 ( set 51 v040 ) # 07 ( set 81 v041 ) # 30 31 ( set 81 v042 ) # 30 31 ( set 82 v043 ) # 10 11 ( set 82 v044 ) # 10 11 ( set 83 v045 ) # 01 ( set 84 v046 ) # 05 ( set 80 v047 ) # 10 12 ( set 80 v048 ) # 10 12 ( set b0 v049 ) # 00 01 03 ( set 10 v050 ) # 00 04 05 0d 15 1d ( set 10 v051 ) # 00 04 05 0d 15 1d ( set 10 v052 ) # 00 04 05 0d 15 1d ( set 10 v053 ) # 00 04 05 0d 15 1d ( set 11 v054 ) # 00 21 25 35 41 61 80 81 82 83 91 93 c1 c3 d1 ( set 11 v055 ) # 00 21 25 35 41 61 80 81 82 83 91 93 c1 c3 d1 ( set 11 v056 ) # 00 21 25 35 41 61 80 81 82 83 91 93 c1 c3 d1 ( set 11 v057 ) # 00 21 25 35 41 61 80 81 82 83 91 93 c1 c3 d1 ( set 11 v058 ) # 00 21 25 35 41 61 80 81 82 83 91 93 c1 c3 d1 ( set 11 v059 ) # 00 21 25 35 41 61 80 81 82 83 91 93 c1 c3 d1 ( set 11 v060 ) # 00 21 25 35 41 61 80 81 82 83 91 93 c1 c3 d1 ( set 12 v061 ) # 01 10 40 50 7d ( set 13 v062 ) # 00 01 10 50 7d ( set 16 v063 ) # 01 10 40 50 7d ( set 21 v064 ) # 06 ( set 22 v065 ) # 01 10 40 50 7d ( set 20 v066 ) # 06 ( set 1d v067 ) # 00 ( set 1e v068 ) # 00 03 36 ( set 1f v069 ) # 02 04 d0 d2 e8 ( set 66 v070 ) # 00 ( set 67 v071 ) # 00 01 ( set 68 v072 ) # 06 80 ( set 1a v073 ) # 00 ( set 1b v074 ) # 00 ( set 1c v075 ) # 02 ( set 15 v076 ) # 01 80 83 ( set 14 v077 ) # 01 79 7c ( set 17 v078 ) # 01 02 ( set 43 v079 ) # 1c ( set 44 v080 ) # 9c ( set 45 v081 ) # 38 ( set 23 v082 ) # 05 0d 0a ( set 33 v083 ) # 05 0d 0a ( set 24 v084 ) # 05 0d 0a ( set 34 v085 ) # 05 0d 0a ( set 25 v086 ) # 05 0d 0a ( set 35 v087 ) # 05 0d 0a ( set 26 v088 ) # 05 0d 0a ( set 36 v089 ) # 05 0d 0a ( set 27 v090 ) # 05 0d 0a ( set 37 v091 ) # 05 0d 0a ( set 28 v092 ) # 05 0d 0a ( set 38 v093 ) # 05 0d 0a ( set 29 v094 ) # 05 0d 0a ( set 39 v095 ) # 05 0d 0a ( set 2a v096 ) # 05 0d 0a ( set 3a v097 ) # 05 0d 0a ( set 2b v098 ) # 05 0d 0a ( set 3b v099 ) # 05 0d 0a ( set 2c v100 ) # 05 0d 0a ( set 3c v101 ) # 05 0d 0a ( set 2d v102 ) # 05 0d 0a ( set 3d v103 ) # 05 0d 0a ( set 2e v104 ) # 05 0d 0a ( set 3e v105 ) # 05 0d 0a ( set 2f v106 ) # 05 0d 0a ( set 3f v107 ) # 05 0d 0a ( set 30 v108 ) # 05 0d 0a ( set 40 v109 ) # 05 0d 0a ( set 31 v110 ) # 05 0d 0a ( set 41 v111 ) # 05 0d 0a ( set 32 v112 ) # 05 0d 0a ( set 42 v113 ) # 05 0d 0a ( set ca v114 ) # 00 ( set ca v115 ) # 00 ( set ca v116 ) # 00 ( set 18 v117 ) # 00 } def block4 ( v001 ) { ( set 90 ea ) ( set 9b 07 ) ( set 9b 05 ) ( set 9b 07 ) ( set 9b 05 ) ( set 90 fa ) ( set b0 v001 ) } def block5 ( v001 ) { ( set 90 e8 ) ( set 9b 06 ) ( set 9b 04 ) ( set 90 f8 ) ( set b0 v001 ) } def block6 ( v001 v002 ) { ( set 80 v001 ) ( set 11 v002 ) } def block7 ( v001 v002 v003 ) { ( block6 v001 v002 ) ( set 9b v003 ) } def block8 ( ) { ( set 04 0c ) ( set 05 00 ) ( set 06 00 ) } def block9 ( ) { ( block2 00 ) # ADDR=000000 ( block2 01 ) # ADDR=000100 ( block2 02 ) # ADDR=000200 } def motor ( v001 v002 ) { ( set 10 v001 ) ( get 4a ) ( get 4b ) ( get 4c ) ( set 11 v002 ) ( set 60 01 ) ( set 80 12 ) ( set 03 01 ) # start motor } def read_buttons { ( get 91 ) # check for pressed buttons } #------------------------------------------ # USB log starts here #------------------------------------------ ( get d0 ) ( get 46 ) ( set 02 01 ) ( set 02 00 ) ( set 01 00 ) ( set 01 28 ) ( set a0 04 ) ( set a0 05 ) ( set 01 28 ) ( block8 ) ( set 90 27 ) ( set 92 f7 ) ( set 94 f7 ) ( read_buttons ) ( set 93 00 ) ( set 91 1f ) ( set 95 0f ) ( set 97 0f ) ( set 9b 00 ) ( set 9c 07 ) ( set 90 f0 ) ( set 9b 04 ) ( set 98 00 ) ( set 98 00 ) ( set 98 02 ) ( set 99 3b ) ( set 9a 03 ) ( set 80 10 ) ( set 8d 00 ) ( set 8d 04 ) ( get 8b ) ( get 8b ) ( set 85 00 ) ( set 87 00 ) ( set 88 70 ) ( get 8b ) ( get 8b ) ( set 85 03 ) ( set 87 00 ) ( set 88 00 ) ( get 8b ) ( get 8b ) ( set 85 06 ) ( set 87 00 ) ( set 88 88 ) # read whole register page from 0x00 to 0xfe ( get 00 ) # ... ( get fe ) ( set 60 01 ) ( set 90 f8 ) ( set 60 01 ) ( set 9b 04 ) ( get 46 ) ( block7 12 00 05 ) ( set 90 fa ) ( get 46 ) ( block6 12 00 ) ( set 01 28 ) ( block8 ) ( set 01 29 ) ( block9 ) ( block4 00 ) ( set_regs 00 00 01 e3 02 22 1d 00 01 90 00 00 00 29 e0 00 00 fa 07 ff ff ff ff 00 01 00 01 00 01 00 01 02 00 03 01 01 01 01 04 07 30 31 10 11 01 05 12 12 00 00 00 00 04 80 80 80 80 80 82 83 50 50 50 06 50 06 00 00 d2 00 00 06 00 00 02 80 79 02 1c 9c 38 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 00 00 00 00 ) ( send_slope_table01 00 ) # ADDR=030000 ( send_slope_table01 02 ) # ADDR=030200 ( send_slope_table02 04 ) # ADDR=030400 ( send_slope_table01 06 ) # ADDR=030600 ( send_slope_table02 08 ) # ADDR=030800 ( motor 05 93 ) ( get 46 ) # 5x ( block7 12 83 05 ) ( get 46 ) ( block6 12 83 ) ( set 01 29 ) ( block8 ) ( set 01 29 ) ( block9 ) ( block4 00 ) ( set_regs 00 00 01 e3 02 22 1d 00 01 90 00 00 00 29 e0 04 04 fa 07 ff ff ff ff 00 01 00 01 00 01 00 01 02 00 03 01 01 01 01 04 07 31 31 11 11 01 05 12 12 00 05 0d 0d 0d 83 83 83 83 83 81 81 50 50 50 06 50 06 00 00 d2 00 00 06 00 00 02 80 79 02 1c 9c 38 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 05 00 00 00 00 ) ( send_slope_table01 00 ) # ADDR=030000 ( send_slope_table01 02 ) # ADDR=030200 ( send_slope_table02 04 ) # ADDR=030400 ( send_slope_table01 06 ) # ADDR=030600 ( send_slope_table02 08 ) # ADDR=030800 ( motor 0d 91 ) ( get 46 ) # 10x ( block7 12 81 04 ) ( set 90 f8 ) ( get 46 ) ( block6 12 81 ) ( read_buttons ) ( set 90 f8 ) ( get 46 ) # 3x ( block6 12 81 ) ( set 01 29 ) ( block8 ) ( set 01 29 ) ( block9 ) ( set_regs 00 00 01 b3 01 d2 1d 00 00 10 00 00 00 2e 00 04 04 f8 07 ff ff ff ff 00 01 00 01 00 01 00 01 02 00 03 01 01 01 01 04 07 31 31 11 11 01 05 12 12 00 1d 15 15 15 81 81 81 81 81 83 83 01 01 01 06 01 06 00 00 02 00 00 06 00 00 02 83 7c 02 1c 9c 38 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 00 00 00 00 ) ( send_slope_table03 00 ) # ADDR=030000 ( send_slope_table03 02 ) # ADDR=030200 ( send_slope_table04 04 ) # ADDR=030400 ( send_slope_table03 06 ) # ADDR=030600 ( send_slope_table04 08 ) # ADDR=030800 ( motor 15 93 ) ( set 90 f8 ) ( get 46 ) # 3x ( block6 12 83 ) ( set 01 29 ) ( block8 ) ( set 01 29 ) ( block9 ) ( block5 01 ) ( set_regs 00 00 01 b3 01 d2 1d 00 00 70 00 00 00 15 e0 04 04 f8 07 ff ff ff ff 00 01 00 01 00 01 00 01 02 00 03 01 01 01 01 04 07 31 31 11 11 01 05 12 12 01 05 05 05 05 83 83 83 83 83 83 83 10 10 10 06 10 06 00 03 e8 00 00 06 00 00 02 83 7c 02 1c 9c 38 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 00 00 00 00 ) ( send_slope_table05 00 ) # ADDR=030000 ( send_slope_table05 02 ) # ADDR=030200 ( send_slope_table06 04 ) # ADDR=030400 ( send_slope_table05 06 ) # ADDR=030600 ( send_slope_table06 08 ) # ADDR=030800 ( motor 05 93 ) ( get 46 ) # 3x ( block6 12 83 ) ( set 90 f8 ) ( get 46 ) # 3x ( block6 12 83 ) ( get 46 ) ( set 01 29 ) ( block8 ) ( set 01 29 ) ( block9 ) ( block5 01 ) ( set_regs 00 00 0b 3b 0c 3a 1d 00 03 10 00 00 00 15 e0 04 04 f8 07 ff ff ff ff 0a f0 0a f0 0a f0 00 01 02 00 03 01 01 01 01 04 07 31 31 11 11 01 05 12 12 01 05 05 05 05 83 83 c3 c3 c3 c1 c1 40 00 40 06 40 06 00 00 04 00 01 80 00 00 02 01 01 01 1c 9c 38 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 0a 00 00 00 00 ) ( send_slope_table07 00 ) # ADDR=030000 ( send_slope_table07 02 ) # ADDR=030200 ( send_slope_table08 04 ) # ADDR=030400 ( send_slope_table07 06 ) # ADDR=030600 ( send_slope_table08 08 ) # ADDR=030800 ( set 90 fa ) ( motor 05 d1 ) ( set 71 01 ) (set2 30 11 ) ( set 71 18 ) ( set 72 00 ) ( set 73 10 ) (set2 39 40 ) (set2 38 89 ) (set2 3c 2f ) (set2 64 20 ) ( get a5 ) #\ This whole block is repeated many times. ( get a6 ) #| It requests if there is any scan data. The length of available ( get a7 ) #| data is returned with 3 bytes (every get returns 1 byte, higher to lower). ( set 72 01 ) #| Has to be multiplied with 2 to give data length. ( set 73 00 ) #| Byte counter is set to length. ( read LO HI ) #/ Then the data is fetched. ( set 90 f8 ) ( get 46 ) # 2x ( block6 12 c1 ) ( get 46 ) ( block6 12 c1 ) ( read_buttons ) ( set 90 f8 ) ( get 46 ) # 3x ( block6 12 c1 ) ( set 01 29 ) ( block8 ) ( set 01 29 ) ( block9 ) ( block5 03 ) ( set_regs 00 00 01 b3 02 32 1d 00 00 70 00 00 00 2e 00 04 04 f8 07 ff ff ff ff 00 01 00 01 00 01 00 01 02 00 03 01 01 01 01 04 07 31 31 11 11 01 05 12 12 03 05 05 05 05 41 61 21 21 25 25 25 7d 7d 7d 06 7d 06 00 36 d0 00 00 06 00 00 02 83 7c 02 1c 9c 38 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 0d 00 00 00 00 ) ( send_slope_table09 00 ) # ADDR=030000 ( send_slope_table09 02 ) # ADDR=030200 ( send_slope_table10 04 ) # ADDR=030400 ( send_slope_table09 06 ) # ADDR=030600 ( send_slope_table10 08 ) # ADDR=030800 ( motor 05 35 ) ( get 46 ) # 7x ( block6 12 25 ) ( set 80 12 ) ( get 46 ) ( block6 12 25 ) ( get 90 ) ( get 90 ) ( set 9b 00 ) ( set 60 00 ) ( set 90 b8 ) ( read_buttons ) ...