Ранее в статье Учим iCEstick передавать видео-сигнал по VGA мы узнали, как работает VGA. Однако кое-что осталось за кадром. Когда я подключаю VGA-кабель к ноутбуку и говорю xrandr , программа выводит список разрешений, поддерживаемых монитором. Как она получает эту информацию?

Оказывается, что в каждом VGA-кабеле есть шина I2C . Под нее отведены пины 12 (SDA) и 15 (SCL). Ну раз такое дело, давайте возьмем HydraBus и подключимся к этим пинам:

Просканируем адреса на шине:

i2c1> scan
Device found at address 0x37
Device found at address 0x50
Device found at address 0x51
Device found at address 0x52
Device found at address 0x53
Device found at address 0x54
Device found at address 0x55
Device found at address 0x56
Device found at address 0x57

Из всех этих устройств нас интересует устройство с адресом 0 x 50. Если честно, я не знаю, для чего нужны остальные, и есть ли они на всех мониторах. Итак, с этого устройства нам нужно прочитать 128 байт:

i2c1> [ 0xA0 0x00 ] [ 0xA1 hd:128 ]
I2C START
WRITE: 0xA0 ACK 0x00 ACK
I2C STOP
I2C START
WRITE: 0xA1 ACK
00 FF FF FF FF FF FF 00  04 72 AC 00 66 F6 00 01  |  ………r..f…
0A 14 01 03 68 34 1D 78  2A EE D1 A5 55 48 9B 26  |  ….h4.x*…UH.&
12 50 54 B3 0C 00 71 4F  81 80 95 00 81 00 D1 C0  |  .PT…qO……..
01 01 01 01 01 01 02 3A  80 18 71 38 2D 40 58 2C  |  …….:..q8-@X,
45 00 09 25 21 00 00 1E  00 00 00 FD 00 38 4B 1E  |  E..%!……..8K.
53 12 00 0A 20 20 20 20  20 20 00 00 00 FF 00 4C  |  S…      …..L
47 34 30 38 30 31 36 34  32 32 30 0A 00 00 00 FC  |  G4080164220…..
00 41 43 45 52 20 58 32  34 33 48 51 0A 20 00 F6  |  .ACER X243HQ. ..
NACK
I2C STOP

Здесь 0 x A0 — это адрес устройства, сдвинутый на один бит влево и с нулем в младшем бите, означающим запись. Следом мы передаем байт 0 x 00, означающий адрес в памяти, с которого мы хотим начать читать. Передаваемый следом байт 0 x A1 — это снова сдвинутый на один бит адрес устройства, но на этот раз с единицей в младшем бите, что означает чтение. Затем мы считываем 128 байт и выводим их в виде hex dump’а.

Полученные байтики — это данные в формате EDID, Extended Display Identification Data. Сей формат неплохо описан в Википедии , так что нам не должно составить труда его декодировать.

Первые 8 байт представляют собой фиксированный заголовок. Следующие два байта 04 72 хранят три буквы имени производителя, по пять бит на каждую букву:

>>> «{:08b}».format(0x04)
‘00000100’
>>> «{:08b}».format(0x72)
‘01110010’
>>> chr(ord(‘A’) — 1 + 0b00001)
‘A’
>>> chr(ord(‘A’) — 1 + 0b00011)
‘C’
>>> chr(ord(‘A’) — 1 + 0b10010)
‘R’

Ну да, устройство действительно было произведено компанией Acer. Байты AC 01 это код продукта, а 66 F6 00 01 — его серийный номер. Такой же серийный номер можно найти на наклейке с обратной стороны монитора. Дальше идут байты 0A 14 . Это неделя и год производства дисплея, 10-ая неделя (возможно, 11-ая, если производитель нумерует их с нуля) 1900 + 20 = 2010 года. Сзади монитора написано, что он сделан в марте 2010. Вроде, все сходится. Идущие следом байты 01 03 означают версию EDID 1.3. Если версия иная, скорее всего, что-то пошло сильно не так.

Дальше мы немного пропустим и рассмотрим байты 35-37 (нумерация байт начинается с нуля): B3 0C 00 . Это битовая маска, отражающая поддержку дисплеем «традиционных» разрешений и FPS. Декодируется она следующим образом:

1 — 720×400 @ 70 Hz
0 — 720×400 @ 88 Hz
1 — 640×480 @ 60 Hz
1 — 640×480 @ 67 Hz
0 — 640×480 @ 72 Hz
0 — 640×480 @ 75 Hz
1 — 800×600 @ 56 Hz
1 — 800×600 @ 60 Hz

0 — 800×600 @ 72 Hz
0 — 800×600 @ 75 Hz
0 — 832×624 @ 75 Hz
0 — 1024×768 @ 87 Hz, interlaced
1 — 1024×768 @ 60 Hz
1 — 1024×768 @ 72 Hz
0 — 1024×768 @ 75 Hz
0 — 1280×1024 @ 75 Hz

Ну и последний байт 00 говорит нам о том, что дисплей не поддерживает 1152 x 870 @ 75 Hz и не имеет никаких «manufacturer-specific display modes».

Далее мы видим последовательность:

71 4F 81 80 95 00 81 00 D1 C0 01 01 01 01 01 01

Каждые два байта кодируют поддерживаемое разрешение, всего до 8 возможных дополнительных разрешений. Специальная последовательность 01 01 означает пустое значение. Попробуем декодировать первые два байта:

>>> (0x71 + 31) * 8
1152
>>> «{:08b}».format(0x4F)
‘01001111’

В первом байте закодировано количество пикселей по горизонтали. Во втором байте старшие два бита 01 означают aspect ratio 4:3 (00 = 16:10, 01 = 4:3, 10 = 5:4, 11 = 16:9), а в младших шести битах закодирована частота:

>>> 60 + 0b001111
75

Итого получаем 1152 x 864 @ 75 Hz. По аналогии оставшиеся байты декодируются в 1280 x 1024 @ 60 Hz, 1440 x 900 @ 60 Hz, 1280 x 800 @ 60 Hz и 1920 x 1080 @ 60 Hz.

Сравним получившийся список разрешений и FPS с выводом xrandr :

VGA-1 connected (normal left inverted right x axis y axis)
1920×1080     60.00 +
1280×1024     60.02
1440×900      59.89
1280×800      59.81
1152×864      75.00
1024×768      70.07    60.00
800×600       60.32    56.25
640×480       66.67    59.94
720×400       70.08

Вроде, сходится. Таким образом, еще одна загадка вселенной успешно разгадана.

admin

Share
Published by
admin

Recent Posts

Консоль удаленного рабочего стола(rdp console)

Клиент удаленного рабочего стола (rdp) предоставляет нам возможность войти на сервер терминалов через консоль. Что…

1 месяц ago

Настройка сети в VMware Workstation

В VMware Workstation есть несколько способов настройки сети гостевой машины: 1) Bridged networking 2) Network…

1 месяц ago

Логи брандмауэра Windows

Встроенный брандмауэр Windows может не только остановить нежелательный трафик на вашем пороге, но и может…

1 месяц ago

Правильный способ отключения IPv6

Вопреки распространенному мнению, отключить IPv6 в Windows Vista и Server 2008 это не просто снять…

1 месяц ago

Ключи реестра Windows, отвечающие за параметры экранной заставки

Параметры экранной заставки для текущего пользователя можно править из системного реестра, для чего: Запустите редактор…

1 месяц ago

Как управлять журналами событий из командной строки

В этой статье расскажу про возможность просмотра журналов событий из командной строки. Эти возможности можно…

1 месяц ago