🧑‍💻 Use spaces indent for Python

This commit is contained in:
Scott Lahteine 2022-10-12 17:52:56 -05:00
parent 5eb39d5277
commit 51c1645ceb
7 changed files with 477 additions and 477 deletions

View File

@ -6,14 +6,14 @@
# #
import pioutil import pioutil
if pioutil.is_pio_build(): if pioutil.is_pio_build():
import platform import platform
current_OS = platform.system() current_OS = platform.system()
if current_OS == 'Windows': if current_OS == 'Windows':
Import("env") Import("env")
# Use bossac.exe on Windows # Use bossac.exe on Windows
env.Replace( env.Replace(
UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE" UPLOADCMD="bossac --info --unlock --write --verify --reset --erase -U false --boot $SOURCE"
) )

View File

@ -4,16 +4,16 @@
import pioutil import pioutil
if pioutil.is_pio_build(): if pioutil.is_pio_build():
Import("env", "projenv") Import("env", "projenv")
flash_size = 0 flash_size = 0
vect_tab_addr = 0 vect_tab_addr = 0
for define in env['CPPDEFINES']: for define in env['CPPDEFINES']:
if define[0] == "VECT_TAB_ADDR": if define[0] == "VECT_TAB_ADDR":
vect_tab_addr = define[1] vect_tab_addr = define[1]
if define[0] == "STM32_FLASH_SIZE": if define[0] == "STM32_FLASH_SIZE":
flash_size = define[1] flash_size = define[1]
print('Use the {0:s} address as the marlin app entry point.'.format(vect_tab_addr)) print('Use the {0:s} address as the marlin app entry point.'.format(vect_tab_addr))
print('Use the {0:d}KB flash version of stm32f103rct6 chip.'.format(flash_size)) print('Use the {0:d}KB flash version of stm32f103rct6 chip.'.format(flash_size))

View File

@ -3,25 +3,25 @@
# #
import pioutil import pioutil
if pioutil.is_pio_build(): if pioutil.is_pio_build():
from os.path import join from os.path import join
from os.path import expandvars from os.path import expandvars
Import("env") Import("env")
# Custom HEX from ELF # Custom HEX from ELF
env.AddPostAction( env.AddPostAction(
join("$BUILD_DIR", "${PROGNAME}.elf"), join("$BUILD_DIR", "${PROGNAME}.elf"),
env.VerboseAction(" ".join([ env.VerboseAction(" ".join([
"$OBJCOPY", "-O ihex", "$TARGET", "$OBJCOPY", "-O ihex", "$TARGET",
"\"" + join("$BUILD_DIR", "${PROGNAME}.hex") + "\"", # Note: $BUILD_DIR is a full path "\"" + join("$BUILD_DIR", "${PROGNAME}.hex") + "\"", # Note: $BUILD_DIR is a full path
]), "Building $TARGET")) ]), "Building $TARGET"))
# In-line command with arguments # In-line command with arguments
UPLOAD_TOOL="stm32flash" UPLOAD_TOOL="stm32flash"
platform = env.PioPlatform() platform = env.PioPlatform()
if platform.get_package_dir("tool-stm32duino") != None: if platform.get_package_dir("tool-stm32duino") != None:
UPLOAD_TOOL=expandvars("\"" + join(platform.get_package_dir("tool-stm32duino"),"stm32flash","stm32flash") + "\"") UPLOAD_TOOL=expandvars("\"" + join(platform.get_package_dir("tool-stm32duino"),"stm32flash","stm32flash") + "\"")
env.Replace( env.Replace(
UPLOADER=UPLOAD_TOOL, UPLOADER=UPLOAD_TOOL,
UPLOADCMD=expandvars(UPLOAD_TOOL + " -v -i rts,-dtr,dtr -R -b 115200 -g 0x8000000 -w \"" + join("$BUILD_DIR","${PROGNAME}.hex")+"\"" + " $UPLOAD_PORT") UPLOADCMD=expandvars(UPLOAD_TOOL + " -v -i rts,-dtr,dtr -R -b 115200 -g 0x8000000 -w \"" + join("$BUILD_DIR","${PROGNAME}.hex")+"\"" + " $UPLOAD_PORT")
) )

View File

@ -3,29 +3,29 @@
# #
import pioutil import pioutil
if pioutil.is_pio_build(): if pioutil.is_pio_build():
import shutil,marlin import shutil,marlin
from pathlib import Path from pathlib import Path
Import("env") Import("env")
platform = env.PioPlatform() platform = env.PioPlatform()
board = env.BoardConfig() board = env.BoardConfig()
FRAMEWORK_DIR = Path(platform.get_package_dir("framework-arduinoststm32-maple")) FRAMEWORK_DIR = Path(platform.get_package_dir("framework-arduinoststm32-maple"))
assert FRAMEWORK_DIR.is_dir() assert FRAMEWORK_DIR.is_dir()
source_root = Path("buildroot/share/PlatformIO/variants") source_root = Path("buildroot/share/PlatformIO/variants")
assert source_root.is_dir() assert source_root.is_dir()
variant = board.get("build.variant") variant = board.get("build.variant")
variant_dir = FRAMEWORK_DIR / "STM32F1/variants" / variant variant_dir = FRAMEWORK_DIR / "STM32F1/variants" / variant
source_dir = source_root / variant source_dir = source_root / variant
assert source_dir.is_dir() assert source_dir.is_dir()
if variant_dir.is_dir(): if variant_dir.is_dir():
shutil.rmtree(variant_dir) shutil.rmtree(variant_dir)
if not variant_dir.is_dir(): if not variant_dir.is_dir():
variant_dir.mkdir() variant_dir.mkdir()
marlin.copytree(source_dir, variant_dir) marlin.copytree(source_dir, variant_dir)

