Merge "stm32_flash: fix sector erase in UART mode"
diff --git a/util/stm32_flash/i2c.c b/util/stm32_flash/i2c.c
index 00a4992..8232d94 100644
--- a/util/stm32_flash/i2c.c
+++ b/util/stm32_flash/i2c.c
@@ -73,6 +73,8 @@
     handle->cmd_read_memory = CMD_READ_MEMORY;
     handle->cmd_write_memory = CMD_WRITE_MEMORY_NS;
 
+    handle->no_extra_sync = 0;
+
     handle->write_data = i2c_write_data;
     handle->write_cmd = i2c_write_cmd;
     handle->read_data = i2c_read_data;
diff --git a/util/stm32_flash/spi.c b/util/stm32_flash/spi.c
index bec5e00..305194a 100644
--- a/util/stm32_flash/spi.c
+++ b/util/stm32_flash/spi.c
@@ -157,6 +157,8 @@
     handle->cmd_read_memory = CMD_READ_MEMORY;
     handle->cmd_write_memory = CMD_WRITE_MEMORY;
 
+    handle->no_extra_sync = 0;
+
     handle->write_data = spi_write_data;
     handle->write_cmd = spi_write_cmd;
     handle->read_data = spi_read_data;
diff --git a/util/stm32_flash/stm32_bl.c b/util/stm32_flash/stm32_bl.c
index 9f651d3..0577a75 100644
--- a/util/stm32_flash/stm32_bl.c
+++ b/util/stm32_flash/stm32_bl.c
@@ -100,19 +100,34 @@
 /* erase a single sector */
 uint8_t erase_sector(handle_t *handle, uint16_t sector)
 {
+    uint8_t buffer[sizeof(uint16_t)+sizeof(uint16_t)+1];
     uint8_t ret;
 
     handle->write_cmd(handle, handle->cmd_erase);
     ret = handle->read_ack(handle);
-    if (sector < 0xFFF0 && ret == CMD_ACK) {
+    if (ret != CMD_ACK)
+        return ret;
+
+    if (sector >= 0xFFF0) {
+        /* special erase */
+        write_cnt(handle, sector);
+    } else if (handle->no_extra_sync) {
+        /* sector erase without extra sync (UART case) */
+        buffer[0] = 0;  /* MSB num of sectors - 1 */
+        buffer[1] = 0;  /* LSB num of sectors - 1 */
+        buffer[2] = (sector >> 8) & 0xFF;
+        buffer[3] = (sector     ) & 0xFF;
+        handle->write_data(handle, buffer, sizeof(uint16_t)+sizeof(uint16_t));
+    } else {
+        /* sector erase */
         write_cnt(handle, 0x0000);
         ret = read_ack_loop(handle);
-    }
-    if (ret == CMD_ACK) {
+        if (ret != CMD_ACK)
+            return ret;
         write_cnt(handle, sector);
-        ret = read_ack_loop(handle);
     }
-    return ret;
+
+    return read_ack_loop(handle);
 }
 
 /* read memory - this will chop the request into 256 byte reads */
diff --git a/util/stm32_flash/stm32_bl.h b/util/stm32_flash/stm32_bl.h
index 19b9573..81e57df 100644
--- a/util/stm32_flash/stm32_bl.h
+++ b/util/stm32_flash/stm32_bl.h
@@ -19,6 +19,7 @@
 
 /*
  * cmd_erase, cmd_read_memory, cmd_write_memory - byte to send for cmd
+ * no_extra_sync - uart erase requires no extra sync between cnt and sector
  *
  * write_data - write length bytes of data
  *   (function must checksum data. space reserved for checksum in buffer)
@@ -32,6 +33,7 @@
     uint8_t cmd_erase;
     uint8_t cmd_read_memory;
     uint8_t cmd_write_memory;
+    uint8_t no_extra_sync;
 
     uint8_t (*write_data)(struct handle *, uint8_t *buffer, int length);
     uint8_t (*write_cmd)(struct handle *, uint8_t cmd);
diff --git a/util/stm32_flash/uart.c b/util/stm32_flash/uart.c
index 111203d..aa3a337 100644
--- a/util/stm32_flash/uart.c
+++ b/util/stm32_flash/uart.c
@@ -89,6 +89,8 @@
     handle->cmd_read_memory = CMD_READ_MEMORY;
     handle->cmd_write_memory = CMD_WRITE_MEMORY;
 
+    handle->no_extra_sync = 1;
+
     handle->write_data = uart_write_data;
     handle->write_cmd = uart_write_cmd;
     handle->read_data = uart_read_data;