CONNECTION AND COMMAND PROTOCOLS OF THE MARS MR97310
Theodore Kilgore <kilgota@auburn.edu> April, 2004.

(This camera library and all files in it carry the LGPL license;
see any of the source files for a more complete statement.)


Peculiarly, the MR97310 camera uses bulk endpoint 0x04 (out) to receive
commands, sending back its responses over bulk endpoint 0x83 (in). Then, it
uses bulk endpoint 0x82 (in) to send data to the computer. The driver has to 
switch the pipe appropriately. A command is a bulk write operation of one or 
two bytes, with the first byte being 0x19. All requests to read a block or 
blocks of data are performed by sending only the single byte 0x19. Otherwise,  
the second byte can apparently be either a command, or part of a sequence 
giving information.

A command is usually followed by a read request for confirmation. The read 
request is of a bulk write of the one byte 0x21. The camera responds by 
sending 16 bytes, in which only the first byte is significant. 

When the single byte 0x19 is sent with no second byte, immediate intention to 
download data is signalled. The 0x19 which is sent must be followed by an 0x21 
read request for confirmation. If the response is correct (must begin with 
0xa8), then the pipe must be switched to 0x82 and the download may be carried 
out by repetition of

gp_port_read(port,data,size); (where maximum size is 0x2000),

until the intended amount of data has been read. After the data has been
successfully read, the pipe must be switched back to 0x83 for the next
command sequence. 

To summarize: bulk inep 0x83 is for receiving responses to commands; bulk 
inep 0x82 is for receiving data, and bulk outep 0x04 is for sending commands. 
The camera also has bulk pipe 0x07, which one would reasonably expect could be 
used to write data to the camera. However, it is not obvious how to do that. 
It may not be possible. 

The observed command sequences sent to the camera are:

19 51	(starts the initialization sequence, any data download
initialization sequence, and the exit sequence)

19 b5	(appears during initialization; could also be part of a memory
address)

19 0f	(flag instructing to move to a memory location which will be
sent to the camera in immediately subsequent communications)

19 54	(computer's acknowledgement to camera that a data download has just
been successfully completed)

19 ba  (flag indicating that memory location should be reset, on exit;
followed by instructions to reset memory pointer to 00 00).

Other things are instructions to go to a memory location. For example, to
download the first photo in the camera, which begins at memory block 0x400,
the sequence is

send 19 0f
send 21, read response
send 19 00
send 21, read response
send 19 04 
send 21, read response; do this repeatedly until first byte of response is
0x0a, then proceed with next command. My conjecture is that this sequence of
read requests is causing the memory pointer to move to the right place,
which is registered as done when the 0x0a comes up. 

After the memory pointer has been successfully moved, the camera must be
told several other things, by sending one byte at a time, ending with an
indication of how big is the photo to be downloaded. For example, if a photo
is 640x480 pixels, equal to 4b000 bytes, then the sequence 

19 b0
21, read response
19 04
21, read response

must be sent. Where this comes from is presented in the next section.


THE CONFIGURATION DATA

The MR973120 camera uses a block of configuration data of size 0x2000, which 
is downloaded during the initialization of the camera. Here is a sample of the 
first few, relevant lines from the configuration data. We have 9 photos in the 
camera. 


0000  ff 00 ff 00 ff 00 ff 01-00 00 00 00 00 00 00 00  
0010  08 00 04 00 0c b0 04 cc-86 13 9a 00 0c 2c 01 6c  
0020  06 a6 bf 00 0c 2c 01 a4-88 39 e5 00 0c b0 04 66  
0030  06 4c 7b 01 0c 2c 01 07-86 df a0 01 0c 2c 01 3f  
0040  08 72 c6 01 0c b0 04 01-88 85 5c 02 0c b0 04 2b  
0050  08 98 f2 02 0c b0 04 54-ff ff ff ff ff ff ff ff  
0060  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff  


