-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
179 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
|
||
install(FILES | ||
README.md | ||
FirmwareUpgradeUtility.py | ||
usc02a_v1.04.pgm | ||
usc03a_v1.03.pgm | ||
usc03b_v1.03.pgm | ||
usc03c_v1.03.pgm | ||
DESTINATION firmwares) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/usr/bin/env python | ||
|
||
import sys | ||
import os | ||
import time | ||
|
||
try: | ||
import serial | ||
except ImportError: | ||
print(f'Pyserial is not installed for {sys.executable}.') | ||
raise | ||
|
||
try: | ||
import serial.tools.list_ports as list_ports | ||
except ImportError: | ||
print(f'The installed version ({sys.VERSION}) of pyserial appears to be too old (Python interpreter {sys.executable}).') | ||
raise | ||
|
||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
def find_maestro_devices(): | ||
devices = [] | ||
for info in list_ports.comports(include_links=False): | ||
port, desc, hwid = info | ||
if 'Pololu' and 'Bootloader' in desc: | ||
devices.append(port) | ||
return sorted(devices) | ||
|
||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
def progress(count, total, status=''): | ||
bar_len = 60 | ||
filled_len = int(round(bar_len * count / float(total))) | ||
|
||
percents = round(100.0 * count / float(total), 1) | ||
bar = '=' * filled_len + ' ' * (bar_len - filled_len) | ||
|
||
sys.stdout.write('[%s] %s%s %s\r' % (bar, percents, '%', status)) | ||
sys.stdout.flush() | ||
|
||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
def flash(firmware, serialPort): | ||
# handshake | ||
text=b'fwbootload' | ||
serialPort.write(text) | ||
answer = serialPort.read(len(text)) | ||
if answer != text.upper(): | ||
sys.exit(f'Expected {text.upper()} got {answer}') | ||
|
||
print('Connected to Maestro bootloader.') | ||
|
||
print('Erasing existing Maestro firmware...') | ||
serialPort.write(b's') | ||
answer = serialPort.read() | ||
|
||
if answer != b'S': | ||
print(f"There was error erasing the old firmware. Expected response 'S' from device but received response {answer}") | ||
raise | ||
|
||
print(f"Uploading new firmware...") | ||
Position=0 | ||
while Position < len(firmware): | ||
serialPort.flush() | ||
serialPort.write(firmware[Position:Position+1000]) | ||
Position+=min(1000, len(firmware) - Position) | ||
progress(Position, len(firmware)) | ||
|
||
time.sleep(0.2) | ||
answer=serialPort.read(serialPort.in_waiting) | ||
|
||
if (len(answer) == 0 or answer[-1] != 124) and serialPort.read() != 124: | ||
print(f"Expected to receive the '|' character, but did not.") | ||
|
||
print(f"\nUpload completed successfully.") | ||
serialPort.write(b'*') | ||
time.sleep(0.2) | ||
|
||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
def main(argv): | ||
print(f'Pololu Maestro firmware upgrade utility\n') | ||
if len(argv) != 2: | ||
sys.exit(f'Usage: {argv[0]} firmware.pgm\n') | ||
|
||
with open(argv[1], mode='rb') as file: | ||
firmware = file.read() | ||
|
||
devices = find_maestro_devices() | ||
|
||
if len(devices) == 0: | ||
sys.exit(f'No Maestro devices in bootloader mode connected.') | ||
if len(devices) > 1: | ||
sys.exit(f'More than one Maestro devices in bootloader mode connected.') | ||
|
||
with serial.Serial(devices[0]) as serialPort: | ||
flash(firmware, serialPort) | ||
|
||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
if __name__ == '__main__': | ||
main(sys.argv) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
#!/usr/bin/env python | ||
|
||
import sys | ||
import os | ||
import time | ||
import serial | ||
import maestro | ||
|
||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
# chose an implementation, depending on os | ||
#~ if sys.platform == 'cli': | ||
#~ else: | ||
if os.name == 'nt': # sys.platform == 'win32': | ||
from serial.tools.list_ports_windows import comports | ||
elif os.name == 'posix': | ||
from serial.tools.list_ports_posix import comports | ||
#~ elif os.name == 'java': | ||
else: | ||
raise ImportError("Sorry: no implementation for your platform ('{}') available".format(os.name)) | ||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
def pololu_devices(): | ||
for info in comports(include_links=False): | ||
port, desc, hwid = info | ||
if 'Pololu' in desc: | ||
yield info | ||
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
|
||
devices = maestro.getConnectedDevices() | ||
|
||
if len(devices) == 0: | ||
sys.exit('No Maestro devices connected') | ||
|
||
print("Pololu Maestro firmware upgrade") | ||
for i,device in enumerate(devices): | ||
print(f"{i}: {device.getName()}") | ||
num = input("Enter device number to upgrade: ") | ||
|
||
if not num.isdigit() or not 0 <= int(num) < len(devices): | ||
sys.exit('wrong input') | ||
|
||
print("Restarting bootloader...") | ||
devices[int(num)].startBootloader() | ||
time.sleep(3) | ||
|
||
devices = pololu_devices() | ||
if len(devices) == 0: | ||
sys.exit('No Maestro devices in bootloader mode detected') | ||
|
||
for i,(port, desc, hwid) in enumerate(devices): | ||
print(f"{i}: {port}") | ||
print(f" desc: {desc}") | ||
print(f" hwid: {hwid}") | ||
|
||
num = input("Enter device number to upgrade: ") | ||
if not num.isdigit() or not 0 <= int(num) < len(devices): | ||
sys.exit('wrong input') | ||
|
||
ser = serial.Serial(devices[int(num)].port) | ||
print(ser.name) # check which port was really used | ||
ser.write(b'fwbootload') # write a string | ||
line = ser.readline() | ||
print(line) | ||
ser.close() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters