Skip to content

Commit

Permalink
Support for ESP32-C3, ESP32-S2 and ESP32-S3 (Jason2866#16)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jason2866 authored Apr 2, 2022
1 parent de941a3 commit 5b3cf81
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 121 deletions.
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

0 comments on commit 5b3cf81

Please sign in to comment.