Description: Add support for ESP32
Author: Ivan Grokhotkov <igrokhotkov@gmail.com>
Origin: upstream
Applied-Upstream: commit 95e1e36
---
This patch header follows DEP-3: http://dep.debian.net/deps/dep3/
--- a/README.md
+++ b/README.md
@@ -34,6 +34,8 @@
 ```-cb <baudrate>``` | Select the baudrate to use, default is 115200.
 ```-ca <address>``` | Address in flash memory to upload the data to. This address is interpreted as hexadecimal. Default is 0x00000000.
 ```-cf <filename>``` | Upload the file to flash. Parameters that set the port, baud rate, and address must preceed the -cf command.
+```-cp <size>``` | Pad last written section of firmware image to the given size, in bytes.
+```-cc <chip>``` | Select chip to upload to. Currently supported values: `esp8266`, `esp32`
 
 Supported boards
 ----------------
@@ -70,5 +72,3 @@
 Copyright (C) 2014 Christian Klippel <ck@atelier-klippel.de>.
 
 This code is licensed under GPL v2.
-
-
--- a/argparse/argparse_commcmd.c
+++ b/argparse/argparse_commcmd.c
@@ -96,6 +96,16 @@
                     return 2;
                 }
 
+            case 'c':
+                if (num_args < 1)
+                {
+                    return 0;
+                }
+                if (espcomm_set_chip(arg_ptr[0]))
+                {
+                    return 2;
+                }
+
             default:
                 return 0;
                 break;
--- a/espcomm/espcomm.c
+++ b/espcomm/espcomm.c
@@ -70,6 +70,10 @@
 
 static int file_uploaded = 0;
 
+typedef enum {ESPCOMM_8266, ESPCOMM_32} espcomm_chip_t;
+
+static espcomm_chip_t s_chip = ESPCOMM_8266;
+
 static void espcomm_enter_boot(void)
 {
     espcomm_board_reset_into_bootloader(espcomm_board);
@@ -287,45 +291,81 @@
     serialport_close();
 }
 