View File

@ -47,150 +47,150 @@ different_out_dir = not (output_examples_dir == input_examples_dir)
#---------------------------------------------- #----------------------------------------------
def process_file(subdir: str, filename: str): def process_file(subdir: str, filename: str):
#---------------------------------------------- #----------------------------------------------
global filenum global filenum
filenum += 1 filenum += 1
print(str(filenum) + ' ' + filename + ': ' + subdir) print(str(filenum) + ' ' + filename + ': ' + subdir)
def_line = (def_macro_name + ' "' + subdir.replace('\\', '/') + '"') def_line = (def_macro_name + ' "' + subdir.replace('\\', '/') + '"')
#------------------------ #------------------------
# Read file # Read file
#------------------------ #------------------------
lines = [] lines = []
infilepath = Path(input_examples_dir, subdir, filename) infilepath = Path(input_examples_dir, subdir, filename)
try: try:
# UTF-8 because some files contain unicode chars # UTF-8 because some files contain unicode chars
with infilepath.open('rt', encoding="utf-8") as infile: with infilepath.open('rt', encoding="utf-8") as infile:
lines = infile.readlines() lines = infile.readlines()
except Exception as e: except Exception as e:
print('Failed to read file: ' + str(e) ) print('Failed to read file: ' + str(e) )
raise Exception raise Exception
lines = [line.rstrip('\r\n') for line in lines] lines = [line.rstrip('\r\n') for line in lines]
#------------------------ #------------------------
# Process lines # Process lines
#------------------------ #------------------------
file_modified = False file_modified = False
# region state machine # region state machine
# -1 = before pragma once; # -1 = before pragma once;
# 0 = region to place define; # 0 = region to place define;
# 1 = past region to place define # 1 = past region to place define
region = -1 region = -1
outlines = [] outlines = []
for line in lines: for line in lines:
outline = line outline = line
if (region == -1) and (def_macro_name in line): if (region == -1) and (def_macro_name in line):
outline = None outline = None
file_modified = True file_modified = True
elif (region == -1) and ('pragma once' in line): elif (region == -1) and ('pragma once' in line):
region = 0 region = 0
elif (region == 0): elif (region == 0):
if (line.strip() == ''): if (line.strip() == ''):
pass pass
elif (def_macro_name in line): elif (def_macro_name in line):
region = 1 region = 1
if line == def_line: # leave it as is if line == def_line: # leave it as is
pass pass
else: else:
outline = def_line outline = def_line
file_modified = True file_modified = True
else: # some other string else: # some other string
outlines.append(def_line) outlines.append(def_line)
outlines.append('') outlines.append('')
region = 1 region = 1
file_modified = True file_modified = True
elif (region == 1): elif (region == 1):
if (def_macro_name in line): if (def_macro_name in line):
outline = None outline = None
file_modified = True file_modified = True
else: else:
pass pass
# end if # end if
if outline is not None: if outline is not None:
outlines.append(outline) outlines.append(outline)
# end for # end for
#------------------------- #-------------------------
# Output file # Output file
#------------------------- #-------------------------
outdir = Path(output_examples_dir, subdir) outdir = Path(output_examples_dir, subdir)
outfilepath = outdir / filename outfilepath = outdir / filename
if file_modified: if file_modified:
# Note: no need to create output dirs, as the initial copy_tree # Note: no need to create output dirs, as the initial copy_tree
# will do that. # will do that.
print(' writing ' + str(outfilepath)) print(' writing ' + str(outfilepath))
try: try:
# Preserve unicode chars; Avoid CR-LF on Windows. # Preserve unicode chars; Avoid CR-LF on Windows.
with outfilepath.open("w", encoding="utf-8", newline='\n') as outfile: with outfilepath.open("w", encoding="utf-8", newline='\n') as outfile:
outfile.write("\n".join(outlines) + "\n") outfile.write("\n".join(outlines) + "\n")
except Exception as e: except Exception as e:
print('Failed to write file: ' + str(e) ) print('Failed to write file: ' + str(e) )
raise Exception raise Exception
else: else:
print(' no change for ' + str(outfilepath)) print(' no change for ' + str(outfilepath))
#---------- #----------
def main(): def main():
#---------- #----------
global filenum global filenum
global input_examples_dir global input_examples_dir
global output_examples_dir global output_examples_dir
filenum = 0 filenum = 0
#-------------------------------- #--------------------------------
# Check for requirements # Check for requirements
#-------------------------------- #--------------------------------
input_examples_dir = input_examples_dir.strip() input_examples_dir = input_examples_dir.strip()
input_examples_dir = input_examples_dir.rstrip('\\/') input_examples_dir = input_examples_dir.rstrip('\\/')
output_examples_dir = output_examples_dir.strip() output_examples_dir = output_examples_dir.strip()
output_examples_dir = output_examples_dir.rstrip('\\/') output_examples_dir = output_examples_dir.rstrip('\\/')
for dir in (input_examples_dir, output_examples_dir): for dir in (input_examples_dir, output_examples_dir):
if not Path(dir).exists(): if not Path(dir).exists():
print('Directory not found: ' + dir) print('Directory not found: ' + dir)
sys.exit(1) sys.exit(1)
#-------------------------------- #--------------------------------
# Copy tree if necessary. # Copy tree if necessary.
#-------------------------------- #--------------------------------
# This includes files that are not otherwise included in the # This includes files that are not otherwise included in the
# insertion of the define statement. # insertion of the define statement.
# #
if different_out_dir: if different_out_dir:
print('Copying files to new directory: ' + output_examples_dir) print('Copying files to new directory: ' + output_examples_dir)
try: try:
copy_tree(input_examples_dir, output_examples_dir) copy_tree(input_examples_dir, output_examples_dir)
except Exception as e: except Exception as e:
print('Failed to copy directory: ' + str(e) ) print('Failed to copy directory: ' + str(e) )
raise Exception raise Exception
#----------------------------- #-----------------------------
# Find and process files # Find and process files
#----------------------------- #-----------------------------
len_input_examples_dir = 1 + len(input_examples_dir) len_input_examples_dir = 1 + len(input_examples_dir)
for filename in files_to_mod: for filename in files_to_mod:
input_path = Path(input_examples_dir) input_path = Path(input_examples_dir)
filepathlist = input_path.rglob(filename) filepathlist = input_path.rglob(filename)
for filepath in filepathlist: for filepath in filepathlist:
fulldirpath = str(filepath.parent) fulldirpath = str(filepath.parent)
subdir = fulldirpath[len_input_examples_dir:] subdir = fulldirpath[len_input_examples_dir:]
process_file(subdir, filename) process_file(subdir, filename)
#============== #==============
print('--- Starting config-labels ---') print('--- Starting config-labels ---')

