Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for ESP32-C3, ESP32-S2 and ESP32-S3 #16

Merged
merged 10 commits into from
Apr 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 85 additions & 59 deletions esp_flasher/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,54 +9,71 @@
import serial

from esp_flasher import const
from esp_flasher.common import ESP32ChipInfo, Esp_flasherError, chip_run_stub, \
configure_write_flash_args, detect_chip, detect_flash_size, read_chip_info
from esp_flasher.const import ESP32_DEFAULT_BOOTLOADER_FORMAT, ESP32_DEFAULT_OTA_DATA, \
ESP32_DEFAULT_PARTITIONS
from esp_flasher.common import (
ESP32ChipInfo,
Esp_flasherError,
chip_run_stub,
configure_write_flash_args,
detect_chip,
detect_flash_size,
read_chip_info,
)
from esp_flasher.const import (
ESP32_DEFAULT_BOOTLOADER_FORMAT,
ESP32_DEFAULT_OTA_DATA,
)
from esp_flasher.helpers import list_serial_ports


def parse_args(argv):
parser = argparse.ArgumentParser(prog='esp_flasher {}'.format(const.__version__))
parser.add_argument('-p', '--port',
help="Select the USB/COM port for uploading.")
parser = argparse.ArgumentParser(prog=f"esp_flasher {const.__version__}")
parser.add_argument("-p", "--port", help="Select the USB/COM port for uploading.")
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('--esp8266', action='store_true')
group.add_argument('--esp32', action='store_true')
group.add_argument('--upload-baud-rate', type=int, default=460800,
help="Baud rate to upload with (not for logging)")
parser.add_argument('--bootloader',
help="(ESP32-only) The bootloader to flash.",
default=ESP32_DEFAULT_BOOTLOADER_FORMAT)
parser.add_argument('--partitions',
help="(ESP32-only) The partitions to flash.",
default=ESP32_DEFAULT_PARTITIONS)
parser.add_argument('--otadata',
help="(ESP32-only) The otadata file to flash.",
default=ESP32_DEFAULT_OTA_DATA)
parser.add_argument('--no-erase',
help="Do not erase flash before flashing",
action='store_true')
parser.add_argument('--show-logs', help="Only show logs", action='store_true')
parser.add_argument('binary', help="The binary image to flash.")
group.add_argument("--esp8266", action="store_true")
group.add_argument("--esp32", action="store_true")
group.add_argument(
"--upload-baud-rate",
type=int,
default=460800,
help="Baud rate to upload with (not for logging)",
)
parser.add_argument(
"--bootloader",
help="(ESP32-only) The bootloader to flash.",
default=ESP32_DEFAULT_BOOTLOADER_FORMAT,
)
parser.add_argument(
"--partitions",
help="(ESP32-only) The partitions to flash.",
)
parser.add_argument(
"--otadata",
help="(ESP32-only) The otadata file to flash.",
default=ESP32_DEFAULT_OTA_DATA,
)
parser.add_argument(
"--no-erase", help="Do not erase flash before flashing", action="store_true"
)
parser.add_argument("--show-logs", help="Only show logs", action="store_true")
parser.add_argument("binary", help="The binary image to flash.")

return parser.parse_args(argv[1:])


def select_port(args):
if args.port is not None:
print(u"Using '{}' as serial port.".format(args.port))
print(f"Using '{args.port}' as serial port.")
return args.port
ports = list_serial_ports()
if not ports:
raise Esp_flasherError("No serial port found!")
if len(ports) != 1:
print("Found more than one serial port:")
for port, desc in ports:
print(u" * {} ({})".format(port, desc))
print(f" * {port} ({desc})")
print("Please choose one with the --port argument.")
raise Esp_flasherError
print(u"Auto-detected serial port: {}".format(ports[0][0]))
print(f"Auto-detected serial port: {ports[0][0]}")
return ports[0][0]


Expand All @@ -69,14 +86,14 @@ def show_logs(serial_port):
except serial.SerialException:
print("Serial port closed!")
return
text = raw.decode(errors='ignore')
line = text.replace('\r', '').replace('\n', '')
time = datetime.now().time().strftime('[%H:%M:%S]')
message = time + line
text = raw.decode(errors="ignore")
line = text.replace("\r", "").replace("\n", "")
time_ = datetime.now().time().strftime("[%H:%M:%S]")
message = time_ + line
try:
print(message)
except UnicodeEncodeError:
print(message.encode('ascii', 'backslashreplace'))
print(message.encode("ascii", "backslashreplace"))


def run_esp_flasher(argv):
Expand All @@ -89,27 +106,29 @@ def run_esp_flasher(argv):
return

