Added protocol stc89a (BSL 7.2.5c) PR#64

This commit is contained in:
Vincent DEFERT 2023-06-01 18:34:44 +02:00
parent f41ae5679f
commit 4894e8f219
3 changed files with 316 additions and 0 deletions

View File

@ -0,0 +1,80 @@
001046: Read (UP): 2021-01-09 15:37:44.9125552 +0.0085328
46 b9 68 00 29 50 fd 84 1e 11 4d 05 8e 96 27 7c F.h.)P....M...'|
^
cpu_6t
04 47 01 7f 40 81 72 43 00 f0 51 05 80 00 ff ff .G..@.rC..Q.....
^ ^ ^ ^
freq_counte | | |
bl_version |
bl_stepping |
bl_minor
ff ff 38 20 20 02 19 60 0d a0 16 ..8 ..`...
001057: Write (DOWN): 2021-01-09 15:37:44.9814096 +0.0129872
46 b9 6a 00 0a 01 ff fd 82 02 f3 16 F.j.........
^
handshake
001072: Read (UP): 2021-01-09 15:37:45.0836096 +0.0115168
46 b9 68 00 07 01 00 70 16 F.h....p.
001113: Write (DOWN): 2021-01-09 15:37:45.1352048 +0.0171904
46 b9 6a 00 0b 05 00 00 46 b9 01 79 16 F.j.....F..y.
^
ping-pong
001116: Read (UP): 2021-01-09 15:37:45.1392768 +0.0017200
46 b9 68 00 07 05 00 74 16 F.h....t.
001127: Write (DOWN): 2021-01-09 15:37:45.1502464 +0.0109472
46 b9 6a 00 0b 03 00 00 46 b9 01 77 16 F.j.....F..w.
^
erase_flash ?
001170: Read (UP): 2021-01-09 15:37:45.4729040 +0.0099696
46 b9 68 00 0e 03 f0 51 c5 f2 06 7c 14 04 07 16 F.h....Q...|....
^
mcu id
001181: Write (DOWN): 2021-01-09 15:37:45.4791856 +0.0062576
46 b9 6a 00 8b 32 00 00 46 b9 02 00 08 12 00 3f F.j..2..F......?
^ ^
write address
write data
80 fe 75 81 07 12 00 4c e5 82 60 03 02 00 03 e4 ..u....L..`.....
78 ff f6 d8 fd 02 00 03 ae 82 af 83 8e 04 8f 05 x...............
1e be ff 01 1f ec 4d 60 0f 7c 90 7d 01 1c bc ff ......M`.|.}....
01 1d ec 4d 70 f7 80 e4 22 90 03 e8 12 00 1e e5 ...Mp...".......
80 f4 f5 80 80 f3 75 82 00 22 ff ff ff ff ff ff ......u.."......
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
ff ff ff ff ff ff ff ff ff ff 52 f9 16 ..........R..
001188: Read (UP): 2021-01-09 15:37:45.5301744 +0.0047088
46 b9 68 00 08 02 54 00 c6 16 F.h...T...
^
write done
001199: Write (DOWN): 2021-01-09 15:37:45.5575264 +0.0273248
46 b9 6a 00 0c 04 00 00 46 b9 fd 02 76 16 F.j.....F...v.
^
write msr
001202: Read (UP): 2021-01-09 15:37:45.5625296 +0.0018304
46 b9 68 00 08 04 54 00 c8 16 F.h...T...
unknown
001213: Write (DOWN): 2021-01-09 15:37:45.5712992 +0.0087472
46 b9 6a 00 07 ff 01 70 16 F.j....p.
unknown

View File

@ -26,6 +26,7 @@ import stcgal
import serial
from stcgal.utils import BaudType
from stcgal.protocols import Stc89Protocol
from stcgal.protocols import Stc89AProtocol
from stcgal.protocols import Stc12AProtocol
from stcgal.protocols import Stc12BProtocol
from stcgal.protocols import Stc12Protocol
@ -52,6 +53,8 @@ class StcGal:
"""Initialize protocol backend"""
if opts.protocol == "stc89":
self.protocol = Stc89Protocol(opts.port, opts.handshake, opts.baud)
elif opts.protocol == "stc89a":
self.protocol = Stc89AProtocol(opts.port, opts.handshake, opts.baud)
elif opts.protocol == "stc12a":
self.protocol = Stc12AProtocol(opts.port, opts.handshake, opts.baud)
elif opts.protocol == "stc12b":

View File

@ -628,6 +628,239 @@ class Stc89Protocol(StcBaseProtocol):
print("done")
class Stc89AProtocol(StcBaseProtocol):
"""Protocol handler for STC 89/90 series"""
PARITY = serial.PARITY_NONE
"""Parity configuration - these don't use any parity"""
PROGRAM_BLOCKSIZE = 128
"""block size for programming flash"""
def __init__(self, port, baud_handshake, baud_transfer):
StcBaseProtocol.__init__(self, port, baud_handshake, baud_transfer)
self.cpu_6t = None
def extract_payload(self, packet):
"""Verify the checksum of packet and return its payload"""
packet_csum = packet[-2] + (packet[-3] << 8)
calc_csum = sum(packet[2:-3]) & 0xffff
if packet_csum != calc_csum:
self.dump_packet(packet)
raise StcFramingException("packet checksum mismatch")
payload = StcBaseProtocol.extract_payload(self, packet)
return payload[:-1]
def write_packet(self, packet_data):
"""Send packet to MCU.
Constructs a packet with supplied payload and sends it to the MCU.
"""
# frame start and direction magic
packet = bytes()
packet += self.PACKET_START
packet += self.PACKET_HOST
# packet length and payload
packet += struct.pack(">H", len(packet_data) + 6)
packet += packet_data
# checksum and end code
packet += struct.pack(">H", sum(packet[2:]) & 0xffff)
packet += self.PACKET_END
self.dump_packet(packet, receive=False)
self.ser.write(packet)
self.ser.flush()
def get_status_packet(self):
"""Read and decode status packet"""
status_packet = self.read_packet()
if status_packet[0] != 0x50:
raise StcProtocolException("incorrect magic in status packet" + str(status_packet[0]))
return status_packet
def initialize_options(self, status_packet):
"""Initialize options"""
if len(status_packet) < 20:
raise StcProtocolException("invalid options in status packet")
self.options = Stc89Option(status_packet[1])
self.options.print()
self.ser.parity = "E"
def calculate_baud(self):
"""Calculate MCU baudrate setting.
Calculate appropriate baudrate settings for the MCU's UART,
according to clock frequency and requested baud rate.
"""
# timing is different in 6T mode
sample_rate = 32 #if self.cpu_6t else 32
# baudrate is directly controlled by programming the MCU's BRT register
brt = 65536 - round((self.mcu_clock_hz) / (self.baud_transfer * sample_rate))
baud_actual = (self.mcu_clock_hz) / (sample_rate * (65536 - brt))
baud_error = (abs(self.baud_transfer - baud_actual) * 100.0) / self.baud_transfer
if baud_error > 5.0:
print("WARNING: baudrate error is %.2f%%. You may need to set a slower rate." %
baud_error, file=sys.stderr)
# IAP wait states (according to datasheet(s))
iap_wait = 0x80
if self.mcu_clock_hz < 10E6: iap_wait = 0x83
elif self.mcu_clock_hz < 30E6: iap_wait = 0x82
elif self.mcu_clock_hz < 50E6: iap_wait = 0x81
# MCU delay after switching baud rates
delay = 0xa0
return brt, iap_wait
def initialize_status(self, status_packet):
"""Decode status packet and store basic MCU info"""
self.cpu_6t = not bool(status_packet[1] & 1)
freq_counter = struct.unpack(">H", status_packet[13:15])[0]
self.mcu_clock_hz = (12 * freq_counter * self.baud_handshake)
bl_version, bl_stepping = struct.unpack("BB", status_packet[17:19])
bl_minor = status_packet[22] & 0x0f
self.mcu_bsl_version = "%d.%d.%d%s" % (bl_version >> 4, bl_version & 0x0f,
bl_minor, chr(bl_stepping))
def handshake(self):
"""Switch to transfer baudrate
Switches to transfer baudrate and verifies that the setting works with
a ping-pong exchange of packets."""
# check new baudrate
print("Switching to %d baud: " % self.baud_transfer, end="")
sys.stdout.flush()
brt,iap = self.calculate_baud()
print("checking ", end="")
sys.stdout.flush()
packet = bytes([0x01])
packet += struct.pack(">H", brt)
packet += bytes([iap])
self.write_packet(packet)
time.sleep(0.2)
print(self.baud_transfer)
response = self.read_packet()
if response[0] != 0x01:
raise StcProtocolException("incorrect magic in handshake packet")
self.ser.baudrate = self.baud_transfer
# ping-pong test
print("testing ", end="")
sys.stdout.flush()
packet = bytes([0x05, 0x00, 0x00, 0x46, 0xB9])
self.write_packet(packet)
response = self.read_packet()
if response[0] != 0x05:
raise StcProtocolException("incorrect magic in handshake packet")
print("done")
def reset_device(self, resetcmd=False):
if not resetcmd:
print("Cycling power: ", end="")
sys.stdout.flush()
self.ser.setDTR(False)
time.sleep(0.5)
self.ser.setDTR(True)
print("done")
else:
print("Cycling power via shell cmd: " + resetcmd)
os.system(resetcmd)
print("Waiting for MCU: ", end="")
sys.stdout.flush()
def erase_flash(self, erase_size, _):
"""Erase the MCU's flash memory.
Erase the flash memory with a block-erase command.
flash_size is ignored; not used on STC 89 series.
"""
print("Erasing All blocks: ", end="")
sys.stdout.flush()
packet = bytes([0x03, 0x00, 0x00, 0x46, 0xB9])
self.write_packet(packet)
response = self.read_packet()
if response[0] != 0x03:
raise StcProtocolException("incorrect magic in erase packet")
print("MCU ID: {:x}{:x}{:x}{:x}{:x}{:x}{:x}".format(response[1],response[2],response[3]
,response[4],response[5],response[6],response[7]))
print("done")
def program_flash(self, data):
"""Program the MCU's flash memory.
Write data into flash memory, using the PROGRAM_BLOCKSIZE
as the block size (depends on MCU's RAM size).
"""
p = 0
for i in range(0, len(data), self.PROGRAM_BLOCKSIZE):
packet = bytes(3)
if p == 0:
packet = bytes([0x22,0x00,0x00])
else:
packet = bytes([0x02])
packet += int(128 * p).to_bytes(length=2, byteorder='big', signed=True)
p = p + 1
packet += bytes([0x46, 0xB9])
packet += data[i:i+self.PROGRAM_BLOCKSIZE]
self.write_packet(packet)
response = self.read_packet()
if len(response) < 1 or response[0] != 0x02:
raise StcProtocolException("incorrect magic in write packet")
self.progress_cb(i, self.PROGRAM_BLOCKSIZE, len(data))
self.progress_cb(len(data), self.PROGRAM_BLOCKSIZE, len(data))
def program_options(self):
"""Program option byte into flash"""
print("Setting options: ")
sys.stdout.flush()
msr = self.options.get_msr()
packet = bytes([0x04,0x00,0x00,0x46,0xB9, msr])
self.write_packet(packet)
response = self.read_packet()
if response[0] != 0x04:
raise StcProtocolException("incorrect magic in option packet")
print("done")
def disconnect(self):
"""Disconnect from MCU"""
# reset mcu
packet = bytes([0xFF])
self.write_packet(packet)
self.ser.close()
print("Disconnected!")
class Stc12AOptionsMixIn:
def program_options(self):
print("Setting options: ", end="")