View File

@ -26,38 +26,38 @@ import sys,struct
from PIL import Image from PIL import Image
def image2bin(image, output_file): def image2bin(image, output_file):
if output_file.endswith(('.c', '.cpp')): if output_file.endswith(('.c', '.cpp')):
f = open(output_file, 'wt') f = open(output_file, 'wt')
is_cpp = True is_cpp = True
f.write("const uint16_t image[%d] = {\n" % (image.size[1] * image.size[0])) f.write("const uint16_t image[%d] = {\n" % (image.size[1] * image.size[0]))
else: else:
f = open(output_file, 'wb') f = open(output_file, 'wb')
is_cpp = False is_cpp = False
pixs = image.load() pixs = image.load()
for y in range(image.size[1]): for y in range(image.size[1]):
for x in range(image.size[0]): for x in range(image.size[0]):
R = pixs[x, y][0] >> 3 R = pixs[x, y][0] >> 3
G = pixs[x, y][1] >> 2 G = pixs[x, y][1] >> 2
B = pixs[x, y][2] >> 3 B = pixs[x, y][2] >> 3
rgb = (R << 11) | (G << 5) | B rgb = (R << 11) | (G << 5) | B
if is_cpp: if is_cpp:
strHex = '0x{0:04X}, '.format(rgb) strHex = '0x{0:04X}, '.format(rgb)
f.write(strHex) f.write(strHex)
else: else:
f.write(struct.pack("B", (rgb & 0xFF))) f.write(struct.pack("B", (rgb & 0xFF)))
f.write(struct.pack("B", (rgb >> 8) & 0xFF)) f.write(struct.pack("B", (rgb >> 8) & 0xFF))
if is_cpp: if is_cpp:
f.write("\n") f.write("\n")
if is_cpp: if is_cpp:
f.write("};\n") f.write("};\n")
f.close() f.close()
if len(sys.argv) <= 2: if len(sys.argv) <= 2:
print("Utility to export a image in Marlin TFT friendly format.") print("Utility to export a image in Marlin TFT friendly format.")
print("It will dump a raw bin RGB565 image or create a CPP file with an array of 16 bit image pixels.") print("It will dump a raw bin RGB565 image or create a CPP file with an array of 16 bit image pixels.")
print("Usage: gen-tft-image.py INPUT_IMAGE.(png|bmp|jpg) OUTPUT_FILE.(cpp|bin)") print("Usage: gen-tft-image.py INPUT_IMAGE.(png|bmp|jpg) OUTPUT_FILE.(cpp|bin)")
print("Author: rhapsodyv") print("Author: rhapsodyv")
exit(1) exit(1)
output_img = sys.argv[2] output_img = sys.argv[2]
img = Image.open(sys.argv[1]) img = Image.open(sys.argv[1])

