6
6
#
7
7
import sys
8
8
import board
9
- import busio
9
+ import busio
10
10
11
11
def parse_established_timings (edid ):
12
+ # pylint: disable=redefined-outer-name
13
+ # pylint: disable=too-many-branches
12
14
"""Parse established timings from EDID bytes 35-37"""
13
15
modes = []
14
-
16
+
15
17
# Byte 35 (established timings I)
16
18
if edid [35 ] & 0x80 :
17
19
modes .append ("720x400 @70Hz" )
@@ -29,7 +31,7 @@ def parse_established_timings(edid):
29
31
modes .append ("800x600 @56Hz" )
30
32
if edid [35 ] & 0x01 :
31
33
modes .append ("800x600 @60Hz" )
32
-
34
+
33
35
# Byte 36 (established timings II)
34
36
if edid [36 ] & 0x80 :
35
37
modes .append ("800x600 @72Hz" )
@@ -47,31 +49,32 @@ def parse_established_timings(edid):
47
49
modes .append ("1024x768 @75Hz" )
48
50
if edid [36 ] & 0x01 :
49
51
modes .append ("1280x1024 @75Hz" )
50
-
52
+
51
53
# Byte 37 (manufacturer timings)
52
54
if edid [37 ] & 0x80 :
53
55
modes .append ("1152x870 @75Hz" )
54
-
56
+
55
57
return modes
56
58
57
59
def parse_standard_timings (edid ):
60
+ # pylint: disable=redefined-outer-name
58
61
"""Parse standard timings from EDID bytes 38-53"""
59
62
modes = []
60
-
63
+
61
64
for i in range (38 , 54 , 2 ): # 8 standard timing descriptors, 2 bytes each
62
65
if edid [i ] == 0x01 and edid [i + 1 ] == 0x01 :
63
66
continue # Unused timing
64
-
67
+
65
68
if edid [i ] == 0x00 :
66
69
continue # Invalid timing
67
-
70
+
68
71
# Calculate horizontal resolution
69
72
h_res = (edid [i ] + 31 ) * 8
70
-
73
+
71
74
# Calculate aspect ratio and vertical resolution
72
75
aspect_ratio = (edid [i + 1 ] & 0xC0 ) >> 6
73
76
refresh_rate = (edid [i + 1 ] & 0x3F ) + 60
74
-
77
+
75
78
if aspect_ratio == 0 : # 16:10
76
79
aspect = "16:10"
77
80
v_res = (h_res * 10 ) // 16
@@ -84,100 +87,103 @@ def parse_standard_timings(edid):
84
87
else : # aspect_ratio == 3, 16:9
85
88
aspect = "16:9"
86
89
v_res = (h_res * 9 ) // 16
87
-
90
+
88
91
modes .append (f"{ h_res } x{ v_res } @{ refresh_rate } Hz, Aspect: { aspect } " )
89
-
92
+
90
93
return modes
91
94
92
95
def parse_detailed_timings (edid ):
96
+ # pylint: disable=redefined-outer-name
93
97
# pylint: disable=unused-variable
98
+ # pylint: disable=too-many-locals
99
+
94
100
"""Parse detailed timing descriptors from EDID bytes 54-125"""
95
101
modes = []
96
-
102
+
97
103
for i in range (54 , 126 , 18 ): # 4 detailed timing descriptors, 18 bytes each
98
104
# Check if this is a timing descriptor (pixel clock != 0)
99
105
pixel_clock = edid [i ] | (edid [i + 1 ] << 8 )
100
106
if pixel_clock == 0 :
101
107
continue # Not a timing descriptor
102
-
108
+
103
109
# Parse horizontal resolution
104
110
h_active_low = edid [i + 2 ]
105
111
h_active_high = (edid [i + 4 ] & 0xF0 ) >> 4
106
112
h_active = h_active_low | (h_active_high << 8 )
107
-
113
+
108
114
# Parse vertical resolution
109
115
v_active_low = edid [i + 5 ]
110
116
v_active_high = (edid [i + 7 ] & 0xF0 ) >> 4
111
117
v_active = v_active_low | (v_active_high << 8 )
112
-
118
+
113
119
# Parse horizontal sync
114
120
h_sync_offset_low = edid [i + 8 ]
115
121
h_sync_width_low = edid [i + 9 ]
116
122
h_sync_high = (edid [i + 11 ] & 0xC0 ) >> 6
117
123
h_sync_offset = h_sync_offset_low | ((h_sync_high & 0x3 ) << 8 )
118
124
h_sync_width = h_sync_width_low | ((h_sync_high & 0xC ) << 6 )
119
-
125
+
120
126
# Parse vertical sync
121
127
v_sync_offset_low = (edid [i + 10 ] & 0xF0 ) >> 4
122
128
v_sync_width_low = edid [i + 10 ] & 0x0F
123
129
v_sync_high = (edid [i + 11 ] & 0x0C ) >> 2
124
130
v_sync_offset = v_sync_offset_low | ((v_sync_high & 0x3 ) << 4 )
125
131
v_sync_width = v_sync_width_low | ((v_sync_high & 0xC ) << 2 )
126
-
132
+
127
133
# Calculate refresh rate (approximate)
128
134
h_blank_low = edid [i + 3 ]
129
135
h_blank_high = edid [i + 4 ] & 0x0F
130
136
h_blank = h_blank_low | (h_blank_high << 8 )
131
137
h_total = h_active + h_blank
132
-
138
+
133
139
v_blank_low = edid [i + 6 ]
134
140
v_blank_high = edid [i + 7 ] & 0x0F
135
141
v_blank = v_blank_low | (v_blank_high << 8 )
136
142
v_total = v_active + v_blank
137
-
143
+
138
144
if h_total > 0 and v_total > 0 :
139
145
refresh_rate = (pixel_clock * 10000 ) // (h_total * v_total )
140
146
modes .append (f"{ h_active } x{ v_active } @{ refresh_rate } Hz" )
141
-
147
+
142
148
return modes
143
149
144
150
# Main EDID reading code
145
- i2c = busio .I2C (board .SCL , board .SDA )
151
+ i2c = busio .I2C (board .SCL , board .SDA )
146
152
if not i2c :
147
153
print ("Board doesn't have I2C" )
148
154
sys .exit (1 )
149
155
if not i2c .try_lock ():
150
156
print ("Cannot lock I2C" )
151
157
sys .exit (1 )
152
-
153
- print ("\n I2C Present" )
154
-
158
+
159
+ print ("\n I2C Present" )
160
+
155
161
devices = i2c .scan ()
156
- if not ( 0x50 in devices ) :
162
+ if not 0x50 in devices :
157
163
print ("No device found at EDID address 0x50, is the monitor plugged in " +
158
164
"& board power cycled?" )
159
165
sys .exit (1 )
160
-
166
+
161
167
print ("Device 0x50 found!" )
162
168
device = 0x50
163
169
edid = bytearray (128 )
164
170
out = bytearray ([0 ])
165
171
i2c .writeto_then_readfrom (device , out , edid )
166
-
172
+ # pylint: disable=too-many-boolean-expressions
167
173
if edid [0 ] != 0x00 or edid [1 ] != 0xFF or edid [2 ] != 0xFF or \
168
174
edid [3 ] != 0xFF or edid [4 ] != 0xFF or edid [5 ] != 0xFF or \
169
175
edid [6 ] != 0xFF or edid [7 ] != 0x00 :
170
176
print ("EDID signature not recognized" )
171
177
sys .exit (1 )
172
-
178
+
173
179
print ("Valid EDID signature!" )
174
180
175
181
# Verify checksum
176
182
checksum = sum (edid ) & 0xFF
177
183
if checksum != 0 :
178
184
print ("Bad EDID checksum detected" )
179
185
sys .exit (1 )
180
-
186
+
181
187
print ("Good EDID checksum!" )
182
188
183
189
# Parse all supported modes
@@ -187,7 +193,7 @@ def parse_detailed_timings(edid):
187
193
established_modes = parse_established_timings (edid )
188
194
supported_modes .extend (established_modes )
189
195
190
- # Get standard timings
196
+ # Get standard timings
191
197
standard_modes = parse_standard_timings (edid )
192
198
supported_modes .extend (standard_modes )
193
199
0 commit comments