Line 0000 is always the same (or should be -- see next section). 
The first block of 8 bytes seems to be a marker signifying the configuration 
block. The second eight-byte block may, it will become later apparent, refer 
to some data about the block itself -- its type and its memory
location, perhaps. This would seem paradoxical since one can not know the
configuration data before downloading it, but not all in life is logical.


Lines 0010 through 0050 give data about the photos. There are nine photos in
the camera in this sample. When we reach byte 0x58 and begin repeating 0xff, 
we finished reading about these nine photos. Thus, each block of 8 bytes says 
something about a photo, until the repetition of 0xff begins. After this  
the rest of the configuration data is simply junk. 

Let's rearrange the sample, throwing away the unhelpful line 0000 and also 
terminating after byte 0x57:

photo   1	08 00 04 00 0c b0 04 cc
	2	86 13 9a 00 0c 2c 01 6c  
	3	06 a6 bf 00 0c 2c 01 a4
	4	88 39 e5 00 0c b0 04 66  
	5	06 4c 7b 01 0c 2c 01 07
	6	86 df a0 01 0c 2c 01 3f  
	7	08 72 c6 01 0c b0 04 01
	8	88 85 5c 02 0c b0 04 2b  
	9	08 98 f2 02 0c b0 04 54

(the columns in this table are numbered from 0 to 7 in what follows)

In this pattern, the entry in the zeroeth column is a code which refers to the
size of the photo and also indicates whether there is compression, or not. In 
this particular example, none of the photos are compressed. The entries ending 
in 8 indicate size 640x480, and those ending in 6 indicate size 320x240. 
Furthermore, each photo consists of a number of bytes equal to the product of 
its dimensions. For a 640x480 photo, the number of bytes is 0x4b000, and 
for a 320x240 photo is the number is 0x12c00. Why it is that 08 and 88 both 
signify 640x480 and 06 and 86 both signify 320x240, is not clear. Which of the 
two used would seem to depend only upon whether the photo is listed in the left 
half of a line, or in the right half. 

The entries in columns 1, 2, and 3 of our rearranged data seem to indicate the 
storage location, in (hexadecimal) little endian format. Comparison of these 
numbers to the sizes of photos and to the size of the configuration data and 
to the advertised 8 Meg size of the RAM in the camera would seem to imply 
that the memory is addressed as storage blocks, or words, of size 8 bytes. For 
example, the configuration data, of size 0x2000, would require  
0x2000/8 = 0x400 storage blocks, and the beginning point for the first photo is 
listed as location 0x400. Also, the fact that three bytes are used for the 
storage location indicates that the maximum size of memory which can be 
addressed under this scheme is 8*16*16*16 bytes. That is, 32 megabytes.  

Column 4 seems to contain a marker or "magic number" indicating that
the data comprises a photo. For, following this logic, the block 

		00 00 00 00 00 00 00 00

in line 0000 would seem to provide information about the configuration data
block. According to this analysis, the zeroeth 00 would indicate that the data
is configuration data, not a photo. The first and second and third 00 bytes 
would indicate that the config data starts at memory block 00 00 00, and byte 
four would then presumably give 00 as a marker for config data. On the other
hand, the fourth byte of configuration data for a photo is always 0xc0. 

The entries in the fifth and sixth indicate, again in little endian form, the 
number of bytes, times 0x100, which must be downloaded for the given photo. 
For example, we already know that photo 1 is 640x480 and is thus of size 
0x4b000; these bytes here read b0 04. And for photo 2, which is 320x240 and 
thus of size 0x12c00 these bytes read 01 2c. Rather strangely, we have a 
situation in which the memory allocation units seem to be of size 8 bytes each. 
However, the smallest possible unit which can be downloaded is apparently of 
size 0x100=256 bytes. A strange inconsistency. 

Finally, for the seventh column there is at this time no obvious 
interpretation. Perhaps it has to do with brightness, contrast, or gamma factor.
The assumption that it has something to do with the gamma factor is here built
into the code, and that assumption does seem to improve the photos. 

A DATA CORRUPTION PROBLEM

An example of what the same config data can look like if gphoto2 is run
twice without replugging the camera in between, is as follows:


