66#
77import sys
88import board
9- import busio
9+ import busio
1010
1111def parse_established_timings (edid ):
12+ # pylint: disable=redefined-outer-name
13+ # pylint: disable=too-many-branches
1214 """Parse established timings from EDID bytes 35-37"""
1315 modes = []
14-
16+
1517 # Byte 35 (established timings I)
1618 if edid [35 ] & 0x80 :
1719 modes .append ("720x400 @70Hz" )
@@ -29,7 +31,7 @@ def parse_established_timings(edid):
2931 modes .append ("800x600 @56Hz" )
3032 if edid [35 ] & 0x01 :
3133 modes .append ("800x600 @60Hz" )
32-
34+
3335 # Byte 36 (established timings II)
3436 if edid [36 ] & 0x80 :
3537 modes .append ("800x600 @72Hz" )
@@ -47,31 +49,32 @@ def parse_established_timings(edid):
4749 modes .append ("1024x768 @75Hz" )
4850 if edid [36 ] & 0x01 :
4951 modes .append ("1280x1024 @75Hz" )
50-
52+
5153 # Byte 37 (manufacturer timings)
5254 if edid [37 ] & 0x80 :
5355 modes .append ("1152x870 @75Hz" )
54-
56+
5557 return modes
5658
5759def parse_standard_timings (edid ):
60+ # pylint: disable=redefined-outer-name
5861 """Parse standard timings from EDID bytes 38-53"""
5962 modes = []
60-
63+
6164 for i in range (38 , 54 , 2 ): # 8 standard timing descriptors, 2 bytes each
6265 if edid [i ] == 0x01 and edid [i + 1 ] == 0x01 :
6366 continue # Unused timing
64-
67+
6568 if edid [i ] == 0x00 :
6669 continue # Invalid timing
67-
70+
6871 # Calculate horizontal resolution
6972 h_res = (edid [i ] + 31 ) * 8
70-
73+
7174 # Calculate aspect ratio and vertical resolution
7275 aspect_ratio = (edid [i + 1 ] & 0xC0 ) >> 6
7376 refresh_rate = (edid [i + 1 ] & 0x3F ) + 60
74-
77+
7578 if aspect_ratio == 0 : # 16:10
7679 aspect = "16:10"
7780 v_res = (h_res * 10 ) // 16
@@ -84,100 +87,103 @@ def parse_standard_timings(edid):
8487 else : # aspect_ratio == 3, 16:9
8588 aspect = "16:9"
8689 v_res = (h_res * 9 ) // 16
87-
90+
8891 modes .append (f"{ h_res } x{ v_res } @{ refresh_rate } Hz, Aspect: { aspect } " )
89-
92+
9093 return modes
9194
9295def parse_detailed_timings (edid ):
96+ # pylint: disable=redefined-outer-name
9397 # pylint: disable=unused-variable
98+ # pylint: disable=too-many-locals
99+
94100 """Parse detailed timing descriptors from EDID bytes 54-125"""
95101 modes = []
96-
102+
97103 for i in range (54 , 126 , 18 ): # 4 detailed timing descriptors, 18 bytes each
98104 # Check if this is a timing descriptor (pixel clock != 0)
99105 pixel_clock = edid [i ] | (edid [i + 1 ] << 8 )
100106 if pixel_clock == 0 :
101107 continue # Not a timing descriptor
102-
108+
103109 # Parse horizontal resolution
104110 h_active_low = edid [i + 2 ]
105111 h_active_high = (edid [i + 4 ] & 0xF0 ) >> 4
106112 h_active = h_active_low | (h_active_high << 8 )
107-
113+
108114 # Parse vertical resolution
109115 v_active_low = edid [i + 5 ]
110116 v_active_high = (edid [i + 7 ] & 0xF0 ) >> 4
111117 v_active = v_active_low | (v_active_high << 8 )
112-
118+
113119 # Parse horizontal sync
114120 h_sync_offset_low = edid [i + 8 ]
115121 h_sync_width_low = edid [i + 9 ]
116122 h_sync_high = (edid [i + 11 ] & 0xC0 ) >> 6
117123 h_sync_offset = h_sync_offset_low | ((h_sync_high & 0x3 ) << 8 )
118124 h_sync_width = h_sync_width_low | ((h_sync_high & 0xC ) << 6 )
119-
125+
120126 # Parse vertical sync
121127 v_sync_offset_low = (edid [i + 10 ] & 0xF0 ) >> 4
122128 v_sync_width_low = edid [i + 10 ] & 0x0F
123129 v_sync_high = (edid [i + 11 ] & 0x0C ) >> 2
124130 v_sync_offset = v_sync_offset_low | ((v_sync_high & 0x3 ) << 4 )
125131 v_sync_width = v_sync_width_low | ((v_sync_high & 0xC ) << 2 )
126-
132+
127133 # Calculate refresh rate (approximate)
128134 h_blank_low = edid [i + 3 ]
129135 h_blank_high = edid [i + 4 ] & 0x0F
130136 h_blank = h_blank_low | (h_blank_high << 8 )
131137 h_total = h_active + h_blank
132-
138+
133139 v_blank_low = edid [i + 6 ]
134140 v_blank_high = edid [i + 7 ] & 0x0F
135141 v_blank = v_blank_low | (v_blank_high << 8 )
136142 v_total = v_active + v_blank
137-
143+
138144 if h_total > 0 and v_total > 0 :
139145 refresh_rate = (pixel_clock * 10000 ) // (h_total * v_total )
140146 modes .append (f"{ h_active } x{ v_active } @{ refresh_rate } Hz" )
141-
147+
142148 return modes
143149
144150# Main EDID reading code
145- i2c = busio .I2C (board .SCL , board .SDA )
151+ i2c = busio .I2C (board .SCL , board .SDA )
146152if not i2c :
147153 print ("Board doesn't have I2C" )
148154 sys .exit (1 )
149155if not i2c .try_lock ():
150156 print ("Cannot lock I2C" )
151157 sys .exit (1 )
152-
153- print ("\n I2C Present" )
154-
158+
159+ print ("\n I2C Present" )
160+
155161devices = i2c .scan ()
156- if not ( 0x50 in devices ) :
162+ if not 0x50 in devices :
157163 print ("No device found at EDID address 0x50, is the monitor plugged in " +
158164 "& board power cycled?" )
159165 sys .exit (1 )
160-
166+
161167print ("Device 0x50 found!" )
162168device = 0x50
163169edid = bytearray (128 )
164170out = bytearray ([0 ])
165171i2c .writeto_then_readfrom (device , out , edid )
166-
172+ # pylint: disable=too-many-boolean-expressions
167173if edid [0 ] != 0x00 or edid [1 ] != 0xFF or edid [2 ] != 0xFF or \
168174 edid [3 ] != 0xFF or edid [4 ] != 0xFF or edid [5 ] != 0xFF or \
169175 edid [6 ] != 0xFF or edid [7 ] != 0x00 :
170176 print ("EDID signature not recognized" )
171177 sys .exit (1 )
172-
178+
173179print ("Valid EDID signature!" )
174180
175181# Verify checksum
176182checksum = sum (edid ) & 0xFF
177183if checksum != 0 :
178184 print ("Bad EDID checksum detected" )
179185 sys .exit (1 )
180-
186+
181187print ("Good EDID checksum!" )
182188
183189# Parse all supported modes
@@ -187,7 +193,7 @@ def parse_detailed_timings(edid):
187193established_modes = parse_established_timings (edid )
188194supported_modes .extend (established_modes )
189195
190- # Get standard timings
196+ # Get standard timings
191197standard_modes = parse_standard_timings (edid )
192198supported_modes .extend (standard_modes )
193199
0 commit comments