@@ -137,12 +137,16 @@ def auto_detect_com_port() -> Optional[str]:
137
137
# First, try to find sleeping device and wake it up
138
138
for com_port in com_ports :
139
139
if com_port .serial_number == 'USB7INCH' or com_port .serial_number == 'CT21INCH' :
140
- LcdCommRevC ._connect_to_reset_device_name (com_port )
140
+ LcdCommRevC ._wake_up_device (com_port )
141
141
return LcdCommRevC .auto_detect_com_port ()
142
142
if com_port .vid == 0x1a86 and com_port .pid == 0xca21 :
143
- LcdCommRevC ._connect_to_reset_device_name (com_port )
143
+ LcdCommRevC ._wake_up_device (com_port )
144
144
return LcdCommRevC .auto_detect_com_port ()
145
145
146
+ return LcdCommRevC ._get_awake_com_port (com_ports )
147
+
148
+ @staticmethod
149
+ def _get_awake_com_port (com_ports ) -> Optional [str ]:
146
150
# Then try to find awake device through serial number or vid/pid
147
151
for com_port in com_ports :
148
152
if com_port .serial_number == '20080411' :
@@ -155,14 +159,21 @@ def auto_detect_com_port() -> Optional[str]:
155
159
return None
156
160
157
161
@staticmethod
158
- def _connect_to_reset_device_name (com_port ):
162
+ def _wake_up_device (com_port ):
159
163
# this device enumerates differently when off, we need to connect once to reset it to correct COM device
160
- try :
161
- logger .debug (f"Waiting for device { com_port } to be turned ON..." )
162
- serial .Serial (com_port .device , 115200 , timeout = 1 , rtscts = True )
163
- except serial .SerialException :
164
- pass
165
- time .sleep (10 )
164
+ logger .debug (f"Waiting for device { com_port } to be turned ON..." )
165
+
166
+ for i in range (15 ):
167
+ try :
168
+ # Try to connect every second, since it takes sometimes multiple connect to wake up the device
169
+ serial .Serial (com_port .device , 115200 , timeout = 1 , rtscts = True )
170
+ except serial .SerialException :
171
+ pass
172
+
173
+ if LcdCommRevC ._get_awake_com_port (comports ()) is not None :
174
+ time .sleep (1 )
175
+ return
176
+ time .sleep (1 )
166
177
167
178
def _send_command (self , cmd : Command , payload : Optional [bytearray ] = None , padding : Optional [Padding ] = None ,
168
179
bypass_queue : bool = False , readsize : Optional [int ] = None ):
@@ -199,11 +210,20 @@ def _send_command(self, cmd: Command, payload: Optional[bytearray] = None, paddi
199
210
def _hello (self ):
200
211
# This command reads LCD answer on serial link, so it bypasses the queue
201
212
self .sub_revision = SubRevision .UNKNOWN
213
+ self .serial_flush_input ()
202
214
self ._send_command (Command .HELLO , bypass_queue = True )
203
215
response = '' .join (
204
216
filter (lambda x : x in set (string .printable ), str (self .serial_read (23 ).decode (errors = "ignore" ))))
205
217
self .serial_flush_input ()
206
218
logger .debug ("Display ID returned: %s" % response )
219
+ while not response .startswith ("chs_" ):
220
+ logger .warning ("Display returned invalid or unsupported ID, try again in 1 second" )
221
+ time .sleep (1 )
222
+ self ._send_command (Command .HELLO , bypass_queue = True )
223
+ response = '' .join (
224
+ filter (lambda x : x in set (string .printable ), str (self .serial_read (23 ).decode (errors = "ignore" ))))
225
+ self .serial_flush_input ()
226
+ logger .debug ("Display ID returned: %s" % response )
207
227
208
228
# Note: ID returned by display are not reliable for some models e.g. 2.1" displays return "chs_5inch"
209
229
# Rely on width/height for sub-revision detection
@@ -223,7 +243,7 @@ def _hello(self):
223
243
logger .warning ("ROM version %d may be invalid, use default ROM version 87" % self .rom_version )
224
244
self .rom_version = 87
225
245
except :
226
- logger .warning ("Display returned invalid or unsupported ID on Hello answer , use default ROM version 87" )
246
+ logger .warning ("Display returned invalid or unsupported ID, use default ROM version 87" )
227
247
self .rom_version = 87
228
248
229
249
logger .debug ("HW sub-revision detected: %s, ROM version: %d" % ((str (self .sub_revision )), self .rom_version ))
@@ -236,8 +256,15 @@ def Reset(self):
236
256
# Reset command bypasses queue because it is run when queue threads are not yet started
237
257
self ._send_command (Command .RESTART , bypass_queue = True )
238
258
self .closeSerial ()
239
- # Wait for display reset then reconnect
240
- time .sleep (15 )
259
+ # Wait for disconnection (max. 15 seconds)
260
+ for i in range (15 ):
261
+ if LcdCommRevC ._get_awake_com_port (comports ()) is not None :
262
+ time .sleep (1 )
263
+ # Wait for reconnection (max. 15 seconds)
264
+ for i in range (15 ):
265
+ if LcdCommRevC ._get_awake_com_port (comports ()) is None :
266
+ time .sleep (1 )
267
+ # Reconnect to device
241
268
self .openSerial ()
242
269
243
270
def Clear (self ):
@@ -403,7 +430,7 @@ def _generate_update_image(
403
430
# BGRA mode on 4 bytes : [B, G, R, A]
404
431
img_data , pixel_size = image_to_BGRA (image )
405
432
else :
406
- # BGRA mode on 3 bytes: [6-bit B + 2-bit A, 6-bit G + 2-bit A, R]
433
+ # BGRA mode on 3 bytes: [6-bit B + 2-bit A, 6-bit G + 2-bit A, 8-bit R]
407
434
img_data , pixel_size = image_to_compressed_BGRA (image )
408
435
409
436
for h , line in enumerate (chunked (img_data , image .width * pixel_size )):
0 commit comments