Ранее в статье Учим iCEstick передавать видео-сигнал по VGA мы узнали, как работает VGA. Однако кое-что осталось за кадром. Когда я подключаю VGA-кабель к ноутбуку и говорю xrandr
, программа выводит список разрешений, поддерживаемых монитором. Как она получает эту информацию?
Оказывается, что в каждом VGA-кабеле есть шина I2C . Под нее отведены пины 12 (SDA) и 15 (SCL). Ну раз такое дело, давайте возьмем HydraBus и подключимся к этим пинам:
Просканируем адреса на шине:
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 байт:
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
хранят три буквы имени производителя, по пять бит на каждую букву:
‘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. Декодируется она следующим образом:
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».
Далее мы видим последовательность:
Каждые два байта кодируют поддерживаемое разрешение, всего до 8 возможных дополнительных разрешений. Специальная последовательность 01 01
означает пустое значение. Попробуем декодировать первые два байта:
1152
>>> «{:08b}».format(0x4F)
‘01001111’
В первом байте закодировано количество пикселей по горизонтали. Во втором байте старшие два бита 01 означают aspect ratio 4:3 (00 = 16:10, 01 = 4:3, 10 = 5:4, 11 = 16:9), а в младших шести битах закодирована частота:
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
:
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
Вроде, сходится. Таким образом, еще одна загадка вселенной успешно разгадана.