try:
firmware = open(args.binary, 'rb')
# pylint: disable=consider-using-with
firmware = open(args.binary, "rb")
except IOError as err:
raise Esp_flasherError("Error opening binary: {}".format(err))
raise Esp_flasherError(f"Error opening binary: {err}") from err
chip = detect_chip(port, args.esp8266, args.esp32)
info = read_chip_info(chip)

print()
print("Chip Info:")
print(" - Chip Family: {}".format(info.family))
print(" - Chip Model: {}".format(info.model))
print(f" - Chip Family: {info.family}")
print(f" - Chip Model: {info.model}")
if isinstance(info, ESP32ChipInfo):
print(" - Number of Cores: {}".format(info.num_cores))
print(" - Max CPU Frequency: {}".format(info.cpu_frequency))
print(" - Has Bluetooth: {}".format('YES' if info.has_bluetooth else 'NO'))
print(" - Has Embedded Flash: {}".format('YES' if info.has_embedded_flash else 'NO'))
print(" - Has Factory-Calibrated ADC: {}".format(
'YES' if info.has_factory_calibrated_adc else 'NO'))
print(f" - Number of Cores: {info.num_cores}")
print(f" - Max CPU Frequency: {info.cpu_frequency}")
print(f" - Has Bluetooth: {'YES' if info.has_bluetooth else 'NO'}")
print(f" - Has Embedded Flash: {'YES' if info.has_embedded_flash else 'NO'}")
print(
f" - Has Factory-Calibrated ADC: {'YES' if info.has_factory_calibrated_adc else 'NO'}"
)
else:
print(" - Chip ID: {:08X}".format(info.chip_id))
print(f" - Chip ID: {info.chip_id:08X}")

print(" - MAC Address: {}".format(info.mac))
print(f" - MAC Address: {info.mac}")

stub_chip = chip_run_stub(chip)
flash_size = None
Expand All @@ -118,46 +137,50 @@ def run_esp_flasher(argv):
try:
stub_chip.change_baud(args.upload_baud_rate)
except esptool.FatalError as err:
raise Esp_flasherError("Error changing ESP upload baud rate: {}".format(err))
raise Esp_flasherError(
f"Error changing ESP upload baud rate: {err}"
) from err

# Check if the higher baud rate works
try:
flash_size = detect_flash_size(stub_chip)
except Esp_flasherError as err:
except Esp_flasherError:
# Go back to old baud rate by recreating chip instance
print("Chip does not support baud rate {}, changing to 115200".format(args.upload_baud_rate))
print(
f"Chip does not support baud rate {args.upload_baud_rate}, changing to 115200"
)
# pylint: disable=protected-access
stub_chip._port.close()
chip = detect_chip(port, args.esp8266, args.esp32)
stub_chip = chip_run_stub(chip)

if flash_size is None:
flash_size = detect_flash_size(stub_chip)

print(f" - Flash Size: {flash_size}")

print(" - Flash Size: {}".format(flash_size))
mock_args = configure_write_flash_args(
info, firmware, flash_size, args.bootloader, args.partitions, args.otadata
)

mock_args = configure_write_flash_args(info, firmware, flash_size,
args.bootloader, args.partitions,
args.otadata)

print(" - Flash Mode: {}".format(mock_args.flash_mode))
print(" - Flash Frequency: {}Hz".format(mock_args.flash_freq.upper()))
print(f" - Flash Mode: {mock_args.flash_mode}")
print(f" - Flash Frequency: {mock_args.flash_freq.upper()}Hz")

try:
stub_chip.flash_set_parameters(esptool.flash_size_bytes(flash_size))
except esptool.FatalError as err:
raise Esp_flasherError("Error setting flash parameters: {}".format(err))
raise Esp_flasherError(f"Error setting flash parameters: {err}") from err

if not args.no_erase:
try:
esptool.erase_flash(stub_chip, mock_args)
except esptool.FatalError as err:
raise Esp_flasherError("Error while erasing flash: {}".format(err))
raise Esp_flasherError(f"Error while erasing flash: {err}") from err

try:
esptool.write_flash(stub_chip, mock_args)
except esptool.FatalError as err:
raise Esp_flasherError("Error while writing flash: {}".format(err))
raise Esp_flasherError(f"Error while writing flash: {err}") from err

print("Hard Resetting...")
stub_chip.hard_reset()
Expand All @@ -166,10 +189,13 @@ def run_esp_flasher(argv):
print()

if args.upload_baud_rate != 115200:
# pylint: disable=protected-access
stub_chip._port.baudrate = 115200
time.sleep(0.05) # ignore sent data during baud rate change
time.sleep(0.05) # get rid of crap sent during baud rate change
# pylint: disable=protected-access
stub_chip._port.flushInput()

# pylint: disable=protected-access
show_logs(stub_chip._port)


Expand Down
Loading