-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserial-test.py
239 lines (174 loc) · 6.9 KB
/
serial-test.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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
import serial
import time
#
# ----------------------------------------------------------------------
#
# - SECTION - references
#
# (1) https://www.tutorialspoint.com/increment-and-decrement-operators-in-python
#
# (2) https://www.geeksforgeeks.org/print-without-newline-python/
#
# (3) https://www.askpython.com/python-modules/python-time-sleep-method
#
# (4) https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.write
#
# (5) https://gist.github.com/yptheangel/fcd62ad59a569ace75eb07025b8e9c4f . . . serialPort.write(bytes.fromhex("a5"))
#
# (6) https://jimmywongiot.com/2021/03/13/byte-manipulation-on-python-platform/
#
# Note STM32WL55 flash memory start mapped to 0x08000000, per document:
# (7) rm0453-stm32wl5x-advanced-armbased-32bit-mcus-with-subghz-radio-solution-stmicroelectronics.pdf
#
# ----------------------------------------------------------------------
#
# alternate baudrates tested: 115200 - b'\xff' responses
# 9600 - no response at either delay 1uS, 100uS
# 38400 - no response at 1uS
#
serialPort = serial.Serial(port = "/dev/ttyUSB0",
baudrate=115200,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_EVEN,
stopbits=serial.STOPBITS_ONE,
timeout=0,
write_timeout=2.0)
serialString = "" # Used to hold data coming over UART
latest_byte = 'a'
bootloader_handshake_attempts = 0 # bound loop iterations to finite value
HANDSHAKE_ATTEMPTS_TO_MAKE = 4 # . . . was 20
#tries = 0
command_to_bootloader = 0
command_get_attempts = 0
COMMAND_GET_ATTEMPTS_TO_MAKE = 2
ONE_NANOSECOND = 0.000000001
ONE_MICROSECOND = 0.000001
TEN_MICROSECONDS = 0.00001
ONE_HUNDRED_MICROSECONDS = 0.0001
#CHOSEN_DELAY = ONE_HUNDRED_MICROSECONDS
#CHOSEN_DELAY = TEN_MICROSECONDS
CHOSEN_DELAY = ONE_NANOSECOND
# ----------------------------------------------------------------------
# - SECTION - routines
# ----------------------------------------------------------------------
# Example code from reference (6) jimmywongiot.com:
# def serial_command(cmd):
# serial_cmd = cmd + '\r'
# return bytes(serial_cmd.encode())
##
## @brief: this routine expects
##
## * an array of bytes
## * an integer value
##
## @note We would consider taking commands as single quoted strings,
## however STMicro ROM based bootloader command set entails values
## outside the traditional ASCII range.
##
def send_bootloader_cmd(command_as_bytes, send_count):
command_get_attempts = 0
serialPort.write(bytes.fromhex("7f"))
time.sleep(0.00001)
print("sending", end=" ")
print(command_as_bytes, end=" ")
print("to bootloader . . .")
while ( command_get_attempts < send_count ):
command_get_attempts += 1
time.sleep(CHOSEN_DELAY)
serialPort.write(command_as_bytes)
while ( serialPort.in_waiting == 0 ):
time.sleep(CHOSEN_DELAY)
while ( serialPort.in_waiting > 0 ):
serialString = serialPort.read()
print(serialString)
print("")
time.sleep(0.00001)
# return serialString
def command_with_xor(command):
cmd = [0, 0]
cmd[0] = command
cmd[1] = (command ^ 0xFF)
return bytes(cmd)
def send_address_of_memory(address):
command_get_attempts = 0
serialPort.write(bytes.fromhex("7f"))
time.sleep(0.00001)
print("sending memory address 0x", end="")
print(address, end=" ")
print(". . .")
# while ( command_get_attempts < send_count ):
# command_get_attempts += 1
time.sleep(CHOSEN_DELAY)
serialPort.write(address)
while ( serialPort.in_waiting == 0 ):
time.sleep(CHOSEN_DELAY)
while ( serialPort.in_waiting > 0 ):
serialString = serialPort.read()
print(serialString)
print("")
time.sleep(0.00001)
def memory_address_with_crc(address):
bytes_for_address = [0, 0, 0, 0, 0]
bytes_for_address[0] = (( address >> 24 ) & 0xff )
bytes_for_address[1] = (( address >> 16 ) & 0xff )
bytes_for_address[2] = (( address >> 8 ) & 0xff )
bytes_for_address[3] = (( address >> 0 ) & 0xff )
bytes_for_address[4] = (bytes_for_address[0] ^ bytes_for_address[1] ^ bytes_for_address[2] ^ bytes_for_address[3]) & 0xff
return bytes_for_address
# ----------------------------------------------------------------------
# - SECTION - main line code
# ----------------------------------------------------------------------
## STMicro ROM based bootloader expects an initial byte holding 0x7F
## as a sign to commence firmware updating over a serial protocol:
print("Script starting,")
print("At loop to attempt bootloader handshake several times:")
while ( bootloader_handshake_attempts < HANDSHAKE_ATTEMPTS_TO_MAKE ):
bootloader_handshake_attempts += 1
time.sleep(CHOSEN_DELAY)
serialPort.write(bytes.fromhex("7f"))
while ( serialPort.in_waiting == 0 ):
time.sleep(CHOSEN_DELAY)
serialString = serialPort.readline()
print(serialString)
bootloader_handshake_attempts = 0
BOOTLOADER_COMMAND__GET = 0x00
BOOTLOADER_COMMAND__GET_VERSION = 0x01
BOOTLOADER_COMMAND__GET_ID = 0x02
BOOTLOADER_COMMAND__READ = 0x11
BOOTLOADER_COMMAND__GO = 0x21
## def send_bootloader_cmd(command_as_bytes, send_count):
send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__GET_VERSION), 1)
if (0):
send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__GET), 1)
#latest_byte = send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__GET_ID), 1)
#print("latest byte received is ", end=" ")
#print(latest_byte)
#latest_byte = send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__GET_ID), 1)
#print("latest byte received is ", end=" ")
#print(latest_byte)
if (0):
send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__GET_ID), 1)
#latest_byte = send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__READ), 1)
#print("latest byte received is ", end=" ")
#print(latest_byte)
#latest_byte = send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__READ), 1)
#print("latest byte received is ", end=" ")
#print(latest_byte)
if (1):
print("sending read command . . .")
send_bootloader_cmd(command_with_xor(BOOTLOADER_COMMAND__READ), 1)
address_with_checksum = memory_address_with_crc(0x08000000)
print("sending address to start of flash . . .")
send_address_of_memory(address_with_checksum)
#print("At original loop designed to read serial port received bytes:")
#while(1):
#
# # Wait until there is data waiting in the serial buffer
# if(serialPort.in_waiting > 0):
#
# # Read data out of the buffer until a carraige return / new line is found
# serialString = serialPort.readline()
#
# # Print the contents of the serial data
# print(serialString)
print("script done.")