0000  5c 73 60 73 5c 71 5d 6e-5c 72 5d 6c 5c 70 5b 6e  
0010  5d 71 5b 71 5e 71 5c 71-5c 72 5d 6e 5c 72 5e 71  
0020  5c 6f 59 6f 58 67 49 4c-38 43 3a 4c 43 59 49 5b  
0030  4b 5d 51 64 54 66 54 6b-58 6b 56 66 52 64 53 64  
0040  56 6d 55 66 57 6a 56 6a-59 6d 57 6b 58 6a 59 6d  
0050  59 6c 59 67 58 6b 56 6b-57 6a 56 6a 54 63 44 49  
0060  31 3a 2c 38 2c 39 2c 39-2e 38 30 39 2a 36 2a 37  
0070  2a 32 2a 34 26 30 29 31-1f 2d 21 29 1e 26 1c 25  
0080  ff 00 ff 00 ff 00 ff 01-00 00 00 00 00 00 00 00  
0090  08 00 04 00 0c b0 04 cc-86 13 9a 00 0c 2c 01 6c  
00a0  06 a6 bf 00 0c 2c 01 a4-88 39 e5 00 0c b0 04 66  
00b0  06 4c 7b 01 0c 2c 01 07-86 df a0 01 0c 2c 01 3f  
00c0  08 72 c6 01 0c b0 04 01-88 85 5c 02 0c b0 04 2b  
00d0  08 98 f2 02 0c b0 04 54-ff ff ff ff ff ff ff ff  
00e0  ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff  


For some unknown reason, this data corruption occurs if the camera is not
replugged, but the data is always offset either not at all or by exactly 128 
bytes. Thus the problem can apparently be overcome by checking whether 
ff 00 ff 00 occurs on line 0000 or on line 0080. 

For similarly unknown reasons, the same offset seems to occur at the
beginning of every download of a photo. One gets eight lines of junk,
followed by several marker characters, and only then comes the data. The
total number of "junk" characters seems to total 140, which must be thrown
away in order for the photo to come out right instead of in two pieces.
Then, 140 bytes are missing at the bottom right of the photo instead. And,
no, the bytes from the beginning are not supposed to be put at the end,
either. Been there. Tried that. So it is a mystery. 

These picture data corruption problems occur with the manufacturer's driver
as well. However, the "stock" driver does seem to know how to supply some 
missing bytes at the bottom right of the photo -- most definitely without
downloading them. Perhaps the 8 lines of "junk" at the beginning are
supposed to be stuck back somewhere in the middle, in a manner most
mysterious. Who knows? 


UPDATES and REVISIONS:

This section is intended to give further explanations of some things which 
are otherwise mentioned briefly, in the ChangeLog.

1. 2004-05-18 ID number of Emprex PDC3800 contributed by Hisham Muhammad 
<hisham@apple2.com>.

2. 2004-06-09 Compatibility with gtkam ensured; method of adjusting the gamma
setting of a photo introduced, based upon photo's config data. 

3. 2004-09-04 The Vivitar Vivicam 55 has the same USB ID as the Emprex PDC3800
and presumably is therefore the same camera. Turned out that the camera is 
very finicky about initialization. Extensive efforts to make this camera 
actually to work resulted in major revisions to the init sequence. Special 
credit to Sebastien Soilen <sebastien@soilen.net> for sustained, patient, and 
thorough testing. 

4. 2004-10-26 Support for two new cameras with new ID of 0x093a:0x10e, which use 
two new resolution settings, of 352x288 and 176x144. The new codes for these 
resolution settings are:

352x288, uncompressed	0x02 or 0x82
352x288, compressed 	0x22 or 0xa2
176x144, uncompressed    0x0 or 0x80
176x144, compressed 	0x20 or 0xa0

Credits to 

Scott MacKenzie <irrational@poboxes.com> for reporting his camera and for 
submitting the patch which makes it work.
Nils Naumann <nau@gmx.net> for reporting his camera 24 hours after Scott, 
and for testing Scott's patch. 



