This is the gphoto's description of the Canon PowerShot serial/USB protocol, s10sh is based on this document. (read/print this document with a non-proportional font such as courier) ============================================ ====== Canon Powershot Series ====== ==== Transfer Protocol Specifications ===== ============================================ Timestamp: 2000-06-29 * 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 S100. 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. Another program implements this protocol: s10sh, which is a command-line interface. Look for their records on freshmeat.net ! * Contributors: This document was written thanks to the efforts of: Wolfgang G. Reissnegger, Werner Almesberger, Philippe Marzouk, Mikael Nyström, Edouard Lafargue, Salvatore Sanfilippo * Copyright : The Canon Protocol information. Copyright (c) 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: 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. 28 June 2000: Merged the changes from Salvatore. ========================================================================= ============================================ == Background information on the == === Canon Powershot series === ============================================ Here's some information about the hardware found in the canon powershot series cameras, in case you are interested: - Processor: 8086-compatible chip () - Running the datalight embedded DOS (www.datalight.com) - Canon had their own name, "DigitalEye" for the OS/camera environment. It is possible to look into the camera embedded softare by listing other drives than the default flash card: A: -> Main camera application (to be confirmed) B: -> Data, tables (to be confirmed) C: -> D: -> CF card one E: -> On the powershot 70, probably CF card two (to be confirmed) ============================================ == 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 | | 00 C0 01 12 34 (fictious CRC) | | 00 7E E0 01 12 34 | | C0 00 7E E0 01 12 34 C1 v | [ Wire format ] The upper layers are described later in this file. Note that even the checksum bytes must be escaped. 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). On the S-series (S10/S20), the interval can be even shorter, like 0.4 sec, so initialization is faster. 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 four/five second 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. It looks like 4/5 seconds is the camera's own timeout for receiving commands. 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: There are two sequence numbers: the message sequence number and the fragment sequence number . They are counted independently and start at zero. is reset at the beginning of a session, while is reset at the beginning of each message. The following packet types are known: 00 Message fragment 02 Switch the camera off 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. If the camera does not get the ACK it resends the EOT several times. EOT has the following format: xx 04 xx 00 00 00 | | | indication of the message length. Known values: 00 empty message (no fragments) 01 short message (one fragment) 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 The ACK error code is 00 to ACKnowledge the packet, a packet with 01 ask to the camera to resend the first fragment of the last message, 02 ask to the camera to resend the second fragment and so on. the code 0xFF retransmits all the packets of the last message. The ACK sequence number is initally 0, then it is incremented for every _good_ ACK. If you send an ack with error code != 0 you must NOT increment the ACK sequence. 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 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 sent to/from the camera have the following structure: 02 00 00 00 xx 00 00 xx xx xx 00 00 xx xx xx xx ... | | | | | | | | | | Serial nb. message payload | | | message length, MSB | | message length, LSB | direction code message type The message length is the length of the entire message, including the header shown above. The serial number can be chosen at random (use the date for example) and will be returned in the response of the camera. List of known message types/directions: Operation 01 11 Download file 01 12 Identify camera 03 11 Upload file (?) 03 12 Get Date 04 12 Set date 05 11 Make directory 05 12 Change Owner name 06 11 Remove directory 09 11 Disk info request 0a 11 Get flash device identification 0a 12 Power Supply Status 0b 11 List directory 0d 11 Delete file 0e 11 Set file attributes 01 22 Identify camera response 01 21 File download data 03 22 Get Date response 09 21 Disk info response 0a 21 Get disk(s) response 0a 22 Power Supply Status response 0b 21 List without date response 0b 21 List with date response 0d 21 Delete image response A message with 02 is sent by the camera to notify that it isn't no longer if PC-transfer mode (<-._> symbol), this happens when the user switches the camera to some other mode. The four first bytes of each response message is the error code of the operation. Here's the list of known codes: 0x00000000 : Success 0x02000022 : No such file 0x02000029 : File is protected 0x02000040 : No such directory 0x02000087 : No such disk 0x02000086 : Path not found (?) ------------------------------------------ - List Of commands ------------------------------------------ Each command is described in the following format: Command name ------------ * Explanation of what the command does * Format of the request packet. * Format of the response packet with offsets to each part of the data. Offset zero is the first byte after the error code. * Example of request packet (with framing/escaping) * Example of response packet (after unescaping/without framing/CRC) Identify camera --------------- * Asks the camera for some of its parameters: model, firmware, owner. * The identify camera request has no data. * The identify camera response has the following structure: - A5/A50 models : 00 02 00 00 00 00 00 01 00 (more 00s) - S10/S20 : 00 04 00 00 00 00 00 01 and then: (32 bit word) (offset: 0x08) (C string) (offset: 12 / 0x0c) (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 of id camera request: WRITE: (24 bytes) 00000000: C0 00 00 10 00 02 00 00 00 01 00 00 12 10 00 00 - ................ 00000010: 00 14 F7 8A 00 AD 7A C1 - ......z. * Example of id camera response, 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 ---------------- * This command show the current power status of the camera * The get power status command has no data. * The get power status response has the following structure: 0x00 contains a byte with power status: 0x6=good, 0x4=bad 0x03 contains a byte with powertype: 0x10=ac-adaptor, 0x30=battery * Example of get power status request: WRITE: (24 bytes) 00000000: C0 00 00 10 00 02 00 00 00 0A 00 00 12 10 00 00 - ................ 00000010: 00 70 F6 8A 00 7B 46 C1 - .p...{F. * Example of get power status response: 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 ---------------- * This command sets the owner name in the camera. I am not sure this command is supported in the A-series, but both the S10 and the S20 support it. * The payload is a C string (null-terminated) of 30 characters max. * Response: the response contains the error code only. Get Date -------- * This command returns the internal date of the camera. As powershots don't contain a timezone, the date is returned must not be converted to local time. * Payload: no data * Response format: Offsets: 0x00 : Date, unix format, local time, little-endian * Example of request packet: WRITE: (24 bytes) 00000000: C0 00 00 10 00 02 00 00 00 03 00 00 12 10 00 00 - ................ 00000010: 00 78 F3 64 01 A7 77 C1 - .x.d..w. * Example of response packet: RECV: (38 bytes) 00000000: 00 00 20 00 02 00 00 00 03 00 00 22 20 00 00 00 - .. ........" ... 00000010: 78 F3 64 01 00 00 00 00 90 1B 5A 39 00 00 00 00 - x.d.......Z9.... 00000020: 00 00 00 00 57 CC - ....W. Set Date -------- * This command sets the date in the camera. * Request format: 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. * Response format * Example of request packet: * Example of response packet: Make directory -------------- * Creates a directory in the camera. * Request format: The payload of this message is a null-terminated string containing the name of the directory to create. * Response format: The response packet only contains the error code: * Example of request packet: [Canon PowerShot S10] D:> mkdir ED WRITE: (30 bytes) 00000000: C0 00 00 16 00 02 00 00 00 05 00 00 11 16 00 00 - ................ 00000010: 00 00 00 00 00 44 3A 5C 45 44 00 13 7F C1 - .....D:\ED.... * Example of response packet: RECV: (26 bytes) 00000000: 00 00 14 00 02 00 00 00 05 00 00 21 14 00 00 00 - ...........!.... 00000010: 00 00 00 00 00 00 00 00 48 6E - ........Hn Remove directory ---------------- * Removes a directory in the camera. * Request format: The payload of this message is a null-terminated string containing the name of the directory to delete. * Response format: The response packet only contains the error code: 0x0 in case of success 0x2000040 in case of error (no such directory) * Example of request packet: WRITE: (31 bytes) 00000000: C0 00 00 16 00 02 00 00 00 06 00 00 11 16 00 00 - ................ 00000010: 00 00 00 00 00 44 3A 5C 45 44 00 2B 7E 5E C1 - .....D:\ED.+.^. * Example of response packet: Returned packet after a successful directory deletion : RECV: (26 bytes) 00000000: 00 00 14 00 02 00 00 00 06 00 00 21 14 00 00 00 - ...........!.... 00000010: 00 00 00 00 00 00 00 00 69 F4 - ........i. Returned packet after a rmdir of a non-existing dir: RECV: (26 bytes) 00000000: 00 00 14 00 02 00 00 00 06 00 00 21 14 00 00 00 - ...........!.... 00000010: 00 00 00 00 40 00 00 02 CC C1 - ....@..... Flash device identification --------------------------- * Returns the name of the flash drive where pictures are stored. * The flash device request has no arguments. * The flash device response has the following structure: 0x0: C-string containing the disk name. * Example of request: WRITE: (24 bytes) 00000000: C0 00 00 10 00 02 00 00 00 0A 00 00 11 10 00 00 - ................ 00000010: 00 DC F7 8A 00 A9 FF C1 - ........ * Example of response: RECV: (30 bytes) 00000000: 00 00 18 00 02 00 00 00 0A 00 00 21 18 00 00 00 - ...........!.... 00000010: DC F7 8A 00 00 00 00 00 44 3A 00 00 49 5E - ........D:..I^ Disk info --------- * Disk info returns the total capacity and free space on the requested device. * Disk info requests have the following structure: 0x0: C-String containing the name of the device ("D:\") Root name example: "C:\" (The trailing slash is required.) * Disk info responses have the following structure: 0x0: 32bit integer representing total capacity 0x4: 32bit integer representing free space xx xx xx xx xx xx xx xx | | | Free space (in bytes) Total capacity (in bytes) Error code: 0x00000000 in case of success 0x02000087 in case of error (non-existing drive) * Request example: WRITE: (28 bytes) 00000000: C0 00 00 14 00 02 00 00 00 09 00 00 11 14 00 00 - ................ 00000010: 00 D8 F7 8A 00 44 3A 5C 00 74 B6 C1 - .....D:\.t.. * Response example: Error: (diskinfo Z:) RECV: (34 bytes) 00000000: 00 00 1C 00 02 00 00 00 09 00 00 21 1C 00 00 00 - ...........!.... 00000010: D8 F7 8A 00 87 00 00 02 18 00 3C 19 94 2A 0E 00 - ..........<..*.. 00000020: DD 4B - .K Success: (diskinfo A:) RECV: (34 bytes) 00000000: 00 00 1C 00 02 00 00 00 09 00 00 21 1C 00 00 00 - ...........!.... 00000010: D8 F7 8A 00 00 00 00 00 80 E8 06 00 00 00 00 00 - ................ 00000020: A5 C0 - .. List (show directory contents) ------------------------------ * This command lists directory contents for a specified directory. * Structure of request packets: List requests have the following structure: xx 00 00 00 | recursion byte The "recursion byte" can take the following values: 0x00: non-recursive query 0x01: One level of recursion 0x02: Complete recursive directory listing ("ls -lR") Directory name example: "C:\PWRSHOT", "D:", or "D:\.", but not "D:\" (trailing slash), or "D:\.\FOO" (dot not allowed in path ?). A double-dot can be included in the path: "D:\DCIM\..". * Structure of response packets: List responses have the following structure (after the error code which is always at "0x0" in case of dir lists). Failure: 01 00 00 00 00 00 00 00 Success: xx 80 00 00 00 00 00 00 00 00 00 00 00 ... 00 - and are C-strings (null-terminated) - is: 01 if the packet is the last message 00 if more packets are to follow. - is one byte containing the file attributes: File attributes: bit 0: 1= write protected, 0=NOT write protected bit 4: 1=directory contains item but not recursived entered bit 5: 1=NOT downloaded, 0=downloaded (must be manually switched) bit 7: 1=recurively entered directory - is the size in bytes (4 bytes/little-endian). Directory size is always 0. - is a four bytes Unix-style date in little-endian format. * Example of a directory get sequence on a S10: [Canon PowerShot S10] D:> dir d: WRITE: (30 bytes) 00000000: C0 00 00 16 00 02 00 00 00 0B 00 00 11 16 00 00 - ................ 00000010: 00 A8 F6 8A 00 00 64 3A 00 00 00 65 4C C1 - ......d:...eL. WRITE: (10 bytes) 00000000: C0 04 04 01 00 00 00 88 D6 C1 - .......... RECV: (8 bytes) 00000000: 04 05 00 00 00 00 77 C1 - ......w. RECV: (66 bytes) 00000000: 00 00 3C 00 02 00 00 00 0B 00 00 21 3C 00 00 00 - ..<........!<... 00000010: A8 F6 8A 00 00 00 00 00 01 80 00 00 00 00 00 00 - ................ 00000020: 00 00 00 64 3A 00 10 00 00 00 00 00 C4 6A 42 39 - ...d:........jB9 00000030: 44 43 49 4D 00 00 00 00 00 00 00 00 00 00 00 00 - DCIM............ 00000040: DC CA - .. RECV: (8 bytes) 00000000: 03 04 01 00 00 00 59 CA - ......Y. WRITE: (10 bytes) 00000000: C0 03 05 00 00 00 00 A6 DD C1 - .......... -i-- DCIM Sat Jun 10 18:20:20 2000 1 files 0 bytes On S10/S20, if the directory is so large that several message fragments are needed, the fragments are transmitted the normal way as and the sequence is terminated by an EOT (usual way of transmitting a multi-fragment message). On the A5/A50 however, the following behaviour was described: If the directory is so large that additional messages are needed, the following messages have the following structure: 00 00 00 00 xx | 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 file ------------- * This command gets a file from the camera. An option allows to get the thumbnail instead of the whole file. * Structure of request packets: Download requests have the following structure: xx 00 00 00 00 xx 00 00 | | | Length of name (including terminating \0) 0x00 for image 0x01 for thumbnail * Structure of response packets: 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 You can check if the request generated an error checking for the byte at offset 0x16 (00 if more, 01 at end) since it is set to 01 in the first packet if the downloaded failed (this is just an hack since this detection method will fail is the file is shorter than one fragment) All lengths are measured in bytes/little-endian. The camera always sends 8 messages then sends an EOT and 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 eighth packet sent. These error values are not yet known. Note about thumbnails for S10/S20 models: The camera only sends the 10813 first bytes of the image for the thumbnail download request. However it is not a valid image: the camera response you get just contains enough data to parse the EXIF header and extract the thumbnail. The remaining bytes left after parsing are the beginning of the actual image and should be discarded. In order to get the thumbnail, you will have to look for values "FF D8" and "FF D9" in the data , and the thumbnail (valid jpeg image) is between these two values (including ffd8 and ffd9). This is not the prefered method as "ffd8" and "ffd9" can appear anywhere in the data. It is best to parse the header properly. Gphoto offers an EXIF parsing API. * Example of request: WRITE: (62 bytes) 00000000: C0 00 00 36 00 02 00 00 00 01 00 00 11 36 00 00 - ...6.........6.. 00000010: 00 6A 08 79 04 01 00 00 00 00 1E 00 00 44 3A 5C - .j.y.........D:\ 00000020: 64 63 69 6D 5C 31 31 38 63 61 6E 6F 6E 5C 69 6D - dcim\118canon\im 00000030: 67 5F 31 38 34 31 2E 6A 70 67 00 62 C4 C1 - g_1841.jpg.b.. * Examples of answers: - Error for a get on a non-existing file: RECV: (42 bytes) 00000000: 00 00 24 00 02 00 00 00 01 00 00 21 24 00 00 00 - ..$........!$... 00000010: 6A 08 79 04 22 00 00 02 00 00 00 00 00 00 00 00 - j.y."........... 00000020: 00 00 00 00 01 00 00 00 A4 A3 - .......... - First bytes of the first fragment in case of success: RECV: (1022 bytes) 00000000: 00 00 F8 03 02 00 00 00 01 00 00 21 24 1E 00 00 - ...........!$... 00000010: 6A 08 79 04 00 00 00 00 9B 1E 00 00 00 00 00 00 - j.y............. 00000020: 00 1E 00 00 00 00 00 00 FF D8 FF E1 1D FE 45 78 - ..............Ex 00000030: 69 66 00 00 49 49 2A 00 08 00 00 00 09 00 0F 01 - if..II*......... 00000040: 02 00 06 00 00 00 7A 00 00 00 10 01 02 00 14 00 - ......z......... 00000050: 00 00 80 00 00 00 12 01 03 00 01 00 00 00 01 00 - ................ 00000060: 00 00 1A 01 05 00 01 00 00 00 94 00 00 00 1B 01 - ................ 00000070: 05 00 01 00 00 00 9C 00 00 00 28 01 03 00 01 00 - ..........(..... ........: .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. .. - 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 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. Control_transfer_write requesttype=0x40 value=0x11 length=0x10 data=[from step 2] 4. PC sign should now appear on the LCD 5. Receive 0x44 bytes from bulk_in and throw it away. 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 .... ================================================================================ 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 : serial 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 - Serial 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 | 0x1 "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 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: 0x10=ac-adaptor, 0x30=battery **** ** 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 (1= write protected, 0=NOT write protected) bit4 (1=directory contains item but not recursived entered) (NOT used with the attrib command) bit5 (1=NOT downloaded, 0=downloaded) (must be manually switched) bit7 (1=recurively entered directory) (NOT used with the attrib command) Example: 0x21 file is NOT downloaded but deleteprotected **** ** 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: bit1 (1=deleteprotected, 0=NOT deleteprotected) bit4 (1=directory contains item but not recursived entered) (NOT used with the attrib command) bit5 (1=NOT downloaded, 0=downloaded) (must be manually switched) bit8 (1=recurively entered directory) (NOT used with the attrib command) Example: 0x21 file is NOT downloaded but deleteprotected 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 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] This 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. - filename is "D:\DCIM\100CANON\IMG_0002.JPG" for example (files cannot be created in non-existing 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....... * ALL THIRD PARTY BRAND, PRODUCT AND SERVICE NAMES MENTIONED ARE * THE TRADEMARK OR REGISTERED TRADEMARK OF THEIR RESPECTIVE OWNERS