Browse Source

Merge branch 'refactor/examples' into 'master'

Examples refactor

See merge request espressif/esp-serial-flasher!15
Martin Válik 5 years ago
parent
commit
f5a4565f7a
41 changed files with 310 additions and 695 deletions
  1. 5 4
      .gitlab-ci.yml
  2. 0 0
      examples/binaries/ESP32/bootloader.bin
  3. 0 0
      examples/binaries/ESP32/hello-world.bin
  4. 0 0
      examples/binaries/ESP32/partition-table.bin
  5. 0 0
      examples/binaries/ESP32_AT_Firmware/Firmware.bin
  6. 0 0
      examples/binaries/ESP32_S2/bootloader.bin
  7. 0 0
      examples/binaries/ESP32_S2/hello-world.bin
  8. 0 0
      examples/binaries/ESP32_S2/partition-table.bin
  9. 0 0
      examples/binaries/ESP8266/bootloader.bin
  10. 0 0
      examples/binaries/ESP8266/hello-world.bin
  11. 0 0
      examples/binaries/ESP8266/partition-table.bin
  12. 20 0
      examples/common/bin2array.cmake
  13. 53 93
      examples/common/example_common.c
  14. 17 5
      examples/common/example_common.h
  15. 0 1
      examples/esp32_example/CMakeLists.txt
  16. 4 5
      examples/esp32_example/README.md
  17. 17 0
      examples/esp32_example/main/CMakeLists.txt
  18. 44 0
      examples/esp32_example/main/main.c
  19. 0 76
      examples/flash_at_firmware/README.md
  20. 0 2
      examples/flash_at_firmware/main/CMakeLists.txt
  21. 0 96
      examples/flash_at_firmware/main/flash_at_firmware.c
  22. 0 8
      examples/flash_multiple_partitions/CMakeLists.txt
  23. 0 8
      examples/flash_multiple_partitions/main/CMakeLists.txt
  24. 0 72
      examples/flash_multiple_partitions/main/flash_multiple_partitions.c
  25. 0 6
      examples/flash_multiple_partitions/partitions_example.csv
  26. 0 3
      examples/flash_multiple_partitions/sdkconfig.defaults
  27. 2 24
      examples/raspberry_example/CMakeLists.txt
  28. 1 1
      examples/raspberry_example/README.md
  29. 34 79
      examples/raspberry_example/Src/main.c
  30. BIN
      examples/raspberry_example/images/bootloader.bin
  31. BIN
      examples/raspberry_example/images/hello-world.bin
  32. BIN
      examples/raspberry_example/images/partition-table.bin
  33. 13 22
      examples/stm32_example/CMakeLists.txt
  34. 4 2
      examples/stm32_example/README.md
  35. 89 181
      examples/stm32_example/Src/main.c
  36. BIN
      examples/stm32_example/images/bootloader.bin
  37. BIN
      examples/stm32_example/images/hello-world.bin
  38. BIN
      examples/stm32_example/images/partition-table.bin
  39. 1 0
      port/esp32_port.c
  40. 4 4
      port/raspberry_port.c
  41. 2 3
      src/esp_loader.c

+ 5 - 4
.gitlab-ci.yml

@@ -40,10 +40,11 @@ build_with_idf:
     - internet
     - internet
   script:
   script:
     - *clone_and_setup_idf
     - *clone_and_setup_idf
-    - cd $CI_PROJECT_DIR/examples/flash_multiple_partitions
-    - idf.py build
-    - cd $CI_PROJECT_DIR/examples/flash_at_firmware
-    - idf.py build
+    - cd $CI_PROJECT_DIR/examples/esp32_example
+    # Build for all supported targets
+    - idf.py build -DTARGET_SOC=ESP32    -DMD5_ENABLED=1
+    - idf.py build -DTARGET_SOC=ESP8266  -DMD5_ENABLED=0
+    - idf.py build -DTARGET_SOC=ESP32_S2 -DMD5_ENABLED=1
 
 
     - *clone_and_setup_stm32
     - *clone_and_setup_stm32
     - cd $CI_PROJECT_DIR/examples/stm32_example/build
     - cd $CI_PROJECT_DIR/examples/stm32_example/build

+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP32/bootloader.bin → examples/binaries/ESP32/bootloader.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP32/hello-world.bin → examples/binaries/ESP32/hello-world.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP32/partition-table.bin → examples/binaries/ESP32/partition-table.bin


+ 0 - 0
examples/flash_at_firmware/image/Firmware.bin → examples/binaries/ESP32_AT_Firmware/Firmware.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP32_S2/bootloader.bin → examples/binaries/ESP32_S2/bootloader.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP32_S2/hello-world.bin → examples/binaries/ESP32_S2/hello-world.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP32_S2/partition-table.bin → examples/binaries/ESP32_S2/partition-table.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP8266/bootloader.bin → examples/binaries/ESP8266/bootloader.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP8266/hello-world.bin → examples/binaries/ESP8266/hello-world.bin


+ 0 - 0
examples/flash_multiple_partitions/spiffs_image/ESP8266/partition-table.bin → examples/binaries/ESP8266/partition-table.bin


+ 20 - 0
examples/common/bin2array.cmake

