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 |