forked from LowPowerLab/WirelessProgramming
-
Notifications
You must be signed in to change notification settings - Fork 0
/
WirelessProgramming.py
169 lines (149 loc) · 5.08 KB
/
WirelessProgramming.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
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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#/*
# * Copyright (c) 2013 by Felix Rusu <[email protected]>
# *
# * This file is free software; you can redistribute it and/or modify
# * it under the terms of either the GNU General Public License version 2
# * or the GNU Lesser General Public License version 2.1, both as
# * published by the Free Software Foundation.
# */
# This script will handle the transmission of a compiled sketch in the
# form of an INTEL HEX flash image to an attached gateway/master Moteino node,
# for further wireless transmission to a target Moteino node that will receive it de-HEXified and
# store it in external memory. Once received by the target (which is also loaded with a custom bootloader
# capable of reading back that image) it will reset and reprogram itself with the new sketch
#
# EXAMPLE USAGE: WirelessProgramming.py -f FILE.hex -m 10 -s COM6 -b 115200
import time, sys, serial
import collections
import re
### GENERAL SETTINGS ###
SERIALPORT = "COM101" # the default com/serial port the receiver is connected to
BAUDRATE = 115200 # default baud rate we talk to Moteino
DEBUG = False
HEX = "flash.hex"
MOTEID = 10
retries = 2
# Read command line arguments
if (sys.argv and len(sys.argv) > 1):
if len(sys.argv)==2 and sys.argv[1] == "-h":
print " -d Turn on debugging"
print " -f {file} HEX file to upload (Default: ", HEX, ")"
print " -m {ID} ID of target Moteino to be programmed (Default: ", MOTEID, ")"
print " -s {port} Serial port (Default: ", SERIALPORT, ")"
print " -b {baud} Baud rate of serial port (Default: ", BAUDRATE, ")"
print " -h Print this message"
exit(0)
for i in range(len(sys.argv)):
if sys.argv[i] == "-d":
DEBUG = True
if sys.argv[i] == "-s" and len(sys.argv) >= i+2:
SERIALPORT = sys.argv[i+1]
if sys.argv[i] == "-b" and len(sys.argv) >= i+2:
BAUD = sys.argv[i+1]
if sys.argv[i] == "-f" and len(sys.argv) >= i+2:
HEX = sys.argv[i+1]
if sys.argv[i] == "-m" and len(sys.argv) >= i+2:
MOTEID = sys.argv[i+1]
if (MOTEID < 1) or (MOTEID > 255):
print "ERROR: Target ID {", MOTEID, "} invalid, must be 1-255."
exit(1)
# open up the FTDI serial port to get data transmitted to Moteino
ser = serial.Serial(SERIALPORT, BAUDRATE, timeout=1) #timeout=0 means nonblocking
time.sleep(2) #wait for Moteino reset after port open and potential bootloader time (~1.6s)
def millis():
return int(round(time.time() * 1000))
def waitForMIDok():
now = millis()
count = 0
while True:
if millis()-now < 5000:
count += 1
ser.flush()
rx = ser.readline().rstrip()
if len(rx) > 0:
print "Moteino: [" + rx + "]"
if rx == "MID?OK":
print "MID HANDSHAKE OK!"
return True
else: return False
def waitForHandshake(isEOF=False):
now = millis()
count = 0
while True:
if millis()-now < 5000:
count += 1
if isEOF:
ser.write("FLX?EOF" + '\n')
else:
ser.write("FLX?" + '\n')
print "FLX?\n"
ser.flush()
rx = ser.readline().rstrip()
if len(rx) > 0:
print "Moteino: [" + rx + "]"
if rx == "FLX?OK":
print "HANDSHAKE OK!"
return True
else: return False
# return 0:timeout, 1:OK!, 2:match but out of synch
def waitForSEQ(seq):
now = millis()
while True:
if millis()-now < 3000:
rx = ser.readline()
if len(rx) > 0:
rx = rx.strip()
print "Moteino: " + rx
result = re.match("FLX:([0-9]*):OK", rx)
if result != None:
if int(result.group(1)) == seq:
return 1
else: return 2
else: return False
# MAIN()
if __name__ == "__main__":
try:
# send ID of target Moteino
ser.flush()
tx = "MID:" + str(MOTEID)
print "TX > " + tx
ser.write(tx + '\n')
if waitForMIDok():
print "MID OK received"
else:
print "No response from gateway Moteino, exiting..."
exit(1)
with open(HEX) as f:
print "File found, passing to Moteino..."
if waitForHandshake():
seq = 0
content = f.readlines()
while seq < len(content):
tx = "FLX:" + str(seq) + content[seq].strip()
isEOF = (content[seq].strip() == ":00000001FF") #this should be the last line in any valid intel HEX file
if isEOF==False:
print "TX > " + tx
ser.write(tx + '\n')
result = waitForSEQ(seq)
elif waitForHandshake(True):
print "SUCCESS!"
exit(0)
if result == 1: seq+=1
elif result == 2: continue # out of synch, retry
else:
if retries > 0:
retries-=1
print "Timeout, retry...\n"
continue
else:
print "TIMEOUT, aborting..."
exit(1)
while 1:
rx = ser.readline()
if (len(rx) > 0): print rx.strip()
else:
print "No response from Moteino, exiting..."
exit(1)
except IOError:
print "File ", HEX, " not found, exiting..."
exit(1)