| English |
Nikon Coolpix 2500Работа с камерой через USB |
Вместе с новой прошивкой камеры как правило поставляется программа для обновления прошивки. Можно сразу отметить, что острой необходимости в этой программе нет, прошивку можно обновить воспользовавшись CF-картой. Под Windows подключенная через USB камера видна как "Removable Device" или "Съемный диск". В корневой директории этого диска следует создать директорию "FIRMWARE", в которую надо поместить файл "FIRMWARE.BIN" с новой прошивкой. После переключения камеры в рабочий режим (т.е. выключаем камеру, отсоединяем USB кабель, снова включаем камеру) камера переходит в режим обновления firmware. Она показывает версию текущей прошивки, версию прошивки обнаруженной на карте и предлагает обновить прошивку. В своей камере я заменил прошивку именно таким образом.
Итак, никакой необходимости в специальной программе обновления прошивки нет, но раз уж эта программа имеется, и она способна общаться с камерой через USB появляется возможность понаблюдать как происходит это общение.
Общение с камерой осуществляет по стандартному протоколу от Sierra Imaging, более менее подробно описанном здесь. Команды начинаются с кодов 1B 43, в ответ камера отвечает кодом 06. Несколько примеров сообщений и их расшифровка:
Запрос уровня заряда батарей
| 1B 43 02 00 01 10 11 00 | |
| 1B | сообщение является командой |
| 43 | всегда следует за 0x1B |
| 0002 | длина команды |
| 01 | команда чтения из 32-битного регистра |
| 10 | номер регистра |
| 0011 | контрольная сумма (сумма всех байт: 01+10=0011) |
Запрос версии firmware
| 1B 43 02 00 04 1A 1E 00 | |
| 1B | сообщение является командой |
| 43 | всегда следует за 0x1B |
| 0002 | длина команды |
| 04 | команда чтения из регистра переменной длины |
| 1A | номер регистра |
| 001E | контрольная сумма (сумма всех байт: 04+1A=001E) |
Однако этот простой протокол реализован через вызовы IOCTL_SCSI_PASS_THROUGH_DIRECT, что несколько его усложняет. Для начала разберем запрос производителя и типа устройства (SCSIOP_INQUIRY). На этот запрос способны ответить не только камера, но и HDD, и CompactFlash карта подключенная через PC card адаптер, и наверное многие другие устройства.
2C 00 00 00 01 00 0C 18 01 00 00 00 24 00 00 00 : ,...........$... 0C 00 00 00 40 FA 12 00 30 00 00 00 12 00 00 00 : ....@...0....... 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : $............... 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 : ................ >> return OK 0012FA40: 00 80 02 02 1F 00 00 00 4E 49 4B 4F 4E 20 20 20 : ........NIKON... 4E 49 4B 4F 4E 20 44 53 43 20 45 32 35 30 30 20 : NIKON.DSC.E2500. 31 2E 30 30 : 1.00
Собственно запрос является структурой SCSI_PASS_THROUGH_DIRECT, описанной в файле "ntddscsi.h" из NT DDK, следует лишь обратить внимание на выравнивание полей. Так поля DataIn и DataTransferLength в структуре находятся рядом, а фактически поле DataTransferLength отстоит от DataIn на три байта и начинается со следующей позиции, кратной четырем.
typedef struct _SCSI_PASS_THROUGH_DIRECT {
USHORT Length;
UCHAR ScsiStatus;
UCHAR PathId;
UCHAR TargetId;
UCHAR Lun;
UCHAR CdbLength;
UCHAR SenseInfoLength;
UCHAR DataIn;
ULONG DataTransferLength;
ULONG TimeOutValue;
PVOID DataBuffer;
ULONG SenseInfoOffset;
UCHAR Cdb[16];
}SCSI_PASS_THROUGH_DIRECT, *PSCSI_PASS_THROUGH_DIRECT;
Расшифровка запроса:
| USHORT Length; | 002C |
| UCHAR ScsiStatus; | 00 |
| UCHAR PathId; | 00 |
| UCHAR TargetId; | 01 |
| UCHAR Lun; | 00 |
| UCHAR CdbLength; | 0C |
| UCHAR SenseInfoLength; | 18 - это поле всегда обнуляется при возврате |
| UCHAR DataIn; | 01 - признак R/W (1 - Read, 0 - Write) |
| UCHAR _hidden[3]; | 00 00 00 |
| ULONG DataTransferLength; | 00000024 - длина буфера данных |
| ULONG TimeOutValue; | 0000000C |
| PVOID DataBuffer; | 0012FA40 - адрес буфера данных |
| ULONG SenseInfoOffset; | 00000030 |
| это собственно команда | |
| ULONG Command; | 00000012 - код команды SCSIOP_INQUIRY |
| ULONG DataLengh; | 00000024 - совпадает с длиной, в других командах по другому |
Ответ является структурой INQUIRYDATA, описанной в "ddk\scsi.h" из NT DDK.
#define INQUIRYDATABUFFERSIZE 36
typedef struct _INQUIRYDATA {
UCHAR DeviceType : 5;
UCHAR DeviceTypeQualifier : 3;
UCHAR DeviceTypeModifier : 7;
UCHAR RemovableMedia : 1;
UCHAR Versions;
UCHAR ResponseDataFormat : 4;
UCHAR HiSupport : 1;
UCHAR NormACA : 1;
UCHAR ReservedBit : 1;
UCHAR AERC : 1;
UCHAR AdditionalLength;
UCHAR Reserved[2];
UCHAR SoftReset : 1;
UCHAR CommandQueue : 1;
UCHAR Reserved2 : 1;
UCHAR LinkedCommands : 1;
UCHAR Synchronous : 1;
UCHAR Wide16Bit : 1;
UCHAR Wide32Bit : 1;
UCHAR RelativeAddressing : 1;
UCHAR VendorId[8];
UCHAR ProductId[16];
UCHAR ProductRevisionLevel[4];
UCHAR VendorSpecific[20];
UCHAR Reserved3[40];
} INQUIRYDATA, *PINQUIRYDATA;
Последние два поля драйвер NT не использует. Так что полная длина структуры равна 36 байтам,
что мы видим в ответе камеры и в макросе INQUIRYDATABUFFERSIZE. Раcшифровка ответа:
| UCHAR DeviceType : 5; | 0 - DIRECT_ACCESS_DEVICE |
| UCHAR DeviceTypeQualifier : 3; | 0 - DEVICE_CONNECTED |
| UCHAR DeviceTypeModifier : 7; | 0 |
| UCHAR RemovableMedia : 1; | 1 - RemovableMedia |
| UCHAR Versions; | 2 |
| UCHAR ResponseDataFormat : 4; | 2 |
| UCHAR HiSupport : 1; | 0 |
| UCHAR NormACA : 1; | 0 |
| UCHAR ReservedBit : 1; | 0 |
| UCHAR AERC : 1; | 0 |
| UCHAR AdditionalLength; | 0x15 (31) |
| UCHAR Reserved[2]; | 00 00 |
| UCHAR SoftReset : 1; | 0 |
| UCHAR CommandQueue : 1; | 0 |
| UCHAR Reserved2 : 1; | 0 |
| UCHAR LinkedCommands : 1; | 0 |
| UCHAR Synchronous : 1; | 0 |
| UCHAR Wide16Bit : 1; | 0 |
| UCHAR Wide32Bit : 1; | 0 |
| UCHAR RelativeAddressing : 1; | 0 |
| UCHAR VendorId[8]; | "NIKON " |
| UCHAR ProductId[16]; | "NIKON DSC E2500 " |
| UCHAR ProductRevisionLevel[4]; | "1.00" |
Все другие запросы построены по такому же принципу, но коды запросов имеют значения от 0xE0 до 0xE5.
В таблице ниже приводится общий вид протокола обмена. Поля код и R/W из приведенной выше структуры. Данные - содержимое буфера данных на входе (передача данных в камеру, W, DataIn=0), или на выходе (прием данных из камеры, R, DataIn=1).
| код | R/W | данные | комментарий |
|---|---|---|---|
| Запрос данных из камеры | |||
| E0 | W | 10 00 00 00 01 00 FF 9F 00 00 00 00 00 00 00 00 | начало цикла обмена |
| E1 | W | 48 00 00 00 02 00 00 00 00 ... (*) 1B 43 02 00 04 1A 1E 00 | команда протокола Sierra Imaging |
| E3 | R | 0E 00 00 00 03 00 FF 9F 00 00 00 00 00 00 | подтверждение приема команды |
| E0 | W | 10 00 00 00 01 00 FF 9F 00 00 00 00 00 00 00 00 | начало цикла обмена |
| E4 | R | 10 00 00 00 02 00 FF 9F 00 00 00 00 4E 00 00 00 | запрос длины ответа |
| E2 | R | 4E 00 00 00 02 00 FF 9F 00 00 ... (*) 03 00 08 00 76 35 38 35 2D 37 35 00 FF FF | ответ (v585-75) |
| E3 | R | 0E 00 00 00 03 00 FF 9F 00 00 00 00 00 00 | подтверждение приема команды |
| E0 | W | 10 00 00 00 01 00 FF 9F 00 00 00 00 00 00 00 00 | начало цикла обмена |
| E1 | W | 41 00 00 00 02 00 00 00 00 00 ... (*) 06 | подтверждение команды Sierra Imaging |
| E3 | R | 0E 00 00 00 03 00 FF 9F 00 00 00 00 00 00 | подтверждение приема команды |
| Отправка данных в камеру | |||
| E0 | W | 10 00 00 00 01 00 FF 9F 00 00 00 00 00 00 00 00 | начало цикла обмена |
| E1 | W | 4C 00 00 00 02 00 00 00 00 00... (*) 1B 43 06 00 00 20 BE BE ED 0F 98 02 | команда протокола Sierra Imaging |
| E3 | R | 0E 00 00 00 03 00 FF 9F 00 00 00 00 00 00 | подтверждение приема команды |
| E0 | W | 10 00 00 00 01 00 FF 9F 00 00 00 00 00 00 00 00 | начало цикла обмена |
| E4 | R | 10 00 00 00 02 00 FF 9F 00 00 00 00 41 00 00 00 | запрос длины ответа |
| E2 | R | 41 00 00 00 02 00 FF 9F 00 00... (*) 06 | подтверждение команды Sierra Imaging |
| E3 | R | 0E 00 00 00 03 00 FF 9F 00 00 00 00 00 00 | подтверждение приема команды |
| Завершение работы с камерой | |||
| E5 | W | конец работы с камерой | |
| e2500.narod.ru |