+int espcomm_set_flash_params(uint32_t device_id, uint32_t chip_size,
+    uint32_t block_size, uint32_t sector_size,
+    uint32_t page_size, uint32_t status_mask)
+{
+    LOGDEBUG("espcomm_set_flash_params: %x %x %x %x %x %x", device_id, chip_size,
+                block_size, sector_size, page_size, status_mask);
+
+    flash_packet[0] = device_id;
+    flash_packet[1] = chip_size;
+    flash_packet[2] = block_size;
+    flash_packet[3] = sector_size;
+    flash_packet[4] = page_size;
+    flash_packet[5] = status_mask;
+
+    send_packet.checksum = espcomm_calc_checksum((unsigned char*) flash_packet, 24);
+
+    uint32_t res = espcomm_send_command(SET_FLASH_PARAMS, (unsigned char*) &flash_packet, 24, 0);
+    return res;
+}
+
 int espcomm_start_flash(uint32_t size, uint32_t address)
 {
     uint32_t res;
 
     LOGDEBUG("size: %06x address: %06x", size, address);
+    int erase_size;
 
-    const int sector_size = 4096;
-    const int sectors_per_block  = 16;
-    const int first_sector_index = address / sector_size;
-    LOGDEBUG("first_sector_index: %d", first_sector_index);
-
-    const int total_sector_count = ((size % sector_size) == 0) ? 
-                                    (size / sector_size) : (size / sector_size + 1);
-    LOGDEBUG("total_sector_count: %d", total_sector_count);
-
-    const int max_head_sector_count  = sectors_per_block - (first_sector_index % sectors_per_block);
-    const int head_sector_count = (max_head_sector_count > total_sector_count) ? 
-                                    total_sector_count : max_head_sector_count;
-    LOGDEBUG("head_sector_count: %d", head_sector_count);
-
-    // SPIEraseArea function in the esp8266 ROM has a bug which causes extra area to be erased.
-    // If the address range to be erased crosses the block boundary,
-    // then extra head_sector_count sectors are erased.
-    // If the address range doesn't cross the block boundary,
-    // then extra total_sector_count sectors are erased.
-
-    const int adjusted_sector_count = (total_sector_count > 2 * head_sector_count) ?
-                                      (total_sector_count - head_sector_count):
-                                      (total_sector_count + 1) / 2;
-    LOGDEBUG("adjusted_sector_count: %d", adjusted_sector_count);
+    if (s_chip == ESPCOMM_8266)
+    {
+        const int sector_size = 4096;
+        const int sectors_per_block  = 16;
+        const int first_sector_index = address / sector_size;
+        LOGDEBUG("first_sector_index: %d", first_sector_index);
+
+        const int total_sector_count = ((size % sector_size) == 0) ?
+                                        (size / sector_size) : (size / sector_size + 1);
+        LOGDEBUG("total_sector_count: %d", total_sector_count);
+
+        const int max_head_sector_count  = sectors_per_block - (first_sector_index % sectors_per_block);
+        const int head_sector_count = (max_head_sector_count > total_sector_count) ?
+                                        total_sector_count : max_head_sector_count;
+        LOGDEBUG("head_sector_count: %d", head_sector_count);
+
+        // SPIEraseArea function in the esp8266 ROM has a bug which causes extra area to be erased.
+        // If the address range to be erased crosses the block boundary,
+        // then extra head_sector_count sectors are erased.
+        // If the address range doesn't cross the block boundary,
+        // then extra total_sector_count sectors are erased.
+
+        const int adjusted_sector_count = (total_sector_count > 2 * head_sector_count) ?
+                                          (total_sector_count - head_sector_count):
+                                          (total_sector_count + 1) / 2;
+        LOGDEBUG("adjusted_sector_count: %d", adjusted_sector_count);
 
-    const int adjusted_size = adjusted_sector_count * sector_size;
-    LOGDEBUG("adjusted_size: %06x", adjusted_size);
-    
-    flash_packet[0] = adjusted_size;
-    flash_packet[1] = 0x00000200;
+        erase_size = adjusted_sector_count * sector_size;
+    }
+    else {
+        erase_size = size;
+
+        res = espcomm_set_flash_params(0, (128/8)*1024*1024, 64*1024, 4*1024, 256, 0xffff);
+        if (res == 0)
+        {
+            LOGWARN("espcomm_send_command(SET_FLASH_PARAMS) failed");
+            return res;
+        }
+    }
+
+
+    LOGDEBUG("erase_size: %06x", erase_size);
+
+    flash_packet[0] = erase_size;
+    flash_packet[1] = (size + BLOCKSIZE_FLASH - 1) / BLOCKSIZE_FLASH;
     flash_packet[2] = BLOCKSIZE_FLASH;
     flash_packet[3] = address;
-    
+
     send_packet.checksum = espcomm_calc_checksum((unsigned char*) flash_packet, 16);
 
     // int timeout_ms = size / erase_block_size * delay_per_erase_block_ms + 250;
@@ -502,3 +542,18 @@
     return 1;
 }
 
+int espcomm_set_chip(const char* name)
+{
+    LOGDEBUG("setting chip to %s", name);
+    if (strcmp(name, "esp8266") == 0 || strcmp(name, "8266") == 0) {
+        s_chip = ESPCOMM_8266;
+    }
+    else if (strcmp(name, "esp32") == 0 || strcmp(name, "32") == 0) {
+        s_chip = ESPCOMM_32;
+    }
+    else {
+        LOGERR("unknown chip: %s", name);
+        return 0;
+    }
+    return 1;
+}
--- a/espcomm/espcomm.h
+++ b/espcomm/espcomm.h
@@ -38,6 +38,7 @@
     SYNC_FRAME                  = 0x08,
     WRITE_REGISTER              = 0x09,
     READ_REGISTER               = 0x0A,
+    SET_FLASH_PARAMS            = 0x0B,
     NO_COMMAND                  = 0xFF
 };
 
@@ -64,6 +65,7 @@
 int espcomm_set_baudrate(const char *baudrate);
 int espcomm_set_address(const char *address);
 int espcomm_set_board(const char* name);
+int espcomm_set_chip(const char* name);
 
 int espcomm_open(void);
 void espcomm_close(void);
