Newer
Older
#!/usr/bin/env python3
# hn70ap_update_serial.py - Sends an update to the hn70ap board via serial port.
# Copyright (C) 2018 Sebastien Lorquet
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Boston, MA 02110-1301 USA
# This program sends a firmware update image to a hn70ap port via a serial port.
#
# Note that this tool is not a part of NuttX and has a different licence than
# the NuttX RTOS.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
import sys, serial
FDELIM = (0x7E).to_bytes(1, byteorder='big')
FESC = (0x7D).to_bytes(1, byteorder='big')
CRC_INIT = 0xFFFF
CRC_GOOD = 0xF0B8
STATE_NOSYNC = 0
STATE_SYNC = 1
STATE_DATA = 2
STATE_ESC = 3
#-------------------------------------------------------------------------------
def crc16(crc, val):
crc ^= val & 0xFF
crc ^= (crc<<4) & 0xFF
crc = (crc>>8) ^ ((crc&0xFF)<<8) ^ ((crc&0xFF)<<3) ^ ((crc&0xFF)>>4)
return crc
#-------------------------------------------------------------------------------
def frame_send(port, frame):
def write_esc(port,data):
if data == FDELIM or data == FESC:
port.write(FESC)
data ^= 0x20
port.write(data.to_bytes(1, byteorder='big'))
#print('out dat=',frame.hex())
crc = CRC_INIT
port.write(FDELIM)
for i in range(len(frame)):
b = frame[i]
crc = crc16(crc, b)
write_esc(port, b)
crc ^= 0xFFFF;
write_esc(port,crc&0xFF)
write_esc(port,crc>>8)
#print('out crc=',crc.to_bytes(2,byteorder='little').hex())
port.write(FDELIM)
#-------------------------------------------------------------------------------
def frame_receive(port, maxlen):
state = STATE_NOSYNC
packet = bytearray()
crc = CRC_INIT
while True:
ret = port.read(1)
#print("state",state,"char",ret.hex())
b = ret[0]
if state == STATE_NOSYNC:
if ret == FDELIM:
state = STATE_SYNC
else:
print("\x1B[32m", chr(ret[0]), "\x1B[0m", sep='', end='', flush=True)
elif state == STATE_SYNC:
if ret != FDELIM:
packet.append(b)
crc = crc16(crc, b)
state = STATE_DATA
if len(packet) == maxlen:
break
elif state == STATE_DATA:
if ret == FESC:
state = STATE_ESC
elif ret == FDELIM:
break
else:
packet.append(b)
crc = crc16(crc, b)
if len(packet) == maxlen:
break
elif state == STATE_ESC:
b ^= 0x20;
packet.append(b)
crc = crc16(crc, b)
if len(packet) == maxlen:
break
state = STATE_DATA
#check crc
#print("rx crc=%04X"%crc)
if crc != CRC_GOOD:
raise Exception("bad CRC in rx frame")
#done
return packet[0:len(packet)-2]
#-------------------------------------------------------------------------------
if len(sys.argv) != 3:
print("hn70ap_serial_update.py <port> <updateimage>")
sys.exit(1)
up = open(sys.argv[2], 'rb')
port = serial.Serial(port=sys.argv[1], baudrate=230400)
port.write(b"update serial\r\n")
frame_send(port, bytes.fromhex('0A123456'))
print('[', frame_receive(port,2+256).hex(), ']')
port.close()
up.close()