Merge pull request #3077 from adafruit/TheKitty-patch-7

Update Find_EDID_Values.py
This commit is contained in:
Anne Barela 2025-07-15 16:11:42 -04:00 committed by GitHub
commit e579992b2f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -6,12 +6,14 @@
#
import sys
import board
import busio
import busio
def parse_established_timings(edid):
# pylint: disable=redefined-outer-name
# pylint: disable=too-many-branches
"""Parse established timings from EDID bytes 35-37"""
modes = []
# Byte 35 (established timings I)
if edid[35] & 0x80:
modes.append("720x400 @70Hz")
@ -29,7 +31,7 @@ def parse_established_timings(edid):
modes.append("800x600 @56Hz")
if edid[35] & 0x01:
modes.append("800x600 @60Hz")
# Byte 36 (established timings II)
if edid[36] & 0x80:
modes.append("800x600 @72Hz")
@ -47,31 +49,32 @@ def parse_established_timings(edid):
modes.append("1024x768 @75Hz")
if edid[36] & 0x01:
modes.append("1280x1024 @75Hz")
# Byte 37 (manufacturer timings)
if edid[37] & 0x80:
modes.append("1152x870 @75Hz")
return modes
def parse_standard_timings(edid):
# pylint: disable=redefined-outer-name
"""Parse standard timings from EDID bytes 38-53"""
modes = []
for i in range(38, 54, 2): # 8 standard timing descriptors, 2 bytes each
if edid[i] == 0x01 and edid[i+1] == 0x01:
continue # Unused timing
if edid[i] == 0x00:
continue # Invalid timing
# Calculate horizontal resolution
h_res = (edid[i] + 31) * 8
# Calculate aspect ratio and vertical resolution
aspect_ratio = (edid[i+1] & 0xC0) >> 6
refresh_rate = (edid[i+1] & 0x3F) + 60
if aspect_ratio == 0: # 16:10
aspect = "16:10"
v_res = (h_res * 10) // 16
@ -84,92 +87,95 @@ def parse_standard_timings(edid):
else: # aspect_ratio == 3, 16:9
aspect = "16:9"
v_res = (h_res * 9) // 16
modes.append(f"{h_res}x{v_res} @{refresh_rate}Hz, Aspect: {aspect}")
return modes
def parse_detailed_timings(edid):
# pylint: disable=redefined-outer-name
# pylint: disable=unused-variable
# pylint: disable=too-many-locals
"""Parse detailed timing descriptors from EDID bytes 54-125"""
modes = []
for i in range(54, 126, 18): # 4 detailed timing descriptors, 18 bytes each
# Check if this is a timing descriptor (pixel clock != 0)
pixel_clock = edid[i] | (edid[i+1] << 8)
if pixel_clock == 0:
continue # Not a timing descriptor
# Parse horizontal resolution
h_active_low = edid[i+2]
h_active_high = (edid[i+4] & 0xF0) >> 4
h_active = h_active_low | (h_active_high << 8)
# Parse vertical resolution
v_active_low = edid[i+5]
v_active_high = (edid[i+7] & 0xF0) >> 4
v_active = v_active_low | (v_active_high << 8)
# Parse horizontal sync
h_sync_offset_low = edid[i+8]
h_sync_width_low = edid[i+9]
h_sync_high = (edid[i+11] & 0xC0) >> 6
h_sync_offset = h_sync_offset_low | ((h_sync_high & 0x3) << 8)
h_sync_width = h_sync_width_low | ((h_sync_high & 0xC) << 6)
# Parse vertical sync
v_sync_offset_low = (edid[i+10] & 0xF0) >> 4
v_sync_width_low = edid[i+10] & 0x0F
v_sync_high = (edid[i+11] & 0x0C) >> 2
v_sync_offset = v_sync_offset_low | ((v_sync_high & 0x3) << 4)
v_sync_width = v_sync_width_low | ((v_sync_high & 0xC) << 2)
# Calculate refresh rate (approximate)
h_blank_low = edid[i+3]
h_blank_high = edid[i+4] & 0x0F
h_blank = h_blank_low | (h_blank_high << 8)
h_total = h_active + h_blank
v_blank_low = edid[i+6]
v_blank_high = edid[i+7] & 0x0F
v_blank = v_blank_low | (v_blank_high << 8)
v_total = v_active + v_blank
if h_total > 0 and v_total > 0:
refresh_rate = (pixel_clock * 10000) // (h_total * v_total)
modes.append(f"{h_active}x{v_active} @{refresh_rate}Hz")
return modes
# Main EDID reading code
i2c = busio.I2C(board.SCL, board.SDA)
i2c = busio.I2C(board.SCL, board.SDA)
if not i2c:
print("Board doesn't have I2C")
sys.exit(1)
if not i2c.try_lock():
print("Cannot lock I2C")
sys.exit(1)
print("\nI2C Present")
print("\nI2C Present")
devices = i2c.scan()
if not (0x50 in devices):
if not 0x50 in devices:
print("No device found at EDID address 0x50, is the monitor plugged in " +
"& board power cycled?")
sys.exit(1)
print("Device 0x50 found!")
device = 0x50
edid = bytearray(128)
out = bytearray([0])
i2c.writeto_then_readfrom(device, out, edid)
# pylint: disable=too-many-boolean-expressions
if edid[0] != 0x00 or edid[1] != 0xFF or edid[2] != 0xFF or \
edid[3] != 0xFF or edid[4] != 0xFF or edid[5] != 0xFF or \
edid[6] != 0xFF or edid[7] != 0x00:
print("EDID signature not recognized")
sys.exit(1)
print("Valid EDID signature!")
# Verify checksum
@ -177,7 +183,7 @@ checksum = sum(edid) & 0xFF
if checksum != 0:
print("Bad EDID checksum detected")
sys.exit(1)
print("Good EDID checksum!")
# Parse all supported modes
@ -187,7 +193,7 @@ supported_modes = []
established_modes = parse_established_timings(edid)
supported_modes.extend(established_modes)
# Get standard timings
# Get standard timings
standard_modes = parse_standard_timings(edid)
supported_modes.extend(standard_modes)