@@ -0,0 +1,20 @@
+# Creates C resources file from files in given directory
+function(create_resources dir output)
+    # Create empty output file
+    file(WRITE ${output} "")
+    # Collect input files
+    file(GLOB bins ${dir}/*)
+    # Iterate through input files
+    foreach(bin ${bins})
+        # Get short filenames
+        string(REGEX MATCH "([^/]+)$" filename ${bin})
+        # Replace filename spaces & extension separator for C compatibility
+        string(REGEX REPLACE "\\.| |-" "_" filename ${filename})
+        # Read hex data from file
+        file(READ ${bin} filedata HEX)
+        # Convert hex data for C compatibility
+        string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata})
+        # Append data to output file
+        file(APPEND ${output} "const unsigned char ${filename}[] = {${filedata}};\nconst unsigned ${filename}_size = sizeof(${filename});\n")
+    endforeach()
+endfunction()

+ 53 - 93
examples/common/example_common.c

@@ -13,131 +13,91 @@
  * limitations under the License.
  * limitations under the License.
  */
  */
 
 
+#include <stdio.h>
+#include <string.h>
 #include <sys/param.h>
 #include <sys/param.h>
-#include "esp_err.h"
-#include "esp_log.h"
 #include "serial_io.h"
 #include "serial_io.h"
 #include "esp_loader.h"
 #include "esp_loader.h"
-#include "driver/uart.h"
-#include "driver/gpio.h"
 #include "example_common.h"
 #include "example_common.h"
 
 
-#define HIGHER_BAUD_RATE 230400
-
-void flash_binary(FILE *image, size_t image_size, size_t address)
+esp_loader_error_t connect_to_target(uint32_t higrer_baudrate)
 {
 {
-    esp_loader_error_t err;
-    int32_t packet_number = 0;
-    static uint8_t payload[1024];
+    esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
 
 
-    ESP_LOGI(TAG, "Erasing flash...");
-    err = esp_loader_flash_start(address, image_size, sizeof(payload));
+    esp_loader_error_t err = esp_loader_connect(&connect_config);
     if (err != ESP_LOADER_SUCCESS) {
     if (err != ESP_LOADER_SUCCESS) {
-        ESP_LOGE(TAG, "Erasing flash failed with error %d.", err);
-        return;
+        printf("Cannot connect to target. Error: %u\n", err);
+        return err;
     }
     }
-    ESP_LOGI(TAG, "Start programming");
-
-    while (image_size > 0) {
-        size_t to_read = MIN(image_size, sizeof(payload));
+    printf("Connected to target\n");
 
 
-        size_t read = fread(payload, 1, to_read, image);
-        if (read != to_read) {
-            ESP_LOGE(TAG, "Error occurred while reading file. to_read %u, read %u", to_read, read);
-            return;
+#ifndef TARGET_ESP8266
+    if (higrer_baudrate) {
+        err = esp_loader_change_baudrate(higrer_baudrate);
+        if (err != ESP_LOADER_SUCCESS) {
+            printf("Unable to change baud rate on target.");
+            return err;
         }
         }
 
 
-        err = esp_loader_flash_write(payload, to_read);
+        err = loader_port_change_baudrate(higrer_baudrate);
         if (err != ESP_LOADER_SUCCESS) {
         if (err != ESP_LOADER_SUCCESS) {
-            ESP_LOGE(TAG, "Packet could not be written");
-            return;
+            printf("Unable to change baud rate.");
+            return err;
         }
         }
-
-        printf("packet: %d  written: %u B\n", packet_number++, to_read);
-
-        image_size -= to_read;
-    };
-
-    ESP_LOGI(TAG, "Finished programming");
-
-#if MD5_ENABLED
-    err = esp_loader_flash_verify();
-    if (err != ESP_LOADER_SUCCESS) {
-        ESP_LOGE(TAG, "MD5 does not match. err: %d", err);
-        return;
+        printf("Baudrate changed\n");
     }
     }
-    ESP_LOGI(TAG, "Flash verified");
 #endif
 #endif
-}
 
 
-FILE *get_image_and_its_size(const char *path, size_t *image_size)
-{
-    FILE *image = fopen(path, "r");
-    if (image == NULL) {
-        ESP_LOGE(TAG, "Failed to open file %s", path);
-        return NULL;
-    }
-
-    fseek(image, 0L, SEEK_END);
-    *image_size = ftell(image);
-    rewind(image);
-
-    ESP_LOGW(TAG, "File %s opened. Size: %u bytes", path, *image_size);
-
-    return image;
+    return ESP_LOADER_SUCCESS;
 }
 }
 
 
-void upload_file(const char *path, size_t address)
-{
-    size_t image_size;
-    FILE *image = get_image_and_its_size(path, &image_size);
 
 
-    if (image != NULL) {
-        flash_binary(image, image_size, address);
-        fclose(image);
-    }
-}
-
-esp_err_t connect_to_target()
+esp_loader_error_t flash_binary(const unsigned char *bin, size_t size, size_t address)
 {
 {
-    const loader_serial_config_t config = {
-        .baud_rate = 115200,
-        .uart_port = UART_NUM_1,
-        .uart_rx_pin = GPIO_NUM_5,
-        .uart_tx_pin = GPIO_NUM_4,
-        .reset_trigger_pin = GPIO_NUM_25,
-        .gpio0_trigger_pin = GPIO_NUM_26,
-    };
+    esp_loader_error_t err;
+    static uint8_t payload[1024];
+    const unsigned char *bin_addr = bin;
 
 
-    // Initialize UART
-    esp_loader_error_t err = loader_port_serial_init(&config);
+    printf("Erasing flash (this may take a while)...\n");
+    err = esp_loader_flash_start(address, size, sizeof(payload));
     if (err != ESP_LOADER_SUCCESS) {
     if (err != ESP_LOADER_SUCCESS) {
-        ESP_LOGE(TAG, "serial initialization failed.");
+        printf("Erasing flash failed with error %d.\n", err);
         return err;
         return err;
     }
     }
+    printf("Start programming\n");
 
 
-    esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
+    size_t binary_size = size;
+    size_t written = 0; 
 
 
-    err = esp_loader_connect(&connect_config);
-    if (err != ESP_LOADER_SUCCESS) {
-        ESP_LOGE(TAG, "Cannot connect to target. Error: %u", err);
-        return err;
-    }
-    ESP_LOGI(TAG, "Connected to target");
+    while (size > 0) {
+        size_t to_read = MIN(size, sizeof(payload));
+        memcpy(payload, bin_addr, to_read);
 
 
-#ifndef TARGET_ESP8266
-    err = esp_loader_change_baudrate(HIGHER_BAUD_RATE);
-    if (err != ESP_LOADER_SUCCESS) {
-        ESP_LOGE(TAG, "Unable to change baud rate on target.");
-        return err;
-    }
+        err = esp_loader_flash_write(payload, to_read);
+        if (err != ESP_LOADER_SUCCESS) {
+            printf("\nPacket could not be written! Error %d.\n", err);
+            return err;
+        }
+
+        size -= to_read;
+        bin_addr += to_read;
+        written += to_read;
 
 
-    err = loader_port_change_baudrate(HIGHER_BAUD_RATE);
+        int progress = (int)(((float)written / binary_size) * 100);
+        printf("\rProgress: %d %%", progress);
+        fflush(stdout);
+    };
+
+    printf("\nFinished programming\n");
+
+#if MD5_ENABLED
+    err = esp_loader_flash_verify();
     if (err != ESP_LOADER_SUCCESS) {
     if (err != ESP_LOADER_SUCCESS) {
-        ESP_LOGE(TAG, "Unable to change baud rate.");
+        printf("MD5 does not match. err: %d\n", err);
         return err;
         return err;
     }
     }
+    printf("Flash verified\n");
 #endif
 #endif
 
 
-    return ESP_OK;
+    return ESP_LOADER_SUCCESS;
 }
 }

+ 17 - 5
examples/common/example_common.h

@@ -15,9 +15,21 @@
 
 
 #pragma once
 #pragma once
 
 
-static const char *TAG = "example";
+#ifndef TARGET_ESP8266
+    #define BOOTLOADER_ADDRESS 0x1000
+#else
+    #define BOOTLOADER_ADDRESS 0x0
+#endif
 
 
-void flash_binary(FILE *image, size_t image_size, size_t address);
-FILE *get_image_and_its_size(const char *path, size_t *image_size);
-void upload_file(const char *path, size_t address);
-esp_err_t connect_to_target();
+#define PARTITION_ADDRESS   0x8000
+#define APPLICATION_ADDRESS 0x10000
+
+extern const unsigned char bootloader_bin[];
+extern const unsigned bootloader_bin_size;
+extern const unsigned char hello_world_bin[];
+extern const unsigned hello_world_bin_size;
+extern const unsigned char partition_table_bin[];
+extern const unsigned partition_table_bin_size;
+
+esp_loader_error_t connect_to_target(uint32_t higrer_baudrate);
+esp_loader_error_t flash_binary(const unsigned char *bin, size_t size, size_t address);

+ 0 - 1
examples/flash_at_firmware/CMakeLists.txt → examples/esp32_example/CMakeLists.txt

@@ -3,6 +3,5 @@
 cmake_minimum_required(VERSION 3.5)
 cmake_minimum_required(VERSION 3.5)
 
 
 set(EXTRA_COMPONENT_DIRS ../../)
 set(EXTRA_COMPONENT_DIRS ../../)
-
 include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 include($ENV{IDF_PATH}/tools/cmake/project.cmake)
 project(esp-serial-flasher)
 project(esp-serial-flasher)

+ 4 - 5
examples/flash_multiple_partitions/README.md → examples/esp32_example/README.md

@@ -2,9 +2,7 @@
 
 
 ## Overview
 ## Overview
 
 
-Example demonstrates how to flash ESP32/ESP32-S2/ESP8266 from another (host) MCU using esp_serial_flash component API. In this case, ESP32 is also used as host MCU. Binary to be flashed from host MCU to ESP* is stored in partition named `spiffs`. Binaries are placed in separate folder for each target.
-
-This example is based on spiffsgen example located in IDF. For more information how to use SPIFFS Image Generator, refer to [spiffsgen example](https://github.com/espressif/esp-idf/tree/master/examples/storage/spiffsgen)
+Example demonstrates how to flash ESP32/ESP32-S2/ESP8266 from another (host) MCU using esp_serial_flash component API. In this case, ESP32 is also used as host MCU. Binaries to be flashed from host MCU to another Espressif SoC can be found in `binaries` folder and are converted into C-array during build process.
 
 
 Following steps are performed in order to re-program target's memory:
 Following steps are performed in order to re-program target's memory:
 
 
@@ -49,12 +47,13 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
 
 
 ## Configuration
 ## Configuration
 
 
-For details about available configuration option, please refer to top level [README.md](../../README.md). Compile definitions can be specified on command line when running `idf.py`, for example:
+For details about available configuration option, please refer to top level [README.md](../../README.md). 
+Compile definitions can be specified on command line when running `idf.py`, for example:
 
 
 ```
 ```
 idf.py build -DTARGET_SOC=ESP32_S2 -DMD5_ENABLED=1
 idf.py build -DTARGET_SOC=ESP32_S2 -DMD5_ENABLED=1
 ```
 ```
-By default, example is compiled for ESP32 target with MD5 check disabled.
+Binaries to be flashed are placed in separate folder for each target and converted to C-array for any given SoC based on `TARGET_SOC` configuration option passed to command line. By default, example is compiled for ESP32 target with MD5 check enabled.
 
 
 ## Example output
 ## Example output
 
 

+ 17 - 0
examples/esp32_example/main/CMakeLists.txt

@@ -0,0 +1,17 @@
+idf_component_register(SRCS "main.c" "binaries.c" "../../common/example_common.c"
+                       INCLUDE_DIRS ".""../../common")
+
+set_property(SOURCE binaries.c PROPERTY GENERATED 1)
+
+include(${CMAKE_CURRENT_LIST_DIR}/../../common/bin2array.cmake)
+
+if(TARGET_SOC STREQUAL "ESP32_S2")
+    set(binary_path ${CMAKE_CURRENT_LIST_DIR}/../../binaries/ESP32_S2)
+elseif(TARGET_SOC STREQUAL "ESP8266")
+    set(binary_path ${CMAKE_CURRENT_LIST_DIR}/../../binaries/ESP8266)
+else()
+    set(binary_path ${CMAKE_CURRENT_LIST_DIR}/../../binaries/ESP32)
+endif()
+
+create_resources(${binary_path} binaries.c)
+

+ 44 - 0
examples/esp32_example/main/main.c

@@ -0,0 +1,44 @@
+/* Flash multiple partitions example
+
+   This example code is in the Public Domain (or CC0 licensed, at your option.)
+
+   Unless required by applicable law or agreed to in writing, this
+   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+   CONDITIONS OF ANY KIND, either express or implied.
+*/
+
+#include <sys/param.h>
+#include <string.h>
+#include "esp_err.h"
+#include "esp_log.h"
+#include "driver/uart.h"
+#include "driver/gpio.h"
+#include "serial_io.h"
+#include "esp_loader.h"
+#include "loader_config.h"
+#include "example_common.h"
+
+#define HIGHER_BAUDRATE 230400
+
+void app_main(void)
+{
+    const loader_serial_config_t config = {
+        .baud_rate = 115200,
+        .uart_port = UART_NUM_1,
+        .uart_rx_pin = GPIO_NUM_5,
+        .uart_tx_pin = GPIO_NUM_4,
+        .reset_trigger_pin = GPIO_NUM_25,
+        .gpio0_trigger_pin = GPIO_NUM_26,
+    };
+
+    if ( loader_port_serial_init(&config) != ESP_LOADER_SUCCESS) {
+        ESP_LOGE("example", "serial initialization failed.");
+        return;
+    }
+
+    if (connect_to_target(HIGHER_BAUDRATE) == ESP_LOADER_SUCCESS) {
+        flash_binary(bootloader_bin, bootloader_bin_size, BOOTLOADER_ADDRESS);
+        flash_binary(partition_table_bin, partition_table_bin_size, PARTITION_ADDRESS);
+        flash_binary(hello_world_bin, hello_world_bin_size, APPLICATION_ADDRESS);
+    }
+}

+ 0 - 76
examples/flash_at_firmware/README.md

@@ -1,76 +0,0 @@
-# Flash AT firmware example
-
-## Overview
-
-Example demonstrates how to flash AT command firmware from one ESP32 to another using esp_serial_flash component API. Binary to be flashed has to be stored on SD card with `fat` filesystem. AT command firmware to copy onto SD card can be found in `image` folder. When other AT command firmware is stored on SD card, file name has to be changed in example accordingly.
-
-Following steps are performed in order to re-program target's memory:
-
-1. Filesystem is initialized and mounted.
-2. UART1 through which new binary will be transfered is initialized.
-3. Host puts slave device into boot mode tries to connect by calling `esp_loader_connect()`.
-4. Binary file is opened and its size is acquired, as it has to be known before flashing.
-5. Then `esp_loader_flash_start()` is called to enter flashing mode and erase amount of memory to be flashed.
-6. `esp_loader_flash_write()` function is called repeatedly until the whole binary image is transfered.
-
-## Hardware Required
-
-* `ESP_WROVER_KIT` (with SD card connector)
-* Another board based on WROWER module.
-* One or two USB cables for power supply and programming.
-* microSD card
-
-Note: WROWER module(ESP32) to be flashed can be substituted with any other Espressif SoC as long as appropriate AT firmware version is used.
-
-## Hardware connection
-
-Table below shows connection between two ESP32 devices.
-
-| ESP32 (host) | ESP32 (slave) |
-|:------------:|:-------------:|
-|    IO26      |      IO0      |
-|    IO25      |     RESET     |
-|    IO4       |      RX0      |
-|    IO5       |      TX0      |
-
-### Build and flash
-
-To run the example, type the following command:
-
-```CMake
-idf.py -p PORT flash monitor
-```
-
-(To exit the serial monitor, type ``Ctrl-]``.)
-
-See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
-
-## Configuration
-
-For details about available configuration option, please refer to top level [README.md](../../README.md). Compile definitions can be specified on command line when running `idf.py`, for example:
-
-```
-idf.py build -DTARGET_SOC=ESP32_S2 -DMD5_ENABLED=1
-```
-By default, example is compiled for ESP32 target with MD5 check disabled.
-When target is not ESP32, provide appropriate AT command firmware binary.
-
-For available AT command firmwares refer to [AT firmwares](https://www.espressif.com/en/support/download/at)
-
-## Example output
-
-Here is the example's console output:
-
-```
-...
-I (342) example: Initializing SPIFFS
-I (482) example: Image size: 144672
-I (902) example: Connected to target
-I (1732) example: Start programming
-I (1832) example: packet: 0  written: 1024 B
-I (1932) example: packet: 1  written: 1024 B
-...
-I (16052) example: packet: 140  written: 1024 B
-I (16152) example: packet: 141  written: 288 B
-I (16152) example: Finished programming
-```

+ 0 - 2
examples/flash_at_firmware/main/CMakeLists.txt

@@ -1,2 +0,0 @@
-idf_component_register(SRCS "flash_at_firmware.c" "../../common/example_common.c"
-                       INCLUDE_DIRS "." "../../common")

+ 0 - 96
examples/flash_at_firmware/main/flash_at_firmware.c

@@ -1,96 +0,0 @@
-/* Flash AT firmware example
-
-   This example code is in the Public Domain (or CC0 licensed, at your option.)
-
-   Unless required by applicable law or agreed to in writing, this
-   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-   CONDITIONS OF ANY KIND, either express or implied.
-*/
-#include "esp_err.h"
-#include "esp_log.h"
-#include "esp_vfs_fat.h"
-#include "driver/sdspi_host.h"
-#include "driver/spi_common.h"
-#include "example_common.h"
-
-#define MOUNT_POINT "/sdcard"
-
-#define SPI_DMA_CHAN 1
-
-#define PIN_NUM_MISO 2
-#define PIN_NUM_MOSI 15
-#define PIN_NUM_CLK  14
-#define PIN_NUM_CS   13
-
-static sdmmc_card_t *card;
-static sdmmc_host_t host = SDSPI_HOST_DEFAULT();
-
-esp_err_t sdcard_init(void)
-{
-    ESP_LOGI(TAG, "Initializing SD card");
-
-    // Use settings defined above to initialize SD card and mount FAT filesystem.
-    // Note: esp_vfs_fat_sdmmc/sdspi_mount is all-in-one convenience functions.
-    // Please check its source code and implement error recovery when developing
-    // production applications.
-
-    spi_bus_config_t bus_cfg = {
-        .mosi_io_num = PIN_NUM_MOSI,
-        .miso_io_num = PIN_NUM_MISO,
-        .sclk_io_num = PIN_NUM_CLK,
-        .quadwp_io_num = -1,
-        .quadhd_io_num = -1,
-        .max_transfer_sz = 4000,
-    };
-    
-    if( spi_bus_initialize(host.slot, &bus_cfg, SPI_DMA_CHAN) != ESP_OK ) {
-        ESP_LOGE(TAG, "Failed to initialize bus.");
-        return ESP_FAIL;
-    }
-
-    // This initializes the slot without card detect (CD) and write protect (WP) signals.
-    // Modify slot_config.gpio_cd and slot_config.gpio_wp if your board has these signals.
-    sdspi_device_config_t slot_config = SDSPI_DEVICE_CONFIG_DEFAULT();
-    slot_config.gpio_cs = PIN_NUM_CS;
-    slot_config.host_id = host.slot;
-
-    esp_vfs_fat_sdmmc_mount_config_t mount_config = {
-        .format_if_mount_failed = false,
-        .max_files = 5,
-        .allocation_unit_size = 16 * 1024
-    };
-
-    const char mount_point[] = MOUNT_POINT;
-
-    esp_err_t ret = esp_vfs_fat_sdspi_mount(mount_point, &host, &slot_config, &mount_config, &card);
-
-    if (ret != ESP_OK) {
-        if (ret == ESP_FAIL) {
-            ESP_LOGE(TAG, "Failed to mount filesystem. "
-                     "If you want the card to be formatted, set the EXAMPLE_FORMAT_IF_MOUNT_FAILED menuconfig option.");
-        } else {
-            ESP_LOGE(TAG, "Failed to initialize the card (%s). "
-                     "Make sure SD card lines have pull-up resistors in place.", esp_err_to_name(ret));
-        }
-        return ESP_FAIL;
-    }
-
-    return ESP_OK;
-}
-
-void sdcard_deinit()
-{
-    esp_vfs_fat_sdcard_unmount(MOUNT_POINT, card);
-    ESP_LOGI(TAG, "Card unmounted");
-    spi_bus_free(host.slot);
-}
-
-void app_main(void)
-{
-    if ( sdcard_init() == ESP_OK ) {
-        if ( connect_to_target() == ESP_OK) {
-            upload_file(MOUNT_POINT"/Firmware.bin", 0);
-        }
-        sdcard_deinit();
-    }
-}

+ 0 - 8
examples/flash_multiple_partitions/CMakeLists.txt

@@ -1,8 +0,0 @@
-# The following lines of boilerplate have to be in your project's CMakeLists
-# in this exact order for cmake to work correctly
-cmake_minimum_required(VERSION 3.5)
-
-set(EXTRA_COMPONENT_DIRS ../../)
-
-include($ENV{IDF_PATH}/tools/cmake/project.cmake)
-project(esp-serial-flasher)

+ 0 - 8
examples/flash_multiple_partitions/main/CMakeLists.txt

@@ -1,8 +0,0 @@
-idf_component_register(SRCS "flash_multiple_partitions.c" "../../common/example_common.c"
-                       INCLUDE_DIRS ".""../../common")
-
-# Create a SPIFFS image from the contents of the 'spiffs_image' directory
-# that fits the partition named 'storage'. FLASH_IN_PROJECT indicates that
-# the generated image should be flashed when the entire project is flashed to
-# the target with 'idf.py -p PORT flash'. 
-spiffs_create_partition_image(storage ../spiffs_image FLASH_IN_PROJECT)

+ 0 - 72
examples/flash_multiple_partitions/main/flash_multiple_partitions.c

@@ -1,72 +0,0 @@
-/* Flash multiple partitions example
-
-   This example code is in the Public Domain (or CC0 licensed, at your option.)
-
-   Unless required by applicable law or agreed to in writing, this
-   software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
-   CONDITIONS OF ANY KIND, either express or implied.
-*/
-
-#include <sys/param.h>
-#include <string.h>
-#include "esp_err.h"
-#include "esp_log.h"
-#include "esp_spiffs.h"
-#include "loader_config.h"
-#include "example_common.h"
-
-
-#ifndef TARGET_ESP8266
-const uint32_t BOOTLOADER_ADDRESS = 0x1000;
-#else
-const uint32_t BOOTLOADER_ADDRESS = 0x0;
-#endif
-const uint32_t PARTITION_ADDRESS = 0x8000;
-const uint32_t APPLICATION_ADDRESS = 0x10000;
-
-#if defined TARGET_ESP8266
-#define BINARY_PATH "/spiffs/ESP8266/"
-#elif defined TARGET_ESP32
-#define BINARY_PATH "/spiffs/ESP32/"
-#elif defined TARGET_ESP32_S2
-#define BINARY_PATH "/spiffs/ESP32_S2/"
-#endif
-
-static esp_err_t register_vfs()
-{
-    ESP_LOGI(TAG, "Initializing SPIFFS");
-
-    esp_vfs_spiffs_conf_t conf = {
-        .base_path = "/spiffs",
-        .partition_label = NULL,
-        .max_files = 5,
-        .format_if_mount_failed = false
-    };
-
-    // Use settings defined above to initialize and mount SPIFFS filesystem.
-    esp_err_t ret = esp_vfs_spiffs_register(&conf);
-
-    if (ret != ESP_OK) {
-        if (ret == ESP_FAIL) {
-            ESP_LOGE(TAG, "Failed to mount or format filesystem");
-        } else if (ret == ESP_ERR_NOT_FOUND) {
-            ESP_LOGE(TAG, "Failed to find SPIFFS partition");
-        } else {
-            ESP_LOGE(TAG, "Failed to initialize SPIFFS (%s)", esp_err_to_name(ret));
-        }
-    }
-
-    return ret;
-}
-
-void app_main(void)
-{
-    if ( register_vfs() == ESP_OK ) {
-        if ( connect_to_target() == ESP_OK) {
-            upload_file(BINARY_PATH"partition-table.bin", PARTITION_ADDRESS);
-            upload_file(BINARY_PATH"bootloader.bin", BOOTLOADER_ADDRESS);
-            upload_file(BINARY_PATH"hello-world.bin", APPLICATION_ADDRESS);
-        }
-        esp_vfs_spiffs_unregister(NULL);
-    }
-}

+ 0 - 6
examples/flash_multiple_partitions/partitions_example.csv

@@ -1,6 +0,0 @@
-# Name,   Type, SubType, Offset,  Size, Flags
-# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
-nvs,      data, nvs,     0x9000,  0x6000,
-phy_init, data, phy,     0xf000,  0x1000,
-factory,  app,  factory, 0x10000, 1M,
-storage,  data, spiffs,  ,        0xF0000, 

+ 0 - 3
examples/flash_multiple_partitions/sdkconfig.defaults

@@ -1,3 +0,0 @@
-CONFIG_PARTITION_TABLE_CUSTOM=y
-CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_example.csv"
-CONFIG_PARTITION_TABLE_FILENAME="partitions_example.csv"

+ 2 - 24
examples/raspberry_example/CMakeLists.txt

@@ -1,35 +1,13 @@
 cmake_minimum_required(VERSION 3.5)
 cmake_minimum_required(VERSION 3.5)
 
 
-# Creates C resources file from files in given directory
-function(create_resources dir output)
-    # Create empty output file
-    file(WRITE ${output} "")
-    # Collect input files
-    file(GLOB bins ${dir}/*)
-    # Iterate through input files
-    foreach(bin ${bins})
-        # Get short filenames
-        string(REGEX MATCH "([^/]+)$" filename ${bin})
-        message(STATUS "filename: " ${filename})
-        # Replace filename spaces & extension separator for C compatibility
-        string(REGEX REPLACE "\\.| |-" "_" filename ${filename})
-        # Read hex data from file
-        file(READ ${bin} filedata HEX)
-        # Convert hex data for C compatibility
-        string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata})
-        # Append data to output file
-        file(APPEND ${output} "const unsigned char ${filename}[] = {${filedata}};\nconst unsigned ${filename}_size = sizeof(${filename});\n")
-    endforeach()
-endfunction()
-
 set(FLASHER_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
 set(FLASHER_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
 set(PORT RASPBERRY_PI)
 set(PORT RASPBERRY_PI)
 
 
 project(raspberry_flasher)
 project(raspberry_flasher)
     
     
-create_resources(images Src/binaries.c)
+add_executable(${CMAKE_PROJECT_NAME} Src/main.c ../common/example_common.c)
 
 
-add_executable(${CMAKE_PROJECT_NAME} Src/main.c Src/binaries.c)
+target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ../common/)
 
 
 add_subdirectory(${FLASHER_DIR} ${CMAKE_BINARY_DIR}/flasher)
 add_subdirectory(${FLASHER_DIR} ${CMAKE_BINARY_DIR}/flasher)
 
 

+ 1 - 1
examples/raspberry_example/README.md

@@ -2,7 +2,7 @@
 
 
 ## Overview
 ## Overview
 
 
-Example demonstrates how to flash ESP32 from Raspberry Pi 4 (Model B) using esp_serial_flash component API. Binaries to be flashed from Raspberry Pi to ESP32 can be found in `images` directory and converted into C-arrays during build process. USART0 is dedicated for communication with ESP32.
+Example demonstrates how to flash ESP32 from Raspberry Pi 4 (Model B) using esp_serial_flash component API. AT command firmware to be flashed from Raspberry Pi to ESP32 can be found in `binaries`. USART0 is dedicated for communication with ESP32.
 
 
 Following steps are performed in order to re-program target's memory:
 Following steps are performed in order to re-program target's memory:
 
 

+ 34 - 79
examples/raspberry_example/Src/main.c

@@ -9,10 +9,12 @@
 
 
 #include <stdio.h>
 #include <stdio.h>
 #include <stdint.h>
 #include <stdint.h>
+#include <stdlib.h>
 #include <string.h>
 #include <string.h>
 #include <sys/param.h>
 #include <sys/param.h>
 #include "serial_io.h"
 #include "serial_io.h"
 #include "esp_loader.h"
 #include "esp_loader.h"
+#include "example_common.h"
 
 
 #define TARGET_RST_Pin 2
 #define TARGET_RST_Pin 2
 #define TARGET_IO0_Pin 3
 #define TARGET_IO0_Pin 3
@@ -21,103 +23,56 @@
 #define HIGHER_BAUD_RATE  460800
 #define HIGHER_BAUD_RATE  460800
 #define SERIAL_DEVICE     "/dev/ttyS0"
 #define SERIAL_DEVICE     "/dev/ttyS0"
 
 
-esp_loader_error_t loader_port_rpi_init(const char *device,
-                                        uint32_t baudrate,
-                                        uint32_t reset_trigger_pin,
-                                        uint32_t gpio0_trigger_pin);
+#define BINARY_PATH       "../../binaries/ESP32_AT_Firmware/Firmware.bin"
 
 
-extern const unsigned char bootloader_bin[];
-extern const unsigned bootloader_bin_size;
-extern const unsigned char hello_world_bin[];
-extern const unsigned hello_world_bin_size;
-extern const unsigned char partition_table_bin[];
-extern const unsigned partition_table_bin_size;
+esp_loader_error_t loader_port_raspberry_init(const char *device,
+                                              uint32_t baudrate,
+                                              uint32_t reset_trigger_pin,
+                                              uint32_t gpio0_trigger_pin);
 
 
-const uint32_t BOOTLOADER_ADDRESS  = 0x1000;
-const uint32_t PARTITION_ADDRESS   = 0x8000;
-const uint32_t APPLICATION_ADDRESS = 0x10000;
 
 
-
-esp_loader_error_t flash_binary(const unsigned char *bin, size_t size, size_t address)
+static void upload_file(const char *path, size_t address)
 {
 {
-    esp_loader_error_t err;
-    int32_t packet_number = 0;
-    static uint8_t payload[1024];
-    const unsigned char *bin_addr = bin;
-
-    printf("Erasing flash...\n");
-    err = esp_loader_flash_start(address, size, sizeof(payload));
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Erasing flash failed with error %d.\n", err);
-        return err;
-    }
-    printf("Start programming\n");
-
-    while (size > 0) {
-        size_t to_read = MIN(size, sizeof(payload));
-        memcpy(payload, bin_addr, to_read);
-
-        err = esp_loader_flash_write(payload, to_read);
-        if (err != ESP_LOADER_SUCCESS) {
-            printf("Packet could not be written\n");
-            return err;
-        }
-
-        printf("packet: %ld  written: %u B\n", packet_number++, to_read);
-
-        size -= to_read;
-        bin_addr += to_read;
-    };
+    char *buffer = NULL;
 
 
-    printf("Finished programming\n");
-
-#if MD5_ENABLED
-    err = esp_loader_flash_verify();
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("MD5 does not match. err: %d\n", err);
-        return err;
+    FILE *image = fopen(path, "r");
+    if (image == NULL) {
+        printf("Error:Failed to open file %s\n", path);
+        return;
     }
     }
-    printf("Flash verified\n");
-#endif
-
-    return ESP_LOADER_SUCCESS;
-}
 
 
-esp_loader_error_t connect_to_target()
-{
-    loader_port_rpi_init(SERIAL_DEVICE, DEFAULT_BAUD_RATE, TARGET_RST_Pin, TARGET_IO0_Pin);
+    fseek(image, 0L, SEEK_END);
+    size_t size = ftell(image);
+    rewind(image);
 
 
-    esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
+    printf("File %s opened. Size: %u bytes\n", path, size);
 
 
-    esp_loader_error_t err = esp_loader_connect(&connect_config);
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Cannot connect to target. Error: %u\n", err);
-        return err;
+    buffer = (char *)malloc(size);
+    if (buffer == NULL) {
+        printf("Error: Failed allocate memory\n");
+        goto cleanup;
     }
     }
-    printf("Connected to target\n");
 
 
-    err = esp_loader_change_baudrate(HIGHER_BAUD_RATE);
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Unable to change baud rate on target.\n");
-        return err;
+    // copy file content to buffer
+    size_t bytes_read = fread(buffer, 1, size, image);
+    if (bytes_read != size) {
+        printf("Error occurred while reading file");
+        goto cleanup;
     }
     }
 
 
-    err = loader_port_change_baudrate(HIGHER_BAUD_RATE);
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Unable to change baud rate.\n");
-        return err;
-    }
-    printf("Baudrate changed\n");
+    flash_binary(buffer, size, address);
 
 
-    return ESP_LOADER_SUCCESS;
+cleanup:
+    fclose(image);
+    free(buffer);
 }
 }
 
 
 int main(void)
 int main(void)
 {
 {
-    if (connect_to_target() == ESP_LOADER_SUCCESS) {
-        flash_binary(bootloader_bin, bootloader_bin_size, BOOTLOADER_ADDRESS);
-        flash_binary(partition_table_bin, partition_table_bin_size, PARTITION_ADDRESS);
-        flash_binary(hello_world_bin, hello_world_bin_size, APPLICATION_ADDRESS);
+    loader_port_raspberry_init(SERIAL_DEVICE, DEFAULT_BAUD_RATE, TARGET_RST_Pin, TARGET_IO0_Pin);
+
+    if (connect_to_target(HIGHER_BAUD_RATE) == ESP_LOADER_SUCCESS) {
+        upload_file(BINARY_PATH, 0);
     }
     }
 
 
     loader_port_reset_target();
     loader_port_reset_target();

BIN
examples/raspberry_example/images/bootloader.bin


BIN
examples/raspberry_example/images/hello-world.bin


BIN
examples/raspberry_example/images/partition-table.bin


+ 13 - 22
examples/stm32_example/CMakeLists.txt

@@ -1,26 +1,6 @@
 cmake_minimum_required(VERSION 3.5)
 cmake_minimum_required(VERSION 3.5)
 
 
-# Creates C resources file from files in given directory
-function(create_resources dir output)
-    # Create empty output file
-    file(WRITE ${output} "")
-    # Collect input files
-    file(GLOB bins ${dir}/*)
-    # Iterate through input files
-    foreach(bin ${bins})
-        # Get short filenames
-        string(REGEX MATCH "([^/]+)$" filename ${bin})
-        message(STATUS "filename: " ${filename})
-        # Replace filename spaces & extension separator for C compatibility
-        string(REGEX REPLACE "\\.| |-" "_" filename ${filename})
-        # Read hex data from file
-        file(READ ${bin} filedata HEX)
-        # Convert hex data for C compatibility
-        string(REGEX REPLACE "([0-9a-f][0-9a-f])" "0x\\1," filedata ${filedata})
-        # Append data to output file
-        file(APPEND ${output} "const unsigned char ${filename}[] = {${filedata}};\nconst unsigned ${filename}_size = sizeof(${filename});\n")
-    endforeach()
-endfunction()
+include(${CMAKE_CURRENT_LIST_DIR}/../common/bin2array.cmake)
 
 
 set(TOOLCHAIN_PREFIX / CACHE PATH "Path to arm toolchain")
 set(TOOLCHAIN_PREFIX / CACHE PATH "Path to arm toolchain")
 set(STM32Cube_DIR / CACHE PATH "Path to STM32 hal library")
 set(STM32Cube_DIR / CACHE PATH "Path to STM32 hal library")
@@ -34,17 +14,28 @@ project(stm32_flasher)
     
     
 enable_language(ASM)
 enable_language(ASM)
 
 
-create_resources(images Src/binaries.c)
+if(TARGET_SOC STREQUAL "ESP32_S2")
+    set(binary_path ${CMAKE_CURRENT_LIST_DIR}/../binaries/ESP32_S2)
+elseif(TARGET_SOC STREQUAL "ESP8266")
+    set(binary_path ${CMAKE_CURRENT_LIST_DIR}/../binaries/ESP8266)
+else()
+    set(binary_path ${CMAKE_CURRENT_LIST_DIR}/../binaries/ESP32)
+endif()
+
+create_resources(${binary_path} Src/binaries.c)
 
 
 include_directories(${CMAKE_CURRENT_SOURCE_DIR} Inc)
 include_directories(${CMAKE_CURRENT_SOURCE_DIR} Inc)
  
  
 add_executable(${CMAKE_PROJECT_NAME} 
 add_executable(${CMAKE_PROJECT_NAME} 
+    ../common/example_common.c
     Src/main.c
     Src/main.c
     Src/stm32f4xx_hal_msp.c
     Src/stm32f4xx_hal_msp.c
     Src/stm32f4xx_it.c
     Src/stm32f4xx_it.c
     Src/libc_compat.c
     Src/libc_compat.c
     Src/binaries.c)
     Src/binaries.c)
 
 
+target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ../common)
+
 add_subdirectory(${FLASHER_DIR}/submodules ${CMAKE_BINARY_DIR}/submodules)
 add_subdirectory(${FLASHER_DIR}/submodules ${CMAKE_BINARY_DIR}/submodules)
 add_subdirectory(${FLASHER_DIR} ${CMAKE_BINARY_DIR}/flasher)
 add_subdirectory(${FLASHER_DIR} ${CMAKE_BINARY_DIR}/flasher)
 
 

+ 4 - 2
examples/stm32_example/README.md

@@ -1,8 +1,8 @@
-# Flash multiple partitions example
+# STM32 example
 
 
 ## Overview
 ## Overview
 
 
-Example demonstrates how to flash ESP32 from another STM32 (host MCU) using esp_serial_flash component API. STM32F4-Discovery board is used in this example, as STM32F407VG has FLASH memory large enough to fit the whole hello-world example of ESP32. Binaries to be flashed from host MCU to ESP32 can be found in images directory and converted into C-arrays during build process. USART1 is dedicated for communication with ESP32, whereas, USART2 can be used for debug purposes by attaching UART-to-USB bridge.
+Example demonstrates how to flash ESP32 from another STM32 (host MCU) using esp_serial_flash component API. STM32F4-Discovery board is used in this example, as STM32F407VG has FLASH memory large enough to fit the whole hello-world example of ESP32. Binaries to be flashed from host MCU to ESP32 can be found in `binaries` directory and converted into C-arrays during build process. USART1 is dedicated for communication with ESP32, whereas, USART2 can be used for debug purposes by attaching UART-to-USB bridge.
 
 
 Following steps are performed in order to re-program target's memory:
 Following steps are performed in order to re-program target's memory:
 
 
@@ -45,6 +45,8 @@ Run cmake (with appropriate parameters) and build:
 cmake -DTOOLCHAIN_PREFIX="/path_to_toolchain" -DSTM32Cube_DIR="path_to_stm32Cube" -DSTM32_CHIP="STM32F407VG" -DPORT="STM32" .. && cmake --build .
 cmake -DTOOLCHAIN_PREFIX="/path_to_toolchain" -DSTM32Cube_DIR="path_to_stm32Cube" -DSTM32_CHIP="STM32F407VG" -DPORT="STM32" .. && cmake --build .
 ```
 ```
 
 
+Binaries to be flashed are placed in separate folder for each target and converted to C-array for any given SoC based on `TARGET_SOC` configuration option passed to command line. By default, example is compiled for ESP32 target with MD5 check enabled.
+
 For more details regarding to esp_serial_flasher configuration and STM32 support, please refer to top level [README.md](../../README.md).
 For more details regarding to esp_serial_flasher configuration and STM32 support, please refer to top level [README.md](../../README.md).
 
 
 Note: CMake 3.13 or later is required.
 Note: CMake 3.13 or later is required.

+ 89 - 181
examples/stm32_example/Src/main.c

@@ -23,6 +23,7 @@
 #include <sys/param.h>
 #include <sys/param.h>
 #include "serial_io.h"
 #include "serial_io.h"
 #include "esp_loader.h"
 #include "esp_loader.h"
+#include "example_common.h"
 
 
 UART_HandleTypeDef huart1;
 UART_HandleTypeDef huart1;
 UART_HandleTypeDef huart2;
 UART_HandleTypeDef huart2;
@@ -32,217 +33,124 @@ static void MX_GPIO_Init(void);
 static void MX_USART1_UART_Init(void);
 static void MX_USART1_UART_Init(void);
 static void MX_USART2_UART_Init(void);
 static void MX_USART2_UART_Init(void);
 
 
-void flash_images(void);
-void loader_port_stm32_init(UART_HandleTypeDef *huart, 
-                            GPIO_TypeDef* port_io0, 
-                            uint16_t pin_num_io0, 
-                            GPIO_TypeDef* port_rst, 
+void loader_port_stm32_init(UART_HandleTypeDef *huart,
+                            GPIO_TypeDef *port_io0,
+                            uint16_t pin_num_io0,
+                            GPIO_TypeDef *port_rst,
                             uint16_t pin_num_rst);
                             uint16_t pin_num_rst);
 
 
-extern const unsigned char bootloader_bin[];
-extern const unsigned bootloader_bin_size;
-extern const unsigned char hello_world_bin[];
-extern const unsigned hello_world_bin_size;
-extern const unsigned char partition_table_bin[];
-extern const unsigned partition_table_bin_size;
 
 
-const uint32_t BOOTLOADER_ADDRESS  = 0x1000;
-const uint32_t PARTITION_ADDRESS   = 0x8000;
-const uint32_t APPLICATION_ADDRESS = 0x10000;
+#define HIGHER_BAUDRATE 230400
 
 
-
-#define HIGHER_BAUD_RATE 230400
-
-esp_loader_error_t flash_binary(const unsigned char *bin, size_t size, size_t address)
+int main(void)
 {
 {
-    esp_loader_error_t err;
-    int32_t packet_number = 0;
-    static uint8_t payload[1024];
-    const unsigned char *bin_addr = bin;
-
-    printf("Erasing flash...");
-    err = esp_loader_flash_start(address, size, sizeof(payload));
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Erasing flash failed with error %d.\n", err);
-        return err;
-    }
-    printf("Start programming");
-
-    while (size > 0) {
-        size_t to_read = MIN(size, sizeof(payload));
-        memcpy(payload, bin_addr, to_read);
+    HAL_Init();
+    SystemClock_Config();
+    MX_GPIO_Init();
+    MX_USART1_UART_Init();
+    MX_USART2_UART_Init();
 
 
-        err = esp_loader_flash_write(payload, to_read);
-        if (err != ESP_LOADER_SUCCESS) {
-            printf("Packet could not be written\n");
-            return err;
-        }
-
-        printf("packet: %ld  written: %u B\n", packet_number++, to_read);
-
-        size -= to_read;
-        bin_addr += to_read;
-    };
-
-    printf("Finished programming\n");
-
-#if MD5_ENABLED
-    err = esp_loader_flash_verify();
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("MD5 does not match. err: %d\n", err);
-        return err;
-    }
-    printf("Flash verified\n");
-#endif
-    
-    return ESP_LOADER_SUCCESS;
-}
-
-HAL_StatusTypeDef connect_to_target()
-{
     loader_port_stm32_init(&huart1, GPIOB, TARGET_IO0_Pin, GPIOB, TARGET_RST_Pin);
     loader_port_stm32_init(&huart1, GPIOB, TARGET_IO0_Pin, GPIOB, TARGET_RST_Pin);
-
-    esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
-
-    esp_loader_error_t err = esp_loader_connect(&connect_config);
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Cannot connect to target. Error: %u\n", err);
-        return err;
-    }
-    printf("Connected to target\n");
-
-    err = esp_loader_change_baudrate(HIGHER_BAUD_RATE);
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Unable to change baud rate on target.");
-        return err;
-    }
-
-    err = loader_port_change_baudrate(HIGHER_BAUD_RATE);
-    if (err != ESP_LOADER_SUCCESS) {
-        printf("Unable to change baud rate.");
-        return err;
-    }
-    printf("Baudrate changed\n");
-
-    return HAL_OK;
-}
-
-void flash_images()
-{
-    if(connect_to_target() == HAL_OK) {
+    
+    if (connect_to_target(HIGHER_BAUDRATE) == ESP_LOADER_SUCCESS) {
         flash_binary(bootloader_bin, bootloader_bin_size, BOOTLOADER_ADDRESS);
         flash_binary(bootloader_bin, bootloader_bin_size, BOOTLOADER_ADDRESS);
         flash_binary(partition_table_bin, partition_table_bin_size, PARTITION_ADDRESS);
         flash_binary(partition_table_bin, partition_table_bin_size, PARTITION_ADDRESS);
         flash_binary(hello_world_bin, hello_world_bin_size, APPLICATION_ADDRESS);
         flash_binary(hello_world_bin, hello_world_bin_size, APPLICATION_ADDRESS);
     }
     }
-}
-
-
-int main(void)
-{
-  HAL_Init();
-  SystemClock_Config();
-  MX_GPIO_Init();
-  MX_USART1_UART_Init();
-  MX_USART2_UART_Init();
 
 
-  flash_images();
-  while (1) { }
+    while (1) { }
 }
 }
 
 
 
 
 void SystemClock_Config(void)
 void SystemClock_Config(void)
 {
 {
-  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
-  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
-
-  /** Configure the main internal regulator output voltage 
-  */
-  __HAL_RCC_PWR_CLK_ENABLE();
-  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
-  /** Initializes the CPU, AHB and APB busses clocks 
-  */
-  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
-  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
-  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
-  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
-  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
-  {
-    Error_Handler();
-  }
-  /** Initializes the CPU, AHB and APB busses clocks 
-  */
-  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
-                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
-  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
-  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
-  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
-  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-
-  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
-  {
-    Error_Handler();
-  }
+    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+
+    /** Configure the main internal regulator output voltage
+    */
+    __HAL_RCC_PWR_CLK_ENABLE();
+    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+    /** Initializes the CPU, AHB and APB busses clocks
+    */
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
+    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
+        Error_Handler();
+    }
+    /** Initializes the CPU, AHB and APB busses clocks
+    */
+    RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
+                                  | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
+    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
+    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+
+    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) {
+        Error_Handler();
+    }
 }
 }
 
 
 static void MX_USART1_UART_Init(void)
 static void MX_USART1_UART_Init(void)
 {
 {
-  huart1.Instance = USART1;
-  huart1.Init.BaudRate = 115200;
-  huart1.Init.WordLength = UART_WORDLENGTH_8B;
-  huart1.Init.StopBits = UART_STOPBITS_1;
-  huart1.Init.Parity = UART_PARITY_NONE;
-  huart1.Init.Mode = UART_MODE_TX_RX;
-  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
-  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
-  if (HAL_UART_Init(&huart1) != HAL_OK)
-  {
-    Error_Handler();
-  }
+    huart1.Instance = USART1;
+    huart1.Init.BaudRate = 115200;
+    huart1.Init.WordLength = UART_WORDLENGTH_8B;
+    huart1.Init.StopBits = UART_STOPBITS_1;
+    huart1.Init.Parity = UART_PARITY_NONE;
+    huart1.Init.Mode = UART_MODE_TX_RX;
+    huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+    huart1.Init.OverSampling = UART_OVERSAMPLING_16;
+    if (HAL_UART_Init(&huart1) != HAL_OK) {
+        Error_Handler();
+    }
 }
 }
 
 
 static void MX_USART2_UART_Init(void)
 static void MX_USART2_UART_Init(void)
 {
 {
-  huart2.Instance = USART2;
-  huart2.Init.BaudRate = 115200;
-  huart2.Init.WordLength = UART_WORDLENGTH_8B;
-  huart2.Init.StopBits = UART_STOPBITS_1;
-  huart2.Init.Parity = UART_PARITY_NONE;
-  huart2.Init.Mode = UART_MODE_TX_RX;
-  huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
-  huart2.Init.OverSampling = UART_OVERSAMPLING_16;
-  if (HAL_UART_Init(&huart2) != HAL_OK)
-  {
-    Error_Handler();
-  }
+    huart2.Instance = USART2;
+    huart2.Init.BaudRate = 115200;
+    huart2.Init.WordLength = UART_WORDLENGTH_8B;
+    huart2.Init.StopBits = UART_STOPBITS_1;
+    huart2.Init.Parity = UART_PARITY_NONE;
+    huart2.Init.Mode = UART_MODE_TX_RX;
+    huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
+    huart2.Init.OverSampling = UART_OVERSAMPLING_16;
+    if (HAL_UART_Init(&huart2) != HAL_OK) {
+        Error_Handler();
+    }
 }
 }
 
 
 static void MX_GPIO_Init(void)
 static void MX_GPIO_Init(void)
 {
 {
-  GPIO_InitTypeDef GPIO_InitStruct = {0};
+    GPIO_InitTypeDef GPIO_InitStruct = {0};
 
 
-  /* GPIO Ports Clock Enable */
-  __HAL_RCC_GPIOD_CLK_ENABLE();
-  __HAL_RCC_GPIOB_CLK_ENABLE();
+    /* GPIO Ports Clock Enable */
+    __HAL_RCC_GPIOD_CLK_ENABLE();
+    __HAL_RCC_GPIOB_CLK_ENABLE();
 
 
-  /*Configure GPIO pin Output Level */
-  HAL_GPIO_WritePin(GPIOD, GREEN_LED_Pin|ORANGE_LED_Pin|RED_LED_Pin|BLUE_LED_Pin, GPIO_PIN_RESET);
+    /*Configure GPIO pin Output Level */
+    HAL_GPIO_WritePin(GPIOD, GREEN_LED_Pin | ORANGE_LED_Pin | RED_LED_Pin | BLUE_LED_Pin, GPIO_PIN_RESET);
 
 
-  /*Configure GPIO pin Output Level */
-  HAL_GPIO_WritePin(GPIOB, TARGET_RST_Pin|TARGET_IO0_Pin, GPIO_PIN_RESET);
+    /*Configure GPIO pin Output Level */
+    HAL_GPIO_WritePin(GPIOB, TARGET_RST_Pin | TARGET_IO0_Pin, GPIO_PIN_RESET);
 
 
-  /*Configure GPIO pins : GREEN_LED_Pin ORANGE_LED_Pin RED_LED_Pin BLUE_LED_Pin */
-  GPIO_InitStruct.Pin = GREEN_LED_Pin|ORANGE_LED_Pin|RED_LED_Pin|BLUE_LED_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
+    /*Configure GPIO pins : GREEN_LED_Pin ORANGE_LED_Pin RED_LED_Pin BLUE_LED_Pin */
+    GPIO_InitStruct.Pin = GREEN_LED_Pin | ORANGE_LED_Pin | RED_LED_Pin | BLUE_LED_Pin;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
 
 
-  /*Configure GPIO pins : PB4 PB5 */
-  GPIO_InitStruct.Pin = TARGET_RST_Pin|TARGET_IO0_Pin;
-  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-  GPIO_InitStruct.Pull = GPIO_NOPULL;
-  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
-  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
+    /*Configure GPIO pins : PB4 PB5 */
+    GPIO_InitStruct.Pin = TARGET_RST_Pin | TARGET_IO0_Pin;
+    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
+    GPIO_InitStruct.Pull = GPIO_NOPULL;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
+    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
 
 
 }
 }
 
 
