66#
77import sys
88import board
9- import busio
9+ import busio
1010
11- # Functions used for EDID parsing
1211def parse_established_timings (edid ):
12+ # pylint: disable=redefined-outer-name
13+ # pylint: disable=too-many-branches
1314 """Parse established timings from EDID bytes 35-37"""
1415 modes = []
15-
16+
1617 # Byte 35 (established timings I)
1718 if edid [35 ] & 0x80 :
1819 modes .append ("720x400 @70Hz" )
@@ -30,7 +31,7 @@ def parse_established_timings(edid):
3031 modes .append ("800x600 @56Hz" )
3132 if edid [35 ] & 0x01 :
3233 modes .append ("800x600 @60Hz" )
33-
34+
3435 # Byte 36 (established timings II)
3536 if edid [36 ] & 0x80 :
3637 modes .append ("800x600 @72Hz" )
@@ -48,31 +49,32 @@ def parse_established_timings(edid):
4849 modes .append ("1024x768 @75Hz" )
4950 if edid [36 ] & 0x01 :
5051 modes .append ("1280x1024 @75Hz" )
51-
52+
5253 # Byte 37 (manufacturer timings)
5354 if edid [37 ] & 0x80 :
5455 modes .append ("1152x870 @75Hz" )
55-
56+
5657 return modes
5758
5859def parse_standard_timings (edid ):
60+ # pylint: disable=redefined-outer-name
5961 """Parse standard timings from EDID bytes 38-53"""
6062 modes = []
61-
63+
6264 for i in range (38 , 54 , 2 ): # 8 standard timing descriptors, 2 bytes each
6365 if edid [i ] == 0x01 and edid [i + 1 ] == 0x01 :
6466 continue # Unused timing
65-
67+
6668 if edid [i ] == 0x00 :
6769 continue # Invalid timing
68-
70+
6971 # Calculate horizontal resolution
7072 h_res = (edid [i ] + 31 ) * 8
71-
73+
7274 # Calculate aspect ratio and vertical resolution
7375 aspect_ratio = (edid [i + 1 ] & 0xC0 ) >> 6
7476 refresh_rate = (edid [i + 1 ] & 0x3F ) + 60
75-
77+
7678 if aspect_ratio == 0 : # 16:10
7779 aspect = "16:10"
7880 v_res = (h_res * 10 ) // 16
@@ -85,100 +87,103 @@ def parse_standard_timings(edid):
8587 else : # aspect_ratio == 3, 16:9
8688 aspect = "16:9"
8789 v_res = (h_res * 9 ) // 16
88-
90+
8991 modes .append (f"{ h_res } x{ v_res } @{ refresh_rate } Hz, Aspect: { aspect } " )
90-
92+
9193 return modes
9294
9395def parse_detailed_timings (edid ):
96+ # pylint: disable=redefined-outer-name
9497 # pylint: disable=unused-variable
98+ # pylint: disable=too-many-locals
99+
95100 """Parse detailed timing descriptors from EDID bytes 54-125"""
96101 modes = []
97-
102+
98103 for i in range (54 , 126 , 18 ): # 4 detailed timing descriptors, 18 bytes each
99104 # Check if this is a timing descriptor (pixel clock != 0)
100105 pixel_clock = edid [i ] | (edid [i + 1 ] << 8 )
101106 if pixel_clock == 0 :
102107 continue # Not a timing descriptor
103-
108+
104109 # Parse horizontal resolution
105110 h_active_low = edid [i + 2 ]
106111 h_active_high = (edid [i + 4 ] & 0xF0 ) >> 4
107112 h_active = h_active_low | (h_active_high << 8 )
108-
113+
109114 # Parse vertical resolution
110115 v_active_low = edid [i + 5 ]
111116 v_active_high = (edid [i + 7 ] & 0xF0 ) >> 4
112117 v_active = v_active_low | (v_active_high << 8 )
113-
118+
114119 # Parse horizontal sync
115120 h_sync_offset_low = edid [i + 8 ]
116121 h_sync_width_low = edid [i + 9 ]
117122 h_sync_high = (edid [i + 11 ] & 0xC0 ) >> 6
118123 h_sync_offset = h_sync_offset_low | ((h_sync_high & 0x3 ) << 8 )
119124 h_sync_width = h_sync_width_low | ((h_sync_high & 0xC ) << 6 )
120-
125+
121126 # Parse vertical sync
122127 v_sync_offset_low = (edid [i + 10 ] & 0xF0 ) >> 4
123128 v_sync_width_low = edid [i + 10 ] & 0x0F
124129 v_sync_high = (edid [i + 11 ] & 0x0C ) >> 2
125130 v_sync_offset = v_sync_offset_low | ((v_sync_high & 0x3 ) << 4 )
126131 v_sync_width = v_sync_width_low | ((v_sync_high & 0xC ) << 2 )
127-
132+
128133 # Calculate refresh rate (approximate)
129134 h_blank_low = edid [i + 3 ]
130135 h_blank_high = edid [i + 4 ] & 0x0F
131136 h_blank = h_blank_low | (h_blank_high << 8 )
132137 h_total = h_active + h_blank
133-
138+
134139 v_blank_low = edid [i + 6 ]
135140 v_blank_high = edid [i + 7 ] & 0x0F
136141 v_blank = v_blank_low | (v_blank_high << 8 )
137142 v_total = v_active + v_blank
138-
143+
139144 if h_total > 0 and v_total > 0 :
140145 refresh_rate = (pixel_clock * 10000 ) // (h_total * v_total )
141146 modes .append (f"{ h_active } x{ v_active } @{ refresh_rate } Hz" )
142-
147+
143148 return modes
144149
145150# Main EDID reading code
146- i2c = busio .I2C (board .SCL , board .SDA )
151+ i2c = busio .I2C (board .SCL , board .SDA )
147152if not i2c :
148153 print ("Board doesn't have I2C" )
149154 sys .exit (1 )
150155if not i2c .try_lock ():
151156 print ("Cannot lock I2C" )
152157 sys .exit (1 )
153-
154- print ("\n I2C Present" )
155-
158+
159+ print ("\n I2C Present" )
160+
156161devices = i2c .scan ()
157- if not ( 0x50 in devices ) :
162+ if not 0x50 in devices :
158163 print ("No device found at EDID address 0x50, is the monitor plugged in " +
159164 "& board power cycled?" )
160165 sys .exit (1 )
161-
166+
162167print ("Device 0x50 found!" )
163168device = 0x50
164169edid = bytearray (128 )
165170out = bytearray ([0 ])
166171i2c .writeto_then_readfrom (device , out , edid )
167-
172+ # pylint: disable=too-many-boolean-expressions
168173if edid [0 ] != 0x00 or edid [1 ] != 0xFF or edid [2 ] != 0xFF or \
169174 edid [3 ] != 0xFF or edid [4 ] != 0xFF or edid [5 ] != 0xFF or \
170175 edid [6 ] != 0xFF or edid [7 ] != 0x00 :
171176 print ("EDID signature not recognized" )
172177 sys .exit (1 )
173-
178+
174179print ("Valid EDID signature!" )
175180
176181# Verify checksum
177182checksum = sum (edid ) & 0xFF
178183if checksum != 0 :
179184 print ("Bad EDID checksum detected" )
180185 sys .exit (1 )
181-
186+
182187print ("Good EDID checksum!" )
183188
184189# Parse all supported modes
0 commit comments