1 # Copyright (C) Robin Krens - 2024
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 # Commands send to boot firmware
30 # These are combined with send command, for example
31 # STATUS_OK | ERA_CMD == 0x12
32 # STATUS_ERR | ERA_CMD = 0x92
52 # used for init sequence
58 "0xF0", "0xF1", "0xF2", "0xF3",
59 "0xE4", "0xE5", "0xE6", "0xE7",
60 "0xD8", "0xD9", "0xDA", "0xDB",
61 "0xCC", "0xCD", "0xCE", "0xCF"
64 def calc_sum(cmd, data):
66 lnh = data_len + 1 & 0xFF00
67 lnl = data_len + 1 & 0x00FF
69 for i in range(data_len):
70 if isinstance(data[i], str):
71 res += int(data[i], 16)
74 res = ~(res - 1) & 0xFF # two's complement
75 return (lnh, lnl, res)
78 # format of data packet is [SOD|LNH|LNL|COM|byte_data|SUM|ETX]
79 def pack_command(cmd, data):
83 if isinstance(data, str):
84 byte_data = bytes(data.encode('utf-8'))
86 byte_data = bytes([int(x, 16) for x in data])
88 LNH, LNL, SUM = calc_sum(int(cmd), data)
92 fmt = fmt_header + str(len(data)) + 's' + fmt_footer
93 pack = struct.pack(fmt, SOD, LNH, LNL, COM, byte_data, SUM, ETX)
94 print(fmt, pack, len(pack))
97 # format of data packet is [SOD|LNH|LNL|RES|DAT|SUM|ETX]
98 def pack_pkt(res, data):
100 if (len(data) >= 1024):
101 raise Exception(f'Data packet too large, data length is {DATA_LEN} (>1024)')
102 LNH, LNL, SUM = calc_sum(int(res), data)
103 DAT = bytes([int(x, 16) for x in data])
108 fmt = fmt_header + str(len(data)) + 's' + fmt_footer
109 pack = struct.pack(fmt, SOD, LNH, LNL, RES, DAT, SUM, ETX)
112 # packet received from mcu
113 def unpack_pkt(data):
116 SOD, LNH, LNL, RES = struct.unpack(fmt_header, header)
118 raise Exception(f'Wrong start of packet data received')
119 pkt_len = (LNH << 0x8 | LNL) - 1
120 fmt_message = '<' + str(pkt_len) + 's'
121 raw = struct.unpack_from(fmt_message, data, 4)[0]
122 message = ['0x{:02X}'.format(byte) for byte in raw]
124 raise ValueError(f'MCU encountered error {message[0]}')
126 SUM, ETX = struct.unpack_from(fmt_footer, data, 4 + pkt_len)
127 lnh, lnl, local_sum = calc_sum(RES, message)
128 if (SUM != local_sum):
129 raise Exception(f'Sum calculation mismatch, read {local_sum} instead of {SUM}')
131 raise Exception(f'Packet ETX error')
135 cmd = pack_command(INQ_CMD, "")
136 cmd = pack_command(BAU_CMD, ['0x00','0x1E'])
137 cmd = pack_command(IDA_CMD, TESTID)