@@ -252,7 +160,7 @@ static void MX_GPIO_Init(void)
   */
   */
 void Error_Handler(void)
 void Error_Handler(void)
 {
 {
-  /* User can add his own implementation to report the HAL error return state */
+    /* User can add his own implementation to report the HAL error return state */
 }
 }
 
 
 #ifdef  USE_FULL_ASSERT
 #ifdef  USE_FULL_ASSERT
@@ -264,9 +172,9 @@ void Error_Handler(void)
   * @retval None
   * @retval None
   */
   */
 void assert_failed(uint8_t *file, uint32_t line)
 void assert_failed(uint8_t *file, uint32_t line)
-{ 
-  /* User can add his own implementation to report the file name and line number,
-     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+{
+    /* User can add his own implementation to report the file name and line number,
+       tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
 }
 }
 #endif /* USE_FULL_ASSERT */
 #endif /* USE_FULL_ASSERT */
 
 

BIN
examples/stm32_example/images/bootloader.bin


BIN
examples/stm32_example/images/hello-world.bin


BIN
examples/stm32_example/images/partition-table.bin


+ 1 - 0
port/esp32_port.c

@@ -145,6 +145,7 @@ void loader_port_enter_bootloader(void)
 {
 {
     gpio_set_level(s_gpio0_trigger_pin, 0);
     gpio_set_level(s_gpio0_trigger_pin, 0);
     gpio_set_level(s_reset_trigger_pin, 0);
     gpio_set_level(s_reset_trigger_pin, 0);
+    loader_port_delay_ms(50);
     gpio_set_level(s_reset_trigger_pin, 1);
     gpio_set_level(s_reset_trigger_pin, 1);
     loader_port_delay_ms(50);
     loader_port_delay_ms(50);
     gpio_set_level(s_gpio0_trigger_pin, 1);
     gpio_set_level(s_gpio0_trigger_pin, 1);

+ 4 - 4
port/raspberry_port.c

@@ -207,10 +207,10 @@ static esp_loader_error_t read_data(char *buffer, uint32_t size)
     return ESP_LOADER_SUCCESS;
     return ESP_LOADER_SUCCESS;
 }
 }
 
 
-esp_loader_error_t loader_port_rpi_init(const char *device,
-                                        uint32_t baudrate,
-                                        uint32_t reset_trigger_pin,
-                                        uint32_t gpio0_trigger_pin)
+esp_loader_error_t loader_port_raspberry_init(const char *device,
+                                              uint32_t baudrate,
+                                              uint32_t reset_trigger_pin,
+                                              uint32_t gpio0_trigger_pin)
 {
 {
     s_reset_trigger_pin = reset_trigger_pin;
     s_reset_trigger_pin = reset_trigger_pin;
     s_gpio0_trigger_pin = gpio0_trigger_pin;
     s_gpio0_trigger_pin = gpio0_trigger_pin;

+ 2 - 3
src/esp_loader.c

@@ -293,7 +293,7 @@ static esp_loader_error_t detect_flash_size(size_t *flash_size)
     RETURN_ON_ERROR( spi_flash_command(SPI_FLASH_READ_ID, NULL, 0, &flash_id, 24) );
     RETURN_ON_ERROR( spi_flash_command(SPI_FLASH_READ_ID, NULL, 0, &flash_id, 24) );
     uint32_t size_id = flash_id >> 16;
     uint32_t size_id = flash_id >> 16;
 
 
-    if (size_id < 0x12 && size_id > 0x18) {
+    if (size_id < 0x12 || size_id > 0x18) {
         return ESP_LOADER_ERROR_UNSUPPORTED_CHIP;
         return ESP_LOADER_ERROR_UNSUPPORTED_CHIP;
     }
     }
 
 
@@ -302,13 +302,12 @@ static esp_loader_error_t detect_flash_size(size_t *flash_size)
     return ESP_LOADER_SUCCESS;
     return ESP_LOADER_SUCCESS;
 }
 }
 
 
-
 esp_loader_error_t esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size)
 esp_loader_error_t esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size)
 {
 {
     uint32_t blocks_to_write = (image_size + block_size - 1) / block_size;
     uint32_t blocks_to_write = (image_size + block_size - 1) / block_size;
     uint32_t erase_size = block_size * blocks_to_write;
     uint32_t erase_size = block_size * blocks_to_write;
     s_flash_write_size = block_size;
     s_flash_write_size = block_size;
-    size_t flash_size;
+    size_t flash_size = 0;
 
 
     if (detect_flash_size(&flash_size) == ESP_LOADER_SUCCESS) {
     if (detect_flash_size(&flash_size) == ESP_LOADER_SUCCESS) {
         if (image_size > flash_size) {
         if (image_size > flash_size) {