git-svn-id: https://svn.code.sf.net/p/gphoto/code/trunk/libgphoto2@5969 67ed7778-7388-44ab-90cf-0a291f65f57c
1017 lines
39 KiB
Plaintext
1017 lines
39 KiB
Plaintext
(read/print this document with a non-proportional font such as courier)
|
|
|
|
============================================
|
|
====== Canon PowerShot Series ======
|
|
==== Transfer Protocol Specifications =====
|
|
============================================
|
|
|
|
* About this document
|
|
|
|
The following document is an overview of the Canon PowerShot serial
|
|
and USB transfer protocols. It should be a valid reference for models
|
|
ranging from PowerShot A5 to S20.
|
|
|
|
No information present in this document was obtained from Canon.
|
|
Everything is the result of observations and logical analysis. It is
|
|
by no means guaranteed to be accurate, nor even right. Nevertheless, a
|
|
lot of people have managed to communicate with their PowerShot cameras
|
|
using these commands, so they cannot be completely wrong either !
|
|
|
|
An implementation of this communication protocol was made for the
|
|
GPhoto digital camera software, available at www.gphoto.org.
|
|
|
|
* Contributors:
|
|
|
|
This document was written thanks to the efforts of:
|
|
|
|
Wolfgang G. Reissnegger, Werner Almesberger, Philippe Marzouk, Mikael
|
|
Nyström, Edouard Lafargue.
|
|
|
|
|
|
* Copyright :
|
|
|
|
The Canon Protocol information. Copyright © 2000 by its respective
|
|
authors (see the Contributors section).
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or (at
|
|
your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the:
|
|
|
|
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
|
|
USA.
|
|
|
|
* To Do :
|
|
|
|
(send updates to Edouard.Lafargue@bigfoot.com or to the
|
|
gphoto-devel mailing-list)
|
|
|
|
- Serial:
|
|
|
|
Update get_directory description to match what was discovered in USB.
|
|
Describe the structure of the initial ID packet.
|
|
Find out what the real meaning of the "fffb" command is.
|
|
Describe error recovery protocol.
|
|
Describe format of low batt condition.
|
|
Find out the rest of the commands that were discovered in USB:
|
|
- Make dir
|
|
- Delete dir
|
|
- Change attribute
|
|
- etc.
|
|
Describe File upload.
|
|
Describe each command in detail.
|
|
|
|
- USB:
|
|
|
|
Describe the generic get_directory reply packet with the location of
|
|
the error code offset.
|
|
|
|
- General:
|
|
|
|
Rewrite this document in XML (LinuxDoc).
|
|
|
|
* Changelog:
|
|
|
|
09 May 2000: first version with both USB and serial protocols
|
|
described in the same document.
|
|
|
|
|
|
|
|
|
|
|
|
=========================================================================
|
|
|
|
|
|
|
|
|
|
|
|
============================================
|
|
== Serial Protocol ==
|
|
=== Specifications ===
|
|
============================================
|
|
|
|
|
|
Introduction
|
|
============
|
|
|
|
We have chosen to describe the Canon Serial Protocol as successive
|
|
layers. I used OSI-like names but the protocol is not really a network
|
|
protocol.
|
|
|
|
a. Data link layer:
|
|
Responsible for framing, escaping and checksuming messages
|
|
|
|
b. Transport (packet) layer:
|
|
Responsible for dividing messages into packets of known length.
|
|
This layer also handles handshaking, retries, etc.
|
|
|
|
c. Session (message) layer:
|
|
Last layer, carrying whole messages, such as download requests,
|
|
image data, and such information.
|
|
|
|
Currently, all these layers are documented, but we still lack
|
|
information on how to handle protocol retries, and errors in general.
|
|
|
|
|
|
Data link layer
|
|
=====================
|
|
|
|
The following figure illustrates the lower layers of the protocol
|
|
used by some Canon PowerShot cameras:
|
|
|
|
[ Upper layers ] Example: payload "00 C0 01"
|
|
| ^
|
|
| | 00 C0 01
|
|
<CRC>
|
|
| | 00 C0 01 12 34 (fictious CRC)
|
|
<Escaping>
|
|
| | 00 7E E0 01 12 34
|
|
<Framing>
|
|
| | C0 00 7E E0 01 12 34 C1
|
|
v |
|
|
[ Wire format ]
|
|
|
|
The upper layers are described later in this file.
|
|
|
|
|
|
0) Serial timing
|
|
----------------
|
|
|
|
Initialization: PC sends sequences of "U" bytes at 9600 bps until the
|
|
camera responds by sending its ID. Each sequence has a length of 2-8
|
|
bytes. The interval to wait between sequences is 0.9-1.04 sec
|
|
(measured for 8 bytes).
|
|
|
|
When the camera sends its ID, the computer can ask it to change to a
|
|
higher speed. The speed can go up to 115200 bps.
|
|
|
|
Afterwards, a one/two seconds command timeout should be set.
|
|
E.g. retrieving a directory with 1200 files takes several
|
|
seconds. Opening a large capacity flash card takes time as well.
|
|
|
|
|
|
1) Framing
|
|
----------
|
|
|
|
Each message begins with the byte C0 and ends with the byte C1. The
|
|
length of a message including the framing bytes and any escape bytes
|
|
(see below) never exceeds 1024 bytes.
|
|
|
|
|
|
2) Escaping
|
|
-----------
|
|
|
|
The value 7E is used to XOR the following byte with the value 0x20. This
|
|
is used for the following three combinations:
|
|
7E 5E -> 7E
|
|
7E E0 -> C0
|
|
7E E1 -> C1
|
|
|
|
|
|
3) CRC
|
|
------
|
|
|
|
The last two bytes of a message (without framing and escaping) contain
|
|
a 16-bit "CCITT" CRC in little-endian order. The CRC is calculated
|
|
over the entire message, without framing and escaping, and without
|
|
including the CRC bytes. The CRC generator [1] is initialized to a
|
|
length-dependent value. The algorithim for the initial value is not
|
|
known. However, a table of values emitted by the camera has been
|
|
compiled and is in crc.c:crc_init. It is indexed by the length,
|
|
i.e. the number of bytes over which the CRC is taken.
|
|
|
|
|
|
[1] Assuming the use of
|
|
http://www.cse.fau.edu/~sam/course/dc_htm/src_dir/crc_att.c,
|
|
generator polynom 0102010 (octal), the initial value of "crc" is
|
|
the CRC generator's initial value (in the original code always
|
|
zero).
|
|
|
|
|
|
|
|
Transport layer
|
|
=====================
|
|
|
|
Communication is done through messages, which may be split into
|
|
several fragments, which are then sent as individual packets. Packets
|
|
are framed as described earlier in this file.
|
|
|
|
|
|
Packet level
|
|
------------
|
|
|
|
Each packet consists of the following two-byte header:
|
|
|
|
<sequence> <ptype>
|
|
|
|
There are two sequence numbers: the message sequence number <mseq> and
|
|
the fragment sequence number <fseq>. They are counted independently
|
|
and start at zero. <mseq> is reset at the beginning of a session,
|
|
while <fseq> is reset at the beginning of each message.
|
|
|
|
The following packet types are known:
|
|
00 Message fragment
|
|
03 Speed message from computer
|
|
04 EOT
|
|
05 ACK
|
|
06 Compatibility?
|
|
|
|
A packet with type 03 is sent once, early in the initialization for
|
|
the computer to ask the camera to switch to a higher speed.
|
|
|
|
Each message ends with an EOT packet, which is then confirmed by an
|
|
ACK packet.
|
|
|
|
|
|
EOT has the following format:
|
|
xx 04 xx 00 00 00
|
|
| |
|
|
| indication of the message length. Known values:
|
|
<mseq> 00 empty message (no fragments)
|
|
01 short message (one fragment)
|
|
03 used when uploading
|
|
ff maximum length data packet, more to follow
|
|
else data packet, at end (observed values: 0f, 7f)
|
|
|
|
ACK has the following format:
|
|
xx 05 xx 00 00 00
|
|
| |
|
|
| error code
|
|
<mseq> 00 No error, acknowledged
|
|
01 Not acknowledged
|
|
FF retransmit last sequence
|
|
else other values not known
|
|
|
|
|
|
A packet with type 06 is sent once, as the first packet coming from
|
|
the camera. It contains a length, just like a normal message fragment,
|
|
but the message structure is different.
|
|
|
|
An empty message can be used to test if the camera is still responding.
|
|
If yes, it will respond with an ACK. Example:
|
|
PC->CAM xx 04 00 00 00 00
|
|
CAM->PC xx 05 00 00 00 00
|
|
|
|
|
|
Message fragment level
|
|
----------------------
|
|
|
|
Message fragments have the following structure:
|
|
|
|
xx 00 xx xx ...
|
|
| | | |
|
|
| | | fragment data
|
|
| | data length, MSB
|
|
| data length, LSB
|
|
<fseq>
|
|
|
|
The data length is the length (in bytes) of the fragment data that
|
|
follows the length. Fragment data is simply concatenated to form the
|
|
complete message.
|
|
|
|
|
|
Session (message) Layer
|
|
=======================
|
|
|
|
All messages (except the one with type 03) have the following structure:
|
|
|
|
00 02 00 00 xx 00 00 xx xx xx 00 00 ...
|
|
| | | | |
|
|
| | | | message payload
|
|
| | | message length, MSB
|
|
| | message length, LSB
|
|
| direction code <dir>
|
|
message type <mtype>
|
|
|
|
The message length is the length of the entire message, including the
|
|
header shown above.
|
|
|
|
|
|
|
|
The first four bytes of the message payload <fffb> seem to depend on
|
|
the message type. The following combinations have been sighted:
|
|
|
|
<mtype> <dir> <fffb> Operation
|
|
|
|
01 12 14 f7 8a 00 Identify camera request
|
|
01 22 14 f7 8a 00 Identify camera response
|
|
01 11 6a 08 79 04 Download image request
|
|
01 11 aa 06 79 04 Download "thumbnail" request (see below)
|
|
01 21 6a 08 79 04 Image data
|
|
01 21 aa 06 79 04 "Thumbnail" data
|
|
03 11 Upload file
|
|
03 12 78 f3 64 01 Get Date
|
|
04 12 08 d3 9d 00 Set date
|
|
05 12 fc d2 9d 00 Change Owner name
|
|
09 11 d8 f7 8a 00 Disk info request
|
|
09 21 d8 f7 8a 00 Disk info response
|
|
0a 11 dc f7 8a 00 Get disk(s) request
|
|
0a 21 dc f7 8a 00 Get disk(s) response
|
|
0a 12 70 f6 8a 00 Power Supply Status
|
|
0a 22 70 f6 8a 00 Power Supply Status response
|
|
0b 11 94 f6 8a 00 List without date request
|
|
0b 21 94 f6 8a 00 List without date response
|
|
0b 11 a8 f6 8a 00 List with date request
|
|
0b 21 a8 f6 8a 00 List with date response
|
|
0d 11 8c f4 7b 00 Delete image request
|
|
0d 21 8c f4 7b 00 Delete image response
|
|
0e 11 -- -- -- -- Set file attributes.
|
|
|
|
Important note : it seems that the "fffb" part can be set to 0 in
|
|
every case, and the commands will still work. The exact meaning of
|
|
this part of the packet is unknwown. It is probably used as a unique
|
|
ID for each transaction and can be chosen at random each time.
|
|
|
|
|
|
Identify camera
|
|
---------------
|
|
|
|
The identify camera request has no data.
|
|
|
|
The identify camera response has the following structure:
|
|
00 00 00 00 00 02 00 00 00 00 00 01 <camera_name> 00 (more 00s)
|
|
|
|
On the S10, the response has the following structure:
|
|
00 00 00 00 00 04 00 00 00 00 00 01 and then:
|
|
<firmware rev> (32 bit word) (offset: 0x08)
|
|
<model name> (C string) (offset: 12 / 0x0c)
|
|
<owner name> (C string) (offset: 44 / 0x2c)
|
|
|
|
Firmware version: 04 03 02 01 is version 1.2.3.4
|
|
01 00 00 01 is version 1.0.0.1
|
|
|
|
Example (full packet): for a PowerShot S10 with firmware 1.0.0.0
|
|
|
|
RECV: (98 bytes)
|
|
00000000: 00 00 5C 00 02 00 00 00 01 00 00 22 5C 00 00 00 - ..\........"\...
|
|
00000010: 14 F7 8A 00 00 00 00 00 00 04 00 00 00 00 00 01 - ................
|
|
00000020: 43 61 6E 6F 6E 20 50 6F 77 65 72 53 68 6F 74 20 - Canon PowerShot
|
|
00000030: 53 31 30 00 00 00 00 00 00 00 00 00 00 00 00 00 - S10.............
|
|
00000040: 45 64 6F 75 61 72 64 20 4C 61 66 61 72 67 75 65 - Edouard Lafargue
|
|
00000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 - ................
|
|
00000060: 9C EA - ..
|
|
|
|
|
|
Get Power Status
|
|
----------------
|
|
|
|
Offsets in the payload:
|
|
|
|
0x04 contains a byte with power status: 0x6=good, 0x4=bad
|
|
0x07 contains a byte with powertype: 0x10=ac-adaptor, 0x30=battery
|
|
|
|
Example (full packet):
|
|
RECV: (30 bytes)
|
|
00000000: 00 00 18 00 02 00 00 00 0A 00 00 22 18 00 00 00 - ..........."....
|
|
00000010: 70 F6 8A 00 00 00 00 00 06 00 00 30 B5 5A - p..........0.Z
|
|
|
|
|
|
|
|
Change Owner Name
|
|
----------------
|
|
|
|
The name (payload) can be 30 characters max.
|
|
|
|
|
|
Set Date
|
|
--------
|
|
|
|
The payload of this message is 4 bytes, it must be the same unix
|
|
format as in the directory with date request, for example the
|
|
01/01/2000 is 80 43 6D 38.
|
|
|
|
|
|
Get disk(s)
|
|
-----------
|
|
|
|
The get disk(s) request has no data.
|
|
|
|
The get disk response has the following structure:
|
|
00 00 00 00 <disk_name> 00
|
|
|
|
Disk name example: "C:"
|
|
|
|
|
|
Disk info
|
|
---------
|
|
|
|
Disk info requests have the following structure:
|
|
<root_name> 00
|
|
|
|
Disk info responses have the following structure:
|
|
00 00 00 00 xx xx xx xx xx xx xx xx
|
|
| |
|
|
| Free space (in bytes)
|
|
Total capacity (in bytes)
|
|
|
|
Root name example: "C:\" (The trailing slash is required.)
|
|
|
|
|
|
List (show directory contents)
|
|
------------------------------
|
|
|
|
Note: It seems that directory listing as described in the USB part is
|
|
more accurate, when it comes to the meaning of the first byte (
|
|
"date/withtout date").
|
|
|
|
List requests have the following structure:
|
|
xx <directory_name> 00 00 00
|
|
|
|
|
00 if with date, 02 if without date
|
|
|
|
Directory name example: "C:\PWRSHOT", "D:", or "D:\.", but not
|
|
"D:\" (trailing slash), or "D:\.\FOO" (dot not allowed in path ?)
|
|
|
|
List responses have the following structure:
|
|
Failure:
|
|
00 00 00 00 01 00 00 00 00 00 00 00
|
|
|
|
Success:
|
|
00 00 00 00 xx 80 00 00 00 00 00 00 00 00 00 00
|
|
|
|
|
01 if last message, 00 if more
|
|
<directory_name> 00
|
|
<type> 00 <size> <date> <entry_name> 00
|
|
...
|
|
<type> 00 <size> <date> <entry_name> 00 (many 00s)
|
|
|
|
<type> is one byte containing the file attributes:
|
|
File attributes:
|
|
bit0 (0x01) (1=delete protected, 0=NOT delete protected)
|
|
bit4 (0x10) (1=directory contains item but not recursived entered)
|
|
(NOT used with the attrib command)
|
|
bit5 (0x20) (1=NOT downloaded, 0=downloaded)
|
|
(must be manually switched)
|
|
bit7 (0x80) (1=recurively entered directory)
|
|
(NOT used with the attrib command)
|
|
|
|
|
|
<size> is the size in bytes. Directory size is always 0.
|
|
|
|
Entry name example: "AUT_1201.JPG" or "MISC"
|
|
|
|
The date is a four bytes Unix-style date. The list without date responses
|
|
also contains the four data bytes, but sets them to zero.
|
|
|
|
Note: it's unclear if the list with/without date commands differ in any
|
|
other way than the inclusion of the date.
|
|
|
|
If the directory is so large that additional messages are needed, they
|
|
have the following structure:
|
|
00 00 00 00 xx <entry>
|
|
|
|
|
1 if last message, 00 if more
|
|
|
|
The boundary between messages is always chosen such that the terminating
|
|
00 of an entry is the last byte in the earlier message.
|
|
|
|
|
|
Download and Data
|
|
-----------------
|
|
|
|
Download requests have the following structure:
|
|
00 00 00 00 00 xx 00 00 <name> 00
|
|
|
|
|
Length of name (including terminating \0)
|
|
|
|
Data messages have the following structure:
|
|
00 00 00 00 xx xx xx xx xx xx xx xx xx xx xx xx xx 00 00 00 ...
|
|
| | | | |
|
|
| | | | data
|
|
| | | 00 if more, 01 at end
|
|
| | data size in this message
|
|
| current offset
|
|
total length
|
|
|
|
All lengths are measured in bytes.
|
|
|
|
The camera only sends the 10813 first bytes from the image for the thumbnail
|
|
download request. However it is not a valid thumbnail image, the first part
|
|
is the Exif header, the second part is the thumbnail itself between a FF D8
|
|
and a FF D9, the remaining is the beginning of the picture.
|
|
|
|
|
|
The camera always sends 8 messages then waits for an ACK from the computer,
|
|
if the computer has not received everything, it sends an ACK with an error
|
|
value asking to retransmit one of the eight packet sent. These error values
|
|
are not yet known.
|
|
|
|
Upload file
|
|
-----------
|
|
|
|
The serial upload protocol description is not done yet. These are just
|
|
ideas on what it could be. Maybe it's right, maybe it's wrong.
|
|
|
|
* This command sends a file to the camera.
|
|
|
|
* Request structure:
|
|
xx 00 00 00 00 xx 00 00 <name>
|
|
|
|
Each data block has the following format:
|
|
|
|
00 00 00 02 XX XX XX XX - YY YY YY YY filename - datablock
|
|
|
|
XX XX XX XX : offset within the file for this block
|
|
YY YY YY YY : len2: length of this block
|
|
filename : 0-terminated string
|
|
datablock: the data itself.
|
|
|
|
Switch Camera off
|
|
-----------------
|
|
|
|
In order to switch the camera off, you need to send the following
|
|
characters (directly, without extra framing) :
|
|
|
|
C0 00 02 55 2C C1
|
|
C0 00 04 01 00 00 00 24 C6 C1
|
|
|
|
|
|
Low Battery warning
|
|
-------------------
|
|
|
|
If the camera batteries run too low during a transfer and the camera
|
|
needs to switch itself off, it will send a special packet just before
|
|
going down. You can see how it is handled in psa50.c
|
|
|
|
|
|
|
|
===============================================
|
|
=
|
|
= USB Interface
|
|
=
|
|
===============================================
|
|
|
|
Nota:
|
|
When mentioning word, 32bit word little_endian is implied.
|
|
|
|
References to usb11.pdf (Chaper 9.3 page 199):
|
|
http://www.usb.org/developers/data/usbspec.zip (1.8Mb)
|
|
|
|
bmRequestType is 0xC0 during read and 0x40 during write.
|
|
bRequest is 0x4 if length of data is >1, 0x0c otherwise (length > 1 ? 0x04 : 0x0C)
|
|
wValue differs between operations.
|
|
wIndex is always 0x00
|
|
wLength is simply the length of data
|
|
|
|
In linux sending/reciving commands is using usb_control_msg (in usb.c).
|
|
|
|
usb11.pdf name | usb.c name)
|
|
--------------------------------
|
|
bmRequestType | requesttype
|
|
bRequest | request
|
|
wValue | value
|
|
wIndex | index
|
|
wLength | length
|
|
|
|
================================================================================
|
|
Init of camera:
|
|
================================================================================
|
|
|
|
1. Control_transfer_read requesttype=0xC0 value=0x55 length=1
|
|
|
|
Camera responds with following data (single char):
|
|
"A" = Camera was already active
|
|
"C" = Camera was woken up
|
|
"I" = Unknown (some kind of error)
|
|
"E" = Unknown (some kind of error)
|
|
|
|
2. Control_transfer_read requesttype=0xC0 value=0x1 length=0x58
|
|
|
|
The first 0x48 bytes can be trashed, save the last 0x10 byte and us it as
|
|
data in next step.
|
|
Example:
|
|
00000000 18 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 01 00 02 00 43 30 A9 04-00 08 00 00 FF FF FF FF ....C0..........
|
|
00000050 00 FD 00 00 00 FD 00 00 ........
|
|
|
|
3 'A' If the response to step 1 was 'A',
|
|
Control_transfer_read requesttype=0x4 value=0x4 length=0x50
|
|
Throw away the data and we are finished with the initialization [1].
|
|
|
|
3 'C' If the response to step 1 was 'C', take the packet from step 2, change
|
|
the byte at offset 0 to 0x10, move the last 0x10 bytes to position 0x40 and
|
|
Control_transfer_write requesttype=0x40 value=0x11 length=0x50
|
|
|
|
4. PC sign should now appear on the LCD. Not all cameras have PC signs though.
|
|
|
|
5. We should now read a total of 0x44 bytes from bulk_in, but some cameras are
|
|
picky at this stage and we must first read 0x40 bytes and then 0x4 bytes
|
|
(the symptoms if not doing this right is that camera initialization only works
|
|
every second time).
|
|
Newer Canon USB cameras return 0x54 0x78 0x00 0x00 ('Tx\0\0') under some
|
|
cicumstances [2] as the last four bytes in either of these two reads.
|
|
If we get that from the first read we should not try to read the next 0x4 bytes.
|
|
Example:
|
|
00000000 04 00 00 00 02 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 00 00 00 00 ....
|
|
|
|
[1] Many cameras fail the first camera command after this (the command response
|
|
is returned without the first 0x40 bytes). It seems Canon got the same
|
|
problem and worked around it in the Windows driver instead of fixing the
|
|
firmware. The workaround is to retry the first camera command (Identify
|
|
camera is a suitable command) up to four times.
|
|
|
|
[2] It seems this was due to an error in the init sequence described in earlier
|
|
versions of this document. When done like the Windows driver does it, we
|
|
always get 00 00 00 00 back as the last four bytes of step 5.
|
|
|
|
================================================================================
|
|
USB Commands
|
|
================================================================================
|
|
|
|
1. Structure of a command block
|
|
|
|
Example:
|
|
|
|
* Command block sent in general: (Example:Disk info request)
|
|
0000000: 14 00 00 00 01 02 00 00-00 00 00 00 00 00 00 00 ................
|
|
0000010: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
0000020: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
0000030: 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
0000040: 02 00 00 00 09 00 00 11-14 00 00 00 78 56 34 12 ............xV4.
|
|
0000050: 44 3A 5C 00 D:\.
|
|
|
|
USB arguments:
|
|
- value is always 0x10
|
|
- length is TOTAL length (0x54 in example above)
|
|
|
|
* Generic format of block sent:
|
|
|
|
0000000: xx xx xx xx yy yy yy yy - 00 00 00 00 00 00 00 00
|
|
0000010: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
|
|
0000020: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
|
|
0000030: 00 00 00 00 00 00 00 00 - 00 00 00 00 00 00 00 00
|
|
0000040: 02 00 00 00 UU 00 00 VV - xx xx xx xx SS SS SS SS
|
|
0000050: ... (payload/arguments)
|
|
|
|
xx xx xx xx : Length (word)
|
|
yy yy yy yy : cmd3 (word)
|
|
UU : cmd1 (byte)
|
|
VV : cmd2 (byte)
|
|
xx xx xx xx : Length (again)
|
|
SS SS SS SS : sequence number (word)
|
|
|
|
- 'length' is the length of the block, excluding the first 0x40 bytes
|
|
in block, and is never less than 0x10.
|
|
- cmd1 and cmd2 are a single byte
|
|
- cmd3 is a word
|
|
- Sequence number is a word, sent back in command reply.
|
|
|
|
2. Summary of available (known) commands:
|
|
|
|
cmd1 | cmd2 | cmd3 | Argument(eg.) Response Length | Operation
|
|
-----------------------------------------------------------------------------------------------
|
|
0x01 0x11 0x202 | 0x00000000 0x00001400 "D:\DCIM\100CANON\IMG_0100.JPG" 0x00 L | Get picture
|
|
0x01 0x11 0x202 | 0x00000001 0x00001400 "D:\DCIM\100CANON\IMG_0100.JPG" 0x00 L | Get thumbnail
|
|
0x01 0x12 0x201 | none 0x9c | Identify camera request
|
|
0x03 0x12 0x201 | none 0x60 | Get time
|
|
0x04 0x12 0x201 | 0x390873f0 0x00000000 0x00000000 0x54 | Set time (0x390873f0) (UNIX-type)
|
|
0x05 0x11 0x201 | "D:\DCIM" 0x00 0x54 | Make directory
|
|
0x05 0x12 0x201 | "Donald Duck" 0x00 0x54 | Change owner
|
|
0x06 0x11 0x201 | "D:\DCIM" 0x00 0x54 | Remove directory
|
|
0x09 0x11 0x201 | "D:\" 0x00 0x5c | Disk info request
|
|
0x0A 0x11 0x202 | none L | Flash device identification
|
|
0x0A 0x12 0x201 | none 0x58 | Power supply status
|
|
0x0B 0x11 0x202 | 0x01 "D:\DCIM" 0x00 0x00 0x00 L | Get directory (0x1 = max depth of recursion)
|
|
0x0D 0x11 0x201 | "D:\DCIM\100CANON" 0x00 "IMG_0002.JPG" 0x00 0x54 | Delete file
|
|
0x0E 0x11 0x201 | 0x00000021 "D:\DCIM\100CANON" 0x00 "IMG_0002.JPG" 0x00 0x54 | Set file attribute
|
|
0x1B 0x12 0x201 | 0x06 0x00 0x00 0x00 0x54 | EOS (D30) lock keys
|
|
0x1C 0x12 0x201 | none 0x54 | EOS (D30) unlock keys
|
|
0x1F 0x12 0x201 | none 0x380 | Get camera photo abilities?
|
|
0x20 0x12 0x201 | none 0x54 | Lock keys, turn off LCD
|
|
|
|
L means that the program reads 0x40 from bulk in, checks for a word at
|
|
position 0x6 for the length (0xd1fcf in this case), and then reads the
|
|
rest in 0x1400 buffers. (long bulk in read)
|
|
|
|
00000000 00 00 00 00 02 03 CF 1F-0D 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
|
|
****
|
|
** Disk Info Request:
|
|
****
|
|
|
|
* Argument structure:
|
|
|
|
Null-terminated string containing the name of the disk.
|
|
|
|
* Camera response block:
|
|
|
|
Data received via bulk in after a command block: (Disk info request)
|
|
0000000: 00 00 00 00 01 03 00 00 00 00 00 00 00 00 00 00 ................
|
|
0000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
|
0000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
|
0000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
|
|
0000040: 02 00 00 00 09 00 00 21 1C 00 00 00 78 56 34 12 .......!....xV4.
|
|
0000050: 00 00 00 00 00 80 E8 03 00 A0 AF 03 ............
|
|
|
|
First 0x40 bytes is throwable.
|
|
0x54 contains a word with totalbytes on flash.
|
|
0x58 contains a word with bytes free.
|
|
|
|
****
|
|
** Delete directory
|
|
****
|
|
Data received via bulk in after a command block: (Delete directory)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 06 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
|
|
00000050 00 00 00 00 ....
|
|
|
|
****
|
|
** Make directory
|
|
****
|
|
Data received via bulk in after a command block: (Make directory)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 05 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
|
|
00000050 00 00 00 00 ....
|
|
|
|
|
|
****
|
|
** Get time
|
|
****
|
|
|
|
Data received via bulk_in after a command block: (Get time)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 03 00 00 22-20 00 00 00 78 56 34 12 ......." ...xV4.
|
|
00000050 00 00 00 00 8D 1D 12 39-00 00 00 00 00 00 00 00 .......9........
|
|
|
|
First 0x40 bytes is throwable.
|
|
0x54 contains a UNIX time
|
|
|
|
****
|
|
** Power supply status
|
|
****
|
|
|
|
Data received via bulk_in after a command block: (Power supply status)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 0A 00 00 22-18 00 00 00 78 56 34 12 ......."....xV4.
|
|
00000050 00 00 00 00 06 00 00 10- ........
|
|
|
|
First 0x40 bytes is throwable.
|
|
0x54 contains a byte with power status: 0x6=good, 0x4=bad
|
|
0x57 contains a byte with powertype in bit 4:
|
|
((value & 0x20) == 0) running from ac-adaptor
|
|
((value & 0x20) != 0) running from battery
|
|
|
|
Note that the original document claimed for 0x57 that it contained
|
|
"a byte with powertype: 0x10=ac-adaptor, 0x30=battery", whereas a
|
|
PowerShot G2 just toggles one bit.
|
|
|
|
****
|
|
** Identify Camera request
|
|
****
|
|
|
|
Data received via bulk_in after a command block: (Identify camera request)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 01 00 00 22-5C 00 00 00 78 56 34 12 ......."\...xV4.
|
|
00000050 00 00 00 00 00 04 00 00-01 00 00 01 43 61 6E 6F ............Cano
|
|
00000060 6E 20 50 6F 77 65 72 53-68 6F 74 20 53 32 30 00 n PowerShot S20.
|
|
00000070 00 00 00 00 00 00 00 00-00 00 00 00 44 6F 6E 61 ............Dona
|
|
00000080 6C 64 20 44 75 63 6B 00-00 00 00 00 00 00 00 00 ld Duck.........
|
|
00000090 00 00 00 00 00 00 00 00-00 00 00 00 ............
|
|
|
|
First 0x40 bytes is throwable (as usual)
|
|
At 0x5c a string with camera type exist
|
|
At 0x7c a string with owner name exist.
|
|
0x58-0x5b is firmware version (04 03 02 01 is version 1.2.3.4; 01 00 00 01 is version 1.0.0.1)
|
|
Data at 0x54-0x57 has unknown purpose.
|
|
|
|
****
|
|
** Flash device identification
|
|
****
|
|
|
|
Data received via a long_bulk_in_read: (Flash device identification)
|
|
00000000 44 3A 00 00 D:..
|
|
|
|
****
|
|
** Set File Attribute
|
|
****
|
|
|
|
Data received via bulk_in after a command block: (Set file attribute)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 0E 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
|
|
00000050 00 00 00 00 ....
|
|
|
|
Data received via bulk_in after a command block: (Set file attribute) (file did not exist).
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 0E 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
|
|
00000050 22 00 00 02 "...
|
|
|
|
|
|
File attributes:
|
|
bit0 (0x01) (1=delete protected, 0=NOT delete protected)
|
|
bit4 (0x10) (1=directory contains item but not recursived entered)
|
|
(NOT used with the attrib command)
|
|
bit5 (0x20) (1=NOT downloaded, 0=downloaded)
|
|
(must be manually switched)
|
|
bit7 (0x80) (1=recurively entered directory)
|
|
(NOT used with the attrib command)
|
|
|
|
Example: 0x21 file is NOT downloaded but delete protected
|
|
|
|
|
|
****
|
|
** Delete file
|
|
****
|
|
|
|
Data received via bulk_in after a command block: (Delete file) (file did not exist).
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 0D 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
|
|
00000050 22 00 00 02 "...
|
|
|
|
Data received via bulk_in after a command block: (Delete file) (file was protected)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 0D 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
|
|
00000050 29 00 00 02 )...
|
|
|
|
Data received via bulk_in after a command block: (Delete file) (successful)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 0D 00 00 21-14 00 00 00 78 56 34 12 .......!....xV4.
|
|
00000050 00 00 00 00 ....
|
|
|
|
|
|
****
|
|
** Change Owner
|
|
****
|
|
|
|
Data received via bulk_in after a command block: (Change owner) (no errorcodes)
|
|
00000000 00 00 00 00 01 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 05 00 00 22-14 00 00 00 78 56 34 12 ......."....xV4.
|
|
00000050 00 00 00 00 ....
|
|
|
|
****
|
|
** Directory Listing
|
|
****
|
|
|
|
Errorcodes:
|
|
0x02000022 File not found
|
|
0x00000000 No errors
|
|
0x02000086 Path not found
|
|
0x02000029 File was protected
|
|
|
|
File attributes:
|
|
bit0 (0x01) (1=delete protected, 0=NOT delete protected)
|
|
bit4 (0x10) (1=directory contains item but not recursived entered)
|
|
(NOT used with the attrib command)
|
|
bit5 (0x20) (1=NOT downloaded, 0=downloaded)
|
|
(must be manually switched)
|
|
bit7 (0x80) (1=recurively entered directory)
|
|
(NOT used with the attrib command)
|
|
|
|
Example: 0x21 file is NOT downloaded but delete protected
|
|
|
|
Directory handling:
|
|
Thu May 4 00:11:40 2000 D:\DCIM\100CANON\IMG_0001.JPG 778435
|
|
Thu May 4 00:28:32 2000 D:\DCIM\100CANON\IMG_0002.JPG 44409
|
|
Thu May 4 00:28:32 2000 D:\DCIM\CANONMSC\100.CTG 2634
|
|
Thu May 4 00:28:32 2000 D:\DCIM\CANONMSC\D.CTG 383
|
|
|
|
Directory contents: "D:" (recurse = 0x0)
|
|
00000000 80 00 00 00 00 00 00 00-00 00 44 3A 00 10 00 00 ..........D:....
|
|
00000010 00 00 00 C6 B5 10 39 44-43 49 4D 00 00 00 00 00 ......9DCIM.....
|
|
00000020 00 00 00 00 00 00 00 .......
|
|
|
|
Directory contents: "D:" (recurse = 0x1)
|
|
00000000 80 00 00 00 00 00 00 00-00 00 44 3A 00 80 00 00 ..........D:....
|
|
00000010 00 00 00 36 C0 10 39 2E-5C 44 43 49 4D 00 10 00 ...6..9.\DCIM...
|
|
00000020 00 00 00 00 36 C0 10 39-31 30 30 43 41 4E 4F 4E ....6..9100CANON
|
|
00000030 00 10 00 00 00 00 00 CC-B5 10 39 43 41 4E 4F 4E ..........9CANON
|
|
00000040 4D 53 43 00 80 00 00 00-00 00 00 00 00 00 2E 2E MSC.............
|
|
00000050 00 00 00 00 00 00 00 00-00 00 00 00 ............
|
|
|
|
Directory contents: "D:" (recurse = 0x2)
|
|
00000000 80 00 00 00 00 00 00 00-00 00 44 3A 00 80 00 00 ..........D:....
|
|
00000010 00 00 00 36 C0 10 39 2E-5C 44 43 49 4D 00 80 00 ...6..9.\DCIM...
|
|
00000020 00 00 00 00 3C C0 10 39-2E 5C 31 30 30 43 41 4E ....<..9.\100CAN
|
|
00000030 4F 4E 00 20 00 C3 E0 0B-00 3C C0 10 39 49 4D 47 ON. .....<..9IMG
|
|
00000040 5F 30 30 30 31 2E 4A 50-47 00 20 00 79 AD 00 00 _0001.JPG. .y...
|
|
00000050 30 C4 10 39 49 4D 47 5F-30 30 30 32 2E 4A 50 47 0..9IMG_0002.JPG
|
|
00000060 00 80 00 00 00 00 00 00-00 00 00 2E 2E 00 80 00 ................
|
|
00000070 00 00 00 00 30 C4 10 39-2E 5C 43 41 4E 4F 4E 4D ....0..9.\CANONM
|
|
00000080 53 43 00 20 00 4A 0A 00-00 30 C4 10 39 31 30 30 SC. .J...0..9100
|
|
00000090 2E 43 54 47 00 20 00 7F-01 00 00 30 C4 10 39 44 .CTG. ....0..9D
|
|
000000A0 2E 43 54 47 00 80 00 00-00 00 00 00 00 00 00 2E .CTG............
|
|
000000B0 2E 00 80 00 00 00 00 00-00 00 00 00 2E 2E 00 00 ................
|
|
000000C0 00 00 00 00 00 00 00 00-00 00 ..........
|
|
|
|
Directory contents:
|
|
attribute 0x00 size date "name" 0x00
|
|
attribute is a byte describe little earlier in this document
|
|
(0 in attribute, date, length and name means end of direntry, ".." in name means "leave directory".
|
|
size is a word (filesize in byte)
|
|
time is a word (UNIX time)
|
|
|
|
|
|
****
|
|
** Upload (a little bit special):
|
|
****
|
|
|
|
Control_transfer_write
|
|
requesttype=0x40
|
|
requestvalue=0x04
|
|
value=0x10
|
|
length=0x40
|
|
data=0x00000000 0x0203 0x40+len1[explained later] [0x00 repeated 0x38]
|
|
|
|
Example:
|
|
00000000 00 00 00 00 03 02 7A 14-00 00 00 00 00 00 00 00 ......z.........
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
|
|
bulk_in_read [0x40 bytes]
|
|
Example:
|
|
00000000 00 00 00 00 03 03 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
|
|
bulk_write [data below]
|
|
|
|
len1[explained later] 0x00 0x00 0x00000403 0x00000000 0x00000000
|
|
[0x00 repeated 0x30 times]
|
|
0x00000002 0x03 0x00 0x00 0x11 len1 0x00 0x00 serial (this line looks very similar to "ordinary" commands)
|
|
0x00000002 offs len2 filename 0x00 datablock
|
|
|
|
bulk_in_read [0x5c bytes]
|
|
|
|
The whole procedure (i.e. Control_transfer_write(0x40 bytes) -> bulkread(0x40 bytes) ->
|
|
bulkwrite(len1+0x40 bytes) -> bulkread(0x5c bytes))
|
|
is repeated until the whole file is transmitted:
|
|
|
|
- offs is a word that starts at 0 and increments with blocksize each time.
|
|
|
|
- len1 is the length of the "bulk_write_data" block above, minus 0x40 (the
|
|
first length and padded zeros is not counted as in all other commands).
|
|
len1 is typically 0x143A using a standard 0x1400 (ms-windows) block
|
|
using the filename below (29 chars), last block is shorter.
|
|
|
|
- len2 is length of datablock (0x1400 is used in ms-windows), last
|
|
block is shorter serial is a random word that is returned as a reply.
|
|
|
|
- filname is "D:\DCIM\100CANON\IMG_0002.JPG" for example (file cannot
|
|
be created in nonexisting directory.)
|
|
|
|
- datablock is the datablock itself (the fragment of the JPG file).
|
|
|
|
Example of beginning of a block (first one):
|
|
00000000 3A 14 00 00 03 04 00 00-00 00 00 00 00 00 00 00 :...............
|
|
00000010 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000020 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000030 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
|
|
00000040 02 00 00 00 03 00 00 11-3A 14 00 00 78 56 34 12 ........:...xV4.
|
|
00000050 02 00 00 00 00 00 00 00-00 14 00 00 44 3A 5C 44 ............D:\D
|
|
00000060 43 49 4D 5C 31 30 30 43-41 4E 4F 4E 5C 49 4D 47 CIM\100CANON\IMG
|
|
00000070 5F 30 30 30 32 2E 4A 50-47 00 FF D8 FF E1 17 FE _0002.JPG.......
|
|
00000080 45 78 69 66 00 00 49 49-2A 00 08 00 00 00 09 00 Exif..II*.......
|
|
00000090 0F 01 02 00 06 00 00 00-7A 00 00 00 10 01 02 00 ........z.......
|