View File

@ -25,320 +25,320 @@ import MarlinBinaryProtocol
#-----------------# #-----------------#
def Upload(source, target, env): def Upload(source, target, env):
#-------# #-------#
# Debug # # Debug #
#-------# #-------#
Debug = False # Set to True to enable script debug Debug = False # Set to True to enable script debug
def debugPrint(data): def debugPrint(data):
if Debug: print(f"[Debug]: {data}") if Debug: print(f"[Debug]: {data}")
#------------------# #------------------#
# Marlin functions # # Marlin functions #
#------------------# #------------------#
def _GetMarlinEnv(marlinEnv, feature): def _GetMarlinEnv(marlinEnv, feature):
if not marlinEnv: return None if not marlinEnv: return None
return marlinEnv[feature] if feature in marlinEnv else None return marlinEnv[feature] if feature in marlinEnv else None
#----------------# #----------------#
# Port functions # # Port functions #
#----------------# #----------------#
def _GetUploadPort(env): def _GetUploadPort(env):
debugPrint('Autodetecting upload port...') debugPrint('Autodetecting upload port...')
env.AutodetectUploadPort(env) env.AutodetectUploadPort(env)
portName = env.subst('$UPLOAD_PORT') portName = env.subst('$UPLOAD_PORT')
if not portName: if not portName:
raise Exception('Error detecting the upload port.') raise Exception('Error detecting the upload port.')
debugPrint('OK') debugPrint('OK')
return portName return portName
#-------------------------# #-------------------------#
# Simple serial functions # # Simple serial functions #
#-------------------------# #-------------------------#
def _OpenPort(): def _OpenPort():
# Open serial port # Open serial port
if port.is_open: return if port.is_open: return
debugPrint('Opening upload port...') debugPrint('Opening upload port...')
port.open() port.open()
port.reset_input_buffer() port.reset_input_buffer()
debugPrint('OK') debugPrint('OK')
def _ClosePort(): def _ClosePort():
# Open serial port # Open serial port
if port is None: return if port is None: return
if not port.is_open: return if not port.is_open: return
debugPrint('Closing upload port...') debugPrint('Closing upload port...')
port.close() port.close()
debugPrint('OK') debugPrint('OK')
def _Send(data): def _Send(data):
debugPrint(f'>> {data}') debugPrint(f'>> {data}')
strdata = bytearray(data, 'utf8') + b'\n' strdata = bytearray(data, 'utf8') + b'\n'
port.write(strdata) port.write(strdata)
time.sleep(0.010) time.sleep(0.010)
def _Recv(): def _Recv():
clean_responses = [] clean_responses = []
responses = port.readlines() responses = port.readlines()
for Resp in responses: for Resp in responses:
# Suppress invalid chars (coming from debug info) # Suppress invalid chars (coming from debug info)
try: try:
clean_response = Resp.decode('utf8').rstrip().lstrip() clean_response = Resp.decode('utf8').rstrip().lstrip()
clean_responses.append(clean_response) clean_responses.append(clean_response)
debugPrint(f'<< {clean_response}') debugPrint(f'<< {clean_response}')
except: except:
pass pass
return clean_responses return clean_responses
#------------------# #------------------#
# SDCard functions # # SDCard functions #
#------------------# #------------------#
def _CheckSDCard(): def _CheckSDCard():
debugPrint('Checking SD card...') debugPrint('Checking SD card...')
_Send('M21') _Send('M21')
Responses = _Recv() Responses = _Recv()
if len(Responses) < 1 or not any('SD card ok' in r for r in Responses): if len(Responses) < 1 or not any('SD card ok' in r for r in Responses):
raise Exception('Error accessing SD card') raise Exception('Error accessing SD card')
debugPrint('SD Card OK') debugPrint('SD Card OK')
return True return True
#----------------# #----------------#
# File functions # # File functions #
#----------------# #----------------#
def _GetFirmwareFiles(UseLongFilenames): def _GetFirmwareFiles(UseLongFilenames):
debugPrint('Get firmware files...') debugPrint('Get firmware files...')
_Send(f"M20 F{'L' if UseLongFilenames else ''}") _Send(f"M20 F{'L' if UseLongFilenames else ''}")
Responses = _Recv() Responses = _Recv()
if len(Responses) < 3 or not any('file list' in r for r in Responses): if len(Responses) < 3 or not any('file list' in r for r in Responses):
raise Exception('Error getting firmware files') raise Exception('Error getting firmware files')
debugPrint('OK') debugPrint('OK')
return Responses return Responses
def _FilterFirmwareFiles(FirmwareList, UseLongFilenames): def _FilterFirmwareFiles(FirmwareList, UseLongFilenames):
Firmwares = [] Firmwares = []
for FWFile in FirmwareList: for FWFile in FirmwareList:
# For long filenames take the 3rd column of the firmwares list # For long filenames take the 3rd column of the firmwares list
if UseLongFilenames: if UseLongFilenames:
Space = 0 Space = 0
Space = FWFile.find(' ') Space = FWFile.find(' ')
if Space >= 0: Space = FWFile.find(' ', Space + 1) if Space >= 0: Space = FWFile.find(' ', Space + 1)
if Space >= 0: FWFile = FWFile[Space + 1:] if Space >= 0: FWFile = FWFile[Space + 1:]
if not '/' in FWFile and '.BIN' in FWFile.upper(): if not '/' in FWFile and '.BIN' in FWFile.upper():
Firmwares.append(FWFile[:FWFile.upper().index('.BIN') + 4]) Firmwares.append(FWFile[:FWFile.upper().index('.BIN') + 4])
return Firmwares return Firmwares
def _RemoveFirmwareFile(FirmwareFile): def _RemoveFirmwareFile(FirmwareFile):
_Send(f'M30 /{FirmwareFile}') _Send(f'M30 /{FirmwareFile}')
Responses = _Recv() Responses = _Recv()
Removed = len(Responses) >= 1 and any('File deleted' in r for r in Responses) Removed = len(Responses) >= 1 and any('File deleted' in r for r in Responses)
if not Removed: if not Removed:
raise Exception(f"Firmware file '{FirmwareFile}' not removed") raise Exception(f"Firmware file '{FirmwareFile}' not removed")
return Removed return Removed
def _RollbackUpload(FirmwareFile): def _RollbackUpload(FirmwareFile):
if not rollback: return if not rollback: return
print(f"Rollback: trying to delete firmware '{FirmwareFile}'...") print(f"Rollback: trying to delete firmware '{FirmwareFile}'...")
_OpenPort() _OpenPort()
# Wait for SD card release # Wait for SD card release
time.sleep(1) time.sleep(1)
# Remount SD card # Remount SD card
_CheckSDCard() _CheckSDCard()
print(' OK' if _RemoveFirmwareFile(FirmwareFile) else ' Error!') print(' OK' if _RemoveFirmwareFile(FirmwareFile) else ' Error!')
_ClosePort() _ClosePort()
#---------------------# #---------------------#
# Callback Entrypoint # # Callback Entrypoint #
#---------------------# #---------------------#
port = None port = None
protocol = None protocol = None
filetransfer = None filetransfer = None
rollback = False rollback = False
# Get Marlin evironment vars # Get Marlin evironment vars
MarlinEnv = env['MARLIN_FEATURES'] MarlinEnv = env['MARLIN_FEATURES']
marlin_pioenv = _GetMarlinEnv(MarlinEnv, 'PIOENV') marlin_pioenv = _GetMarlinEnv(MarlinEnv, 'PIOENV')
marlin_motherboard = _GetMarlinEnv(MarlinEnv, 'MOTHERBOARD') marlin_motherboard = _GetMarlinEnv(MarlinEnv, 'MOTHERBOARD')
marlin_board_info_name = _GetMarlinEnv(MarlinEnv, 'BOARD_INFO_NAME') marlin_board_info_name = _GetMarlinEnv(MarlinEnv, 'BOARD_INFO_NAME')
marlin_board_custom_build_flags = _GetMarlinEnv(MarlinEnv, 'BOARD_CUSTOM_BUILD_FLAGS') marlin_board_custom_build_flags = _GetMarlinEnv(MarlinEnv, 'BOARD_CUSTOM_BUILD_FLAGS')
marlin_firmware_bin = _GetMarlinEnv(MarlinEnv, 'FIRMWARE_BIN') marlin_firmware_bin = _GetMarlinEnv(MarlinEnv, 'FIRMWARE_BIN')
marlin_long_filename_host_support = _GetMarlinEnv(MarlinEnv, 'LONG_FILENAME_HOST_SUPPORT') is not None marlin_long_filename_host_support = _GetMarlinEnv(MarlinEnv, 'LONG_FILENAME_HOST_SUPPORT') is not None
marlin_longname_write = _GetMarlinEnv(MarlinEnv, 'LONG_FILENAME_WRITE_SUPPORT') is not None marlin_longname_write = _GetMarlinEnv(MarlinEnv, 'LONG_FILENAME_WRITE_SUPPORT') is not None
marlin_custom_firmware_upload = _GetMarlinEnv(MarlinEnv, 'CUSTOM_FIRMWARE_UPLOAD') is not None marlin_custom_firmware_upload = _GetMarlinEnv(MarlinEnv, 'CUSTOM_FIRMWARE_UPLOAD') is not None
marlin_short_build_version = _GetMarlinEnv(MarlinEnv, 'SHORT_BUILD_VERSION') marlin_short_build_version = _GetMarlinEnv(MarlinEnv, 'SHORT_BUILD_VERSION')
marlin_string_config_h_author = _GetMarlinEnv(MarlinEnv, 'STRING_CONFIG_H_AUTHOR') marlin_string_config_h_author = _GetMarlinEnv(MarlinEnv, 'STRING_CONFIG_H_AUTHOR')
# Get firmware upload params # Get firmware upload params
upload_firmware_source_name = str(source[0]) # Source firmware filename upload_firmware_source_name = str(source[0]) # Source firmware filename
upload_speed = env['UPLOAD_SPEED'] if 'UPLOAD_SPEED' in env else 115200 upload_speed = env['UPLOAD_SPEED'] if 'UPLOAD_SPEED' in env else 115200
# baud rate of serial connection # baud rate of serial connection
upload_port = _GetUploadPort(env) # Serial port to use upload_port = _GetUploadPort(env) # Serial port to use
# Set local upload params # Set local upload params
upload_firmware_target_name = os.path.basename(upload_firmware_source_name) upload_firmware_target_name = os.path.basename(upload_firmware_source_name)
# Target firmware filename # Target firmware filename
upload_timeout = 1000 # Communication timout, lossy/slow connections need higher values upload_timeout = 1000 # Communication timout, lossy/slow connections need higher values
upload_blocksize = 512 # Transfer block size. 512 = Autodetect upload_blocksize = 512 # Transfer block size. 512 = Autodetect
upload_compression = True # Enable compression upload_compression = True # Enable compression
upload_error_ratio = 0 # Simulated corruption ratio upload_error_ratio = 0 # Simulated corruption ratio
upload_test = False # Benchmark the serial link without storing the file upload_test = False # Benchmark the serial link without storing the file
upload_reset = True # Trigger a soft reset for firmware update after the upload upload_reset = True # Trigger a soft reset for firmware update after the upload
# Set local upload params based on board type to change script behavior # Set local upload params based on board type to change script behavior
# "upload_delete_old_bins": delete all *.bin files in the root of SD Card # "upload_delete_old_bins": delete all *.bin files in the root of SD Card
upload_delete_old_bins = marlin_motherboard in ['BOARD_CREALITY_V4', 'BOARD_CREALITY_V4210', 'BOARD_CREALITY_V422', 'BOARD_CREALITY_V423', upload_delete_old_bins = marlin_motherboard in ['BOARD_CREALITY_V4', 'BOARD_CREALITY_V4210', 'BOARD_CREALITY_V422', 'BOARD_CREALITY_V423',
'BOARD_CREALITY_V427', 'BOARD_CREALITY_V431', 'BOARD_CREALITY_V452', 'BOARD_CREALITY_V453', 'BOARD_CREALITY_V427', 'BOARD_CREALITY_V431', 'BOARD_CREALITY_V452', 'BOARD_CREALITY_V453',
'BOARD_CREALITY_V24S1'] 'BOARD_CREALITY_V24S1']
# "upload_random_name": generate a random 8.3 firmware filename to upload # "upload_random_name": generate a random 8.3 firmware filename to upload
upload_random_filename = marlin_motherboard in ['BOARD_CREALITY_V4', 'BOARD_CREALITY_V4210', 'BOARD_CREALITY_V422', 'BOARD_CREALITY_V423', upload_random_filename = marlin_motherboard in ['BOARD_CREALITY_V4', 'BOARD_CREALITY_V4210', 'BOARD_CREALITY_V422', 'BOARD_CREALITY_V423',
'BOARD_CREALITY_V427', 'BOARD_CREALITY_V431', 'BOARD_CREALITY_V452', 'BOARD_CREALITY_V453', 'BOARD_CREALITY_V427', 'BOARD_CREALITY_V431', 'BOARD_CREALITY_V452', 'BOARD_CREALITY_V453',
'BOARD_CREALITY_V24S1'] and not marlin_long_filename_host_support 'BOARD_CREALITY_V24S1'] and not marlin_long_filename_host_support
try: try:
# Start upload job # Start upload job
print(f"Uploading firmware '{os.path.basename(upload_firmware_target_name)}' to '{marlin_motherboard}' via '{upload_port}'") print(f"Uploading firmware '{os.path.basename(upload_firmware_target_name)}' to '{marlin_motherboard}' via '{upload_port}'")
# Dump some debug info # Dump some debug info
if Debug: if Debug:
print('Upload using:') print('Upload using:')
print('---- Marlin -----------------------------------') print('---- Marlin -----------------------------------')
print(f' PIOENV : {marlin_pioenv}') print(f' PIOENV : {marlin_pioenv}')
print(f' SHORT_BUILD_VERSION : {marlin_short_build_version}') print(f' SHORT_BUILD_VERSION : {marlin_short_build_version}')
print(f' STRING_CONFIG_H_AUTHOR : {marlin_string_config_h_author}') print(f' STRING_CONFIG_H_AUTHOR : {marlin_string_config_h_author}')
print(f' MOTHERBOARD : {marlin_motherboard}') print(f' MOTHERBOARD : {marlin_motherboard}')
print(f' BOARD_INFO_NAME : {marlin_board_info_name}') print(f' BOARD_INFO_NAME : {marlin_board_info_name}')
print(f' CUSTOM_BUILD_FLAGS : {marlin_board_custom_build_flags}') print(f' CUSTOM_BUILD_FLAGS : {marlin_board_custom_build_flags}')
print(f' FIRMWARE_BIN : {marlin_firmware_bin}') print(f' FIRMWARE_BIN : {marlin_firmware_bin}')
print(f' LONG_FILENAME_HOST_SUPPORT : {marlin_long_filename_host_support}') print(f' LONG_FILENAME_HOST_SUPPORT : {marlin_long_filename_host_support}')
print(f' LONG_FILENAME_WRITE_SUPPORT : {marlin_longname_write}') print(f' LONG_FILENAME_WRITE_SUPPORT : {marlin_longname_write}')
print(f' CUSTOM_FIRMWARE_UPLOAD : {marlin_custom_firmware_upload}') print(f' CUSTOM_FIRMWARE_UPLOAD : {marlin_custom_firmware_upload}')
print('---- Upload parameters ------------------------') print('---- Upload parameters ------------------------')
print(f' Source : {upload_firmware_source_name}') print(f' Source : {upload_firmware_source_name}')
print(f' Target : {upload_firmware_target_name}') print(f' Target : {upload_firmware_target_name}')
print(f' Port : {upload_port} @ {upload_speed} baudrate') print(f' Port : {upload_port} @ {upload_speed} baudrate')
print(f' Timeout : {upload_timeout}') print(f' Timeout : {upload_timeout}')
print(f' Block size : {upload_blocksize}') print(f' Block size : {upload_blocksize}')
print(f' Compression : {upload_compression}') print(f' Compression : {upload_compression}')
print(f' Error ratio : {upload_error_ratio}') print(f' Error ratio : {upload_error_ratio}')
print(f' Test : {upload_test}') print(f' Test : {upload_test}')
print(f' Reset : {upload_reset}') print(f' Reset : {upload_reset}')
print('-----------------------------------------------') print('-----------------------------------------------')
# Custom implementations based on board parameters # Custom implementations based on board parameters
# Generate a new 8.3 random filename # Generate a new 8.3 random filename
if upload_random_filename: if upload_random_filename:
upload_firmware_target_name = f"fw-{''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', k=5))}.BIN" upload_firmware_target_name = f"fw-{''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', k=5))}.BIN"
print(f"Board {marlin_motherboard}: Overriding firmware filename to '{upload_firmware_target_name}'") print(f"Board {marlin_motherboard}: Overriding firmware filename to '{upload_firmware_target_name}'")
# Delete all *.bin files on the root of SD Card (if flagged) # Delete all *.bin files on the root of SD Card (if flagged)
if upload_delete_old_bins: if upload_delete_old_bins:
# CUSTOM_FIRMWARE_UPLOAD is needed for this feature # CUSTOM_FIRMWARE_UPLOAD is needed for this feature
if not marlin_custom_firmware_upload: if not marlin_custom_firmware_upload:
raise Exception(f"CUSTOM_FIRMWARE_UPLOAD must be enabled in 'Configuration_adv.h' for '{marlin_motherboard}'") raise Exception(f"CUSTOM_FIRMWARE_UPLOAD must be enabled in 'Configuration_adv.h' for '{marlin_motherboard}'")
# Init & Open serial port # Init & Open serial port
port = serial.Serial(upload_port, baudrate = upload_speed, write_timeout = 0, timeout = 0.1) port = serial.Serial(upload_port, baudrate = upload_speed, write_timeout = 0, timeout = 0.1)
_OpenPort() _OpenPort()
# Check SD card status # Check SD card status
_CheckSDCard() _CheckSDCard()
# Get firmware files # Get firmware files
FirmwareFiles = _GetFirmwareFiles(marlin_long_filename_host_support) FirmwareFiles = _GetFirmwareFiles(marlin_long_filename_host_support)
if Debug: if Debug:
for FirmwareFile in FirmwareFiles: for FirmwareFile in FirmwareFiles:
print(f'Found: {FirmwareFile}') print(f'Found: {FirmwareFile}')
# Get all 1st level firmware files (to remove) # Get all 1st level firmware files (to remove)
OldFirmwareFiles = _FilterFirmwareFiles(FirmwareFiles[1:len(FirmwareFiles)-2], marlin_long_filename_host_support) # Skip header and footers of list OldFirmwareFiles = _FilterFirmwareFiles(FirmwareFiles[1:len(FirmwareFiles)-2], marlin_long_filename_host_support) # Skip header and footers of list
if len(OldFirmwareFiles) == 0: if len(OldFirmwareFiles) == 0:
print('No old firmware files to delete') print('No old firmware files to delete')
else: else:
print(f"Remove {len(OldFirmwareFiles)} old firmware file{'s' if len(OldFirmwareFiles) != 1 else ''}:") print(f"Remove {len(OldFirmwareFiles)} old firmware file{'s' if len(OldFirmwareFiles) != 1 else ''}:")
for OldFirmwareFile in OldFirmwareFiles: for OldFirmwareFile in OldFirmwareFiles:
print(f" -Removing- '{OldFirmwareFile}'...") print(f" -Removing- '{OldFirmwareFile}'...")
print(' OK' if _RemoveFirmwareFile(OldFirmwareFile) else ' Error!') print(' OK' if _RemoveFirmwareFile(OldFirmwareFile) else ' Error!')
# Close serial # Close serial
_ClosePort() _ClosePort()
# Cleanup completed # Cleanup completed
debugPrint('Cleanup completed') debugPrint('Cleanup completed')
# WARNING! The serial port must be closed here because the serial transfer that follow needs it! # WARNING! The serial port must be closed here because the serial transfer that follow needs it!
# Upload firmware file # Upload firmware file
debugPrint(f"Copy '{upload_firmware_source_name}' --> '{upload_firmware_target_name}'") debugPrint(f"Copy '{upload_firmware_source_name}' --> '{upload_firmware_target_name}'")
protocol = MarlinBinaryProtocol.Protocol(upload_port, upload_speed, upload_blocksize, float(upload_error_ratio), int(upload_timeout)) protocol = MarlinBinaryProtocol.Protocol(upload_port, upload_speed, upload_blocksize, float(upload_error_ratio), int(upload_timeout))
#echologger = MarlinBinaryProtocol.EchoProtocol(protocol) #echologger = MarlinBinaryProtocol.EchoProtocol(protocol)
protocol.connect() protocol.connect()
# Mark the rollback (delete broken transfer) from this point on # Mark the rollback (delete broken transfer) from this point on
rollback = True rollback = True
filetransfer = MarlinBinaryProtocol.FileTransferProtocol(protocol) filetransfer = MarlinBinaryProtocol.FileTransferProtocol(protocol)
transferOK = filetransfer.copy(upload_firmware_source_name, upload_firmware_target_name, upload_compression, upload_test) transferOK = filetransfer.copy(upload_firmware_source_name, upload_firmware_target_name, upload_compression, upload_test)
protocol.disconnect() protocol.disconnect()
# Notify upload completed # Notify upload completed
protocol.send_ascii('M117 Firmware uploaded' if transferOK else 'M117 Firmware upload failed') protocol.send_ascii('M117 Firmware uploaded' if transferOK else 'M117 Firmware upload failed')
# Remount SD card # Remount SD card
print('Wait for SD card release...') print('Wait for SD card release...')
time.sleep(1) time.sleep(1)
print('Remount SD card') print('Remount SD card')
protocol.send_ascii('M21') protocol.send_ascii('M21')
# Transfer failed? # Transfer failed?
if not transferOK: if not transferOK:
protocol.shutdown() protocol.shutdown()
_RollbackUpload(upload_firmware_target_name) _RollbackUpload(upload_firmware_target_name)
else: else:
# Trigger firmware update # Trigger firmware update
if upload_reset: if upload_reset:
print('Trigger firmware update...') print('Trigger firmware update...')
protocol.send_ascii('M997', True) protocol.send_ascii('M997', True)
protocol.shutdown() protocol.shutdown()
print('Firmware update completed' if transferOK else 'Firmware update failed') print('Firmware update completed' if transferOK else 'Firmware update failed')
return 0 if transferOK else -1 return 0 if transferOK else -1
except KeyboardInterrupt: except KeyboardInterrupt:
print('Aborted by user') print('Aborted by user')
if filetransfer: filetransfer.abort() if filetransfer: filetransfer.abort()
if protocol: if protocol:
protocol.disconnect() protocol.disconnect()
protocol.shutdown() protocol.shutdown()
_RollbackUpload(upload_firmware_target_name) _RollbackUpload(upload_firmware_target_name)
_ClosePort() _ClosePort()
raise raise
except serial.SerialException as se: except serial.SerialException as se:
# This exception is raised only for send_ascii data (not for binary transfer) # This exception is raised only for send_ascii data (not for binary transfer)
print(f'Serial excepion: {se}, transfer aborted') print(f'Serial excepion: {se}, transfer aborted')
if protocol: if protocol:
protocol.disconnect() protocol.disconnect()
protocol.shutdown() protocol.shutdown()
_RollbackUpload(upload_firmware_target_name) _RollbackUpload(upload_firmware_target_name)
_ClosePort() _ClosePort()
raise Exception(se) raise Exception(se)
except MarlinBinaryProtocol.FatalError: except MarlinBinaryProtocol.FatalError:
print('Too many retries, transfer aborted') print('Too many retries, transfer aborted')
if protocol: if protocol:
protocol.disconnect() protocol.disconnect()
protocol.shutdown() protocol.shutdown()
_RollbackUpload(upload_firmware_target_name) _RollbackUpload(upload_firmware_target_name)
_ClosePort() _ClosePort()
raise raise
except Exception as ex: except Exception as ex:
print(f"\nException: {ex}, transfer aborted") print(f"\nException: {ex}, transfer aborted")
if protocol: if protocol:
protocol.disconnect() protocol.disconnect()
protocol.shutdown() protocol.shutdown()
_RollbackUpload(upload_firmware_target_name) _RollbackUpload(upload_firmware_target_name)
_ClosePort() _ClosePort()
print('Firmware not updated') print('Firmware not updated')
raise raise
# Attach custom upload callback # Attach custom upload callback
env.Replace(UPLOADCMD=Upload) env.Replace(UPLOADCMD=Upload)