-
Notifications
You must be signed in to change notification settings - Fork 0
/
uploader.py
77 lines (68 loc) · 2.4 KB
/
uploader.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
com_port = 'COM4'
baud_rate = 115200
# baud_rate = 9600
hardware_has_rts_reset = False
do_lua_file_after_upload = False
save_lua = \
r"""file.remove('%s')
file.open('%s', 'w')
uart.on('data', 255,
function (d)
c = tonumber(d:sub(1, 4))
d = d:sub(5, 4+c)
file.write(d)
if c ~= 251 then
uart.on('data')
file.close()
end
uart.write(0, '\r')
end, 0)"""
save_lua = ' '.join([line.strip() for line in save_lua.split('\n')]).replace(', ', ',')
import os, serial, sys
prompt = '\n> '
def read_till_prompt(do_log=False):
data = ''
while data[-3:] != prompt:
d = ser.read()
if do_log:
sys.stdout.write(d)
if d == '':
sys.stdout.write('.')
data += d
return data
ser = serial.Serial(com_port, baud_rate, timeout=1)
# Opening the serial port changes DTR and RTS to 0.
if hardware_has_rts_reset:
sys.stdout.write('Reset... ')
ser.setDTR(False) # Setting them to False sets their logic level back to 1.
ser.setRTS(False)
read_till_prompt() # Wait until Lua has booted after the reset caused by RTS.
# This waits forever in case RTS is not connected to RESET.
sys.stdout.write('done.\n')
else:
sys.stdout.write('If nothing happens, try setting hardware_has_rts_reset = True\n')
file_path = sys.argv[1]
file_name = os.path.basename(file_path)
save_command = save_lua % (file_name, file_name) + '\r'
assert len(save_command) < 256, 'save_command too long: %s bytes' % len(save_command)
ser.write(save_command)
response = read_till_prompt()
assert response == save_command + prompt, response
f = open( file_path, 'rb' ); content = f.read(); f.close()
pos = 0
chunk_size = 251 # 255 (maximum) - 4 (hex_count)
while pos <= len(content):
data = content[pos : pos + chunk_size]
pos += chunk_size
count = len(data)
if count != chunk_size:
data += ' ' * (chunk_size - count) # Fill up to get a full chunk to send.
hex_count = '0x' + hex(count)[2:].zfill(2) # Tell the receiver the real count.
ser.write(hex_count + data)
assert ser.read(1) == '\r'
percent = int(100 * pos / ((len(content) + chunk_size) / chunk_size * chunk_size))
sys.stdout.write('%3s %%\n' % percent)
if do_lua_file_after_upload and file_name.endswith('.lua'):
ser.write('dofile("%s")\r' % file_name)
read_till_prompt(do_log=True)
ser.close()