From df2fbc23cd2d305fe390b9714d9ec03cc80cca03 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Wed, 6 Jan 2021 19:18:23 +0100 Subject: [PATCH 1/4] stc15: fix baudrate switching Baudrate switching fixes for both HW and SW UART devices: * Program secondary SW UART timing parameter correctly. Supposedly this controls the sampling position when receiving data. * Swap around trim range/adjust parameter for HW UART devices (as determind by older traces) * Use correct constant for timing calculations This should fix some STC15x10xW series MCUs. Compatibility to other devices might be improved as well. Addresses #17. --- stcgal/protocols.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/stcgal/protocols.py b/stcgal/protocols.py index 6ce408a..22a1e77 100644 --- a/stcgal/protocols.py +++ b/stcgal/protocols.py @@ -1394,9 +1394,12 @@ class Stc15Protocol(Stc15AProtocol): # hardware UART. Only one family of models seems to lack a hardware # UART, and we can isolate those with a check on the magic. # This is a bit of a hack, but it works. - bauds = self.baud_transfer if (self.mcu_magic >> 8) == 0xf2 else self.baud_transfer * 4 - packet += struct.pack(">H", int(65535 - program_speed / bauds)) - packet += bytes(user_trim) + if (self.mcu_magic >> 8) == 0xf2: + packet += struct.pack(">H", int(65536 - program_speed / self.baud_transfer)) + packet += struct.pack(">H", int(65536 - program_speed / 2 * 3 / self.baud_transfer)) + else: + packet += struct.pack(">H", int(65536 - program_speed / (self.baud_transfer * 4))) + packet += bytes(reversed(user_trim)) iap_wait = self.get_iap_delay(program_speed) packet += bytes([iap_wait]) self.write_packet(packet) @@ -1413,7 +1416,7 @@ class Stc15Protocol(Stc15AProtocol): sys.stdout.flush() packet = bytes([0x01]) packet += bytes([self.freq_count_24, 0x40]) - packet += struct.pack(">H", int(65535 - self.mcu_clock_hz / self.baud_transfer / 4)) + packet += struct.pack(">H", int(65536 - self.mcu_clock_hz / self.baud_transfer / 4)) iap_wait = self.get_iap_delay(self.mcu_clock_hz) packet += bytes([0x00, 0x00, iap_wait]) self.write_packet(packet) @@ -1664,7 +1667,7 @@ class Stc8Protocol(Stc15Protocol): sys.stdout.flush() packet = bytes([0x01, 0x00, 0x00]) bauds = self.baud_transfer * 4 - packet += struct.pack(">H", round(65535 - 24E6 / bauds)) + packet += struct.pack(">H", round(65536 - 24E6 / bauds)) packet += bytes([user_trim[1], user_trim[0]]) iap_wait = self.get_iap_delay(24E6) packet += bytes([iap_wait]) From 384471f7651a93d70b05e8e37401497dbbfcb1a1 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Wed, 6 Jan 2021 20:08:26 +0100 Subject: [PATCH 2/4] stc15: fix fuzzing test failure --- stcgal/protocols.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/stcgal/protocols.py b/stcgal/protocols.py index 22a1e77..b1437a3 100644 --- a/stcgal/protocols.py +++ b/stcgal/protocols.py @@ -1416,7 +1416,10 @@ class Stc15Protocol(Stc15AProtocol): sys.stdout.flush() packet = bytes([0x01]) packet += bytes([self.freq_count_24, 0x40]) - packet += struct.pack(">H", int(65536 - self.mcu_clock_hz / self.baud_transfer / 4)) + bauds = int(65536 - self.mcu_clock_hz / self.baud_transfer / 4) + if bauds >= 65536: + raise StcProtocolException("baudrate adjustment failed") + packet += struct.pack(">H", bauds) iap_wait = self.get_iap_delay(self.mcu_clock_hz) packet += bytes([0x00, 0x00, iap_wait]) self.write_packet(packet) From 3cf2cb38e7fbb6c9c95a8c6f5382e93d6bcd7c40 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Sat, 9 Jan 2021 01:18:56 +0100 Subject: [PATCH 3/4] stc15: reduce sleep after baudrate switch We just sleep 200 ms, but apparently that's already too much with some handshake baudrates. Cut it in half to fix failures with "-l 9600" in some cases. Addresses #17. --- stcgal/protocols.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/stcgal/protocols.py b/stcgal/protocols.py index b1437a3..382792a 100644 --- a/stcgal/protocols.py +++ b/stcgal/protocols.py @@ -1406,7 +1406,7 @@ class Stc15Protocol(Stc15AProtocol): response = self.read_packet() if len(response) < 1 or response[0] != 0x01: raise StcProtocolException("incorrect magic in handshake packet") - time.sleep(0.2) + time.sleep(0.1) self.ser.baudrate = self.baud_transfer def switch_baud_ext(self): @@ -1426,7 +1426,7 @@ class Stc15Protocol(Stc15AProtocol): response = self.read_packet() if len(response) < 1 or response[0] != 0x01: raise StcProtocolException("incorrect magic in handshake packet") - time.sleep(0.2) + time.sleep(0.1) self.ser.baudrate = self.baud_transfer # for switching back to RC, program factory values From 9202399a846393d2c2001d44d5490aad74e8f307 Mon Sep 17 00:00:00 2001 From: Grigori Goronzy Date: Sat, 9 Jan 2021 01:58:32 +0100 Subject: [PATCH 4/4] Add STC15F104W variant to compatibility list --- doc/MODELS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/MODELS.md b/doc/MODELS.md index 1eeda8b..61c3580 100644 --- a/doc/MODELS.md +++ b/doc/MODELS.md @@ -20,7 +20,7 @@ So far, stcgal was tested with the following MCU models: * STC15F104E (BSL version: 6.7Q) * STC15F204EA (BSL version: 6.7R) * STC15L104W (BSL version: 7.1.4Q) -* STC15F104W (BSL version: 7.1.4Q) +* STC15F104W (BSL version: 7.1.4Q and 7.2.5Q) * IAP15F2K61S2 (BSL version: 7.1.4S) * STC15L2K16S2 (BSL version: 7.2.4S) * IAP15L2K61S2 (BSL version: 7.2.5S)