Skip to content

Instantly share code, notes, and snippets.

@tcbennun
Last active November 30, 2020 15:32
Show Gist options
  • Save tcbennun/56aa50cae2eabbcf0a0705c233b55ce9 to your computer and use it in GitHub Desktop.
Save tcbennun/56aa50cae2eabbcf0a0705c233b55ce9 to your computer and use it in GitHub Desktop.
espflash
#!/usr/bin/perl
use feature qw(say);
# try to get correct Python (and detect system)
if ($^O eq "MSWin32" or ($^O eq "linux" and `uname -r` =~ /microsoft/)) {
$python = "python.exe";
$system = "windows";
}
else {
$python = "python";
$system = "linux";
}
$esptool_cmd = "${python} -m esptool --baud 921600";
# ensure it can run
open STDERR_copy, ">&STDERR";
close STDERR;
`${esptool_cmd} --help`;
open STDERR, ">&STDERR_copy";
if ($? != 0) {
say "esptool couldn't run (make sure it's installed, and that python is in your exec path)";
exit 1;
}
# kill PuTTY window if relevant
sub kill_putty {
if ($system eq "windows") {
my $port = $_[0];
if (not $port eq "") {
`taskkill.exe /IM putty.exe /FI 'windowtitle eq ${_[0]}*' /f`;
}
}
}
sub write_flash {
my $port = $_[0];
my $file = $_[1];
my $addr = $_[2];
kill_putty $port;
if (not $port eq "" and not $file eq "") {
system "${esptool_cmd} --port ${port} write_flash ${addr} ${file}";
}
}
sub write_flash_esp32 {
my $port = $_[0];
my $file = $_[1];
my $file_partitions = $file;
$file_partitions =~ s/\.bin$/\.partitions\.bin/;
kill_putty $port;
if (not $port eq "" and not $file eq "") {
my $opts = "--chip esp32 --before default_reset --after hard_reset";
my $flash_opts = "-z --flash_mode dio --flash_freq 80m --flash_size detect";
my $boot_app = "0xe000 /opt/esp32_arduino/tools/partitions/boot_app0.bin";
my $bootloader = "0x1000 /opt/esp32_arduino/tools/sdk/bin/bootloader_dio_80m.bin";
my $sketch = "0x10000 ${file}";
my $partitions = "0x8000 ${file_partitions}";
system "${esptool_cmd} ${opts} --port ${port} write_flash ${flash_opts} ${boot_app} ${bootloader} ${sketch} ${partitions}";
}
}
sub get_flash_id {
my $port = $_[0];
kill_putty $port;
if (not $port eq "") {
return map
{/Detected flash size: ([0-9]+\wB)/}
`${esptool_cmd} --port ${port} flash_id`;
}
}
sub flash_id {
say get_flash_id $_[0];
}
sub erase_flash {
my $port = $_[0];
kill_putty $port;
if (not $port eq "") {
system "${esptool_cmd} --port ${port} erase_flash";
}
}
my $cmd = $ARGV[0];
if ($cmd eq "write") {
if ($#ARGV != 2) {
say "usage: espflash write PORT FILENAME";
}
else {
write_flash $ARGV[1], $ARGV[2], "0x0";
}
}
elsif ($cmd eq "write_esp32") {
if ($#ARGV != 2) {
say "usage: espflash write_esp32 PORT FILENAME";
}
else {
write_flash_esp32 $ARGV[1], $ARGV[2];
}
}
elsif ($cmd eq "write_addr") {
if ($#ARGV != 3) {
say "usage: espflash write_addr PORT ADDRESS FILENAME";
}
else {
write_flash $ARGV[1], $ARGV[3], $ARGV[2];
}
}
elsif ($cmd eq "write_fs") {
if ($#ARGV != 2) {
say "usage: espflash write_fs PORT FILENAME";
}
else {
write_flash $ARGV[1], $ARGV[2], "0x200000";
}
}
elsif ($cmd eq "write_eeprom") {
if ($#ARGV != 2) {
say "usage: espflash write_eeprom PORT FILENAME";
}
else {
my @flash = get_flash_id($ARGV[1]);
my $flash = @flash[0];
my $addr = "";
if ($flash eq "4MB") {
$addr = "0x3FB000";
}
elsif ($flash eq "16MB") {
$addr = "0xFFB000";
}
else {
say "unknown flash ID: ${flash}";
}
if (not $addr eq "") {
write_flash $ARGV[1], $ARGV[2], $addr;
}
}
}
elsif ($cmd eq "flash_id") {
if ($#ARGV != 1) {
say "usage: espflash flash_id PORT";
}
else {
flash_id $ARGV[1];
}
}
elsif ($cmd eq "erase") {
if ($#ARGV != 1) {
say "usage: espflash erase PORT";
}
else {
erase_flash $ARGV[1];
}
}
else {
say "unsupported cmd '${cmd}'";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment