eddy_em: (Костерок)
[personal profile] eddy_em
Когда-то давным-давно я "ломал" пару "канонических" объектива при помощи пиковского мелкоконтроллера, результат выложил у себя на гитхабе (также есть зеркала на сосфорже, гитлабе и битбакете — я после истории с гуглокодом все яйца в одной корзине не храню!).
И вот, опять понадобилось повозиться с объективом, т.к. ребята, пытающиеся в лабвью запустить EF200 по моей шпаргалке, долго бились, в результате сказали, что, возможно, фотоаппарат вообще генерирует каждый раз псевдослучайную последовательность и шифрует код.
В итоге морда была подключена к тушке (надо будет фотоаппарат притащить и сфотографировать все это чудо) шлейфом (Гриша снял байонет с объектива и прицепил туда кусок стеклотекстолита, сам байонет прицепил к фотоаппарату, а объектив подпаял к байонету шлейфом), к ней я подпаял 4 проводка на SPI, подключил свой китайский клон Saleae Logick и стал анализировать.

И вот с анализированием все было плохо. Для начала, я очень долго мучился, пытаясь подобрать оптимальные настройки логанализатора, чтобы можно было хитрый протокол (естественно, каноновцы выдумали свой хитрожопый SPI-протокол, чтобы другим сложней было) сдампить. Вот как выглядит передача/прием одного байта:
2016.03.18_08:42:50
Вот этот маленький выброс на последнем бите и заставил меня целых полдня потратить впустую! Дело в том, что поначалу, сняв пробную порцию данных и увидев, что период синхроимпульсов составляет 12.75мкс (т.е. частота SPI около 78.431кГц), я решил сэкономить на объемах захваченной информации и снизить частоту сэмплирования до 250кГц. В итоге последний синхроимпульс был потерян и я впустую пытался придумать, какие же настройки задать логанализатору, чтобы сдампить результат. Потом поднял частоту до 8МГц и все встало на свои места.
Правда, пришлось схитрить. Вот такая вот дурацкая затея с поджатием к нулю CLK на время бездействия и поджатия его к единице перед началом "общения" заставила выбрать вот такие настройки:
2016.03.18_08:42:57
Т.е. 9-битный режим с data valid на нарастающем фронте синхроимпульса.
Понятно, что в таком виде данные никак не проанализировать. Поэтому был написан парсер дампов:
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv){
	char *inm = argv[1], *onm = argv[2];
	FILE *fin = fopen(inm, "r");
	char *buf = malloc(256);
	printf("# time   MOSI  MISO\n");
	double told = 0.;
	do{
		size_t len = 256;
		if(getline(&buf, &len, fin) < 1) break;
		char *brace;
		if(!(brace = strchr(buf, '('))) continue;
		double t; int mosi, miso;
		t = atof(buf);
		++brace;
		mosi = strtol(brace, NULL, 16);
		if(!(brace = strchr(brace, '('))) continue;
		miso = strtol(brace+1, NULL, 16);
		if(t - told > 0.001) printf("\n"); // next data portion
		printf("%7.5f  %.2x  %.2x\n", t, mosi >> 1, miso >> 1);
		told = t;
	}while(1);
	fclose(fin);
}

Он считывает дамп-файл логанализатора, где каждая строка имеет вид
0.00015375,0,'1' (0x001),'17' (0x011)

затем выдирает оттуда времéнную метку и данные SPI (в скобках), сдвигая данные на один бит вправо, и выводит на стандартный вывод, чтобы можно было сохранить их в какой-то другой файл.
Я экспортировал все в один и тот же файл (canon.txt), поэтому для упрощения преобразования дампа набросал скриптик:
#!/bin/bash
./proc_exp canon.txt > $1.dat
cp canon.txt $1.txt

Так как очень много места в каждой порции данных занимают команды опроса объектива, чтобы наглядней выявить особенности каждого файла, я строил гистограммы частот появления команд:
#!/bin/bash
cat $* | awk '{print $2 " " $3}' | sort | uniq -c | sort -n

Казалось бы, все готово и все рады, но не тут-то было! Во-первых, обнаруженные команды совершенно не соответствовали командам из моего списка (большинство из них попадались на "неизведанные"). Во-вторых, из-за очень частого опроса объектива, когда ответ один и тот же, анализировать данные довольно-таки сложно. Видимо, надо еще один парсер написать, который будет выбрасывать повторяющиеся одинаковые блоки.
Пока что результат таков:
  • блоки опроса различаются для режимов "ручной фокус" и "автофокус";

  • часть команд (0a, 90, a0, b0, b2, c0, e0, e4, e8, ea, f0, f8, fa, fc, fe) появляется наиболее часто и явно предназначена для опроса состояния объектива;

  • еще часть команд (01, 05, 06, 07, 0c, 0f, 2d, 2e, 50, 80, 99) встречается значительно реже, т.е. явно имеет какой-то особый смысл (управление фокусировкой, опрос при инициализации, опрос значения фокуса и т.п.); интересно, что команды 0xC2, которую я использовал раньше для того, чтобы узнать значение отсчета фокуса, в данном случае нигде нет!

  • команды 0a, 90, a0, b0, b2, e4 наиболее часто встречаются в процедуре опроса объектива сразу после включения, т.е. можно сказать, что они отвечают за состояние объектива;

  • а вот команды 01, 07, 0c, 0e, 0f, 2f, 50, 80, 99, c0 при включении встречаются значительно реже — явно они нужны для инициализации и/или опроса редко изменяющихся данных;

  • странно, что при ручной фокусировке дампы вообще ничем не отличались! По крайней мере, ответы были одними и теми же, в обоих случаях команды 01, 0a, 2f, 50, 80, 90, 99 использовались лишь единожды, а основную массу набирали команды опроса состояния;

  • а вот анализ дампа автофокусировки показал забавную вещь: здесь используется уже найденная ранее "методом тыка" (нет, физикам нужно говорить "методом Монте-Карло"!) команда 0xc0 (194), которая позволяет узнать угловую координату лимба фокуса (а не значение в метрах);

  • команда 0x0a почему-то имеет то 2 байта ответа (0xaa, 0x00 — наиболее часто), то всего один (в первом пакете каждого опроса подряд идут команды 0x80, 0x0a и 0x99, в ответ на которые приходит 0x81, 0x87, 0x00);

  • команде 0xe4 всегда дается ответ 0x9c, 0x6a, при работе с другим объективом ответ был другим — явно сигнатура какая-то;

  • в основном ответ команд — либо их эхо, либо 1-2 байта данных, но есть рекордсмены: 0x01 имеет 6 байт ответа (используется при инициализации, возможно, это запрос модели объектива); 0x90 имеет три байта ответа и данные меняются при нажатиях разных кнопок объектива; команда 0xb0 имеет то 3, то 4 байта ответа (0x16, 0x16, 0x50[, 0x00]); 0xb2 имеет 4 байта ответа, меняющихся при автофокусе и постоянных при ручном изменении фокусировки; команда опроса положения лимба (используется при автофокусировке) имеет на самом деле 3 байта в ответе, хотя последний байт всегда нулевой; у команды 0xe8 7 байт ответа (кроме первых двух байт остальные — нули), а у 0xea — 6 байт (тоже только 2 реальных данных), обе используются только при автофокусе и ответ обеим меняется "синхронно" (но по-разному);

  • еще при автофокусировке встречается последовательность команд 0xf8, 0xfc, 0xfa, 0xfe, 0x00, которым приходит разный ответ (судя по тому, что в ответ на 0xfe тоже приходит 1 байт, нулевой в конце добавлен "для пущей безопасности");

  • и т.д., и т.п.


Возможно, подробный анализ что-нибудь да покажет, но лучше уж сразу запрограммировать STM8 или STM32 и попытаться "пообщаться" с объективом с микроконтроллера.

Если кому-то интересно поразмыслить над логами, я запушил их в репозиторий.
This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org

October 2025

S M T W T F S
   1234
567 89 1011
121314 15161718
19202122232425
2627 28293031 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Feb. 26th, 2026 06:45 pm
Powered by Dreamwidth Studios