cancel
Showing results for 
Search instead for 
Did you mean: 

OTA IN STM32U575 USING ESP32

premkumar
Associate II

IS ANY BODY HELP ME IN THE OTA OF THE STM32U575 USING THE ESP32

1. HOW TO SETUP THE SYSTEM BOOTLOADER TO RECEIVE THE FIRMWARE (.BIN FILE) VIA UART AND HOW TO SELECT WHICH UART TO USE FOR UPLOAD , THERE ARE MORE UART WHICH SUPPORT THE UART FLASHING HOW TO ACTIVATE THE DESIRED UART FOR THE FIRMWARE UPLOAD

2. PLEASE SHARE ME ANR RESOUSE REGARDING SYSTEM BOOTLOADER CONFIGURATIONS

3. PLEASE SHARE ANY ESP32 FIRMWARE TRANSMIT THE BINARY FILE VIA UART

8 REPLIES 8

Welcome to the forum.

PLEASE DON'T WRITE THE WHOLE POST IN ALL CAPITALS!

 

https://community.st.com/t5/stm32-mcus-products/how-can-i-use-an-esp32-to-update-the-firmware-of-an-stm32-from/m-p/696241

 

https://community.st.com/t5/stm32-mcus-embedded-software/stm32g0b1ret6-fota-update-through-uart/m-p/790490

 

A complex system that works is invariably found to have evolved from a simple system that worked.
A complex system designed from scratch never works and cannot be patched up to make it work.

sorry for that
in stm32u575

              Will you help me ,how the system bootloader works , how to activate that and how to receive the firmware via usart and selecting the uart for the firmware is ther any configuration  

AN2606 describes the pins involved. Shows the UART Rx pins. You send an 0x7F data pattern at baud rate with 8E1 format for it to auto baud.

AN3155 describes the protocol after you reset with BOOT0  HIGH.

See examples on Arduino MKR WAN1300 Github 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
13:58:55.004 -> [BOOT] Initializing bootloader...
13:58:55.069 -> [NACK] Received
13:58:55.069 -> [BOOT] Failed to sync with STM32 bootloader

what may be the reason for this @Tesla DeLorean @Andrew Neil  for , i am receiving this the above blocks.

NACK receved after sending the 0x7F is it the right command to init the bootloader.

Seeing these messages in WHAT?

The 0x7F at 8E1 is a one-shot deal. You reset the STM32 into the System Loader and first talking interface wins. Watch for modem or GNSS that squawk at startup.

To try again you must reset. You don't get a second chance.

ie you send 0x7F and get an 0x79 back, or you don't. 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Hi @Tesla DeLorean ,

Now the Problem got updated , I am received the 0x79 back , the binary file only not get updated what may be the reason

premkumar_0-1745304471600.png

You seem to have a communications problem.

You'll need to explain how you have this set up, and what exactly you're doing.

Log suggests you're doing an Erase and Go/Jump operation, but you've provided zero actual detail of your system or interactions with it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

premkumar_0-1745405456963.png

this was my hardware setup @Tesla DeLorean manually controlling the boot pin.

what my condition was i am initialized the bootloader receving the ack 0x79 for that , but the write operation and erase is not done. every time i checked with the cube programmer nothing is erased and written in new. this was my current condition

this was my code:-

#include <WiFi.h>
#include <WebServer.h>
#include <LittleFS.h>

#define WIFI_SSID     "Hotspot"
#define WIFI_PASSWORD "12341234"

#define UART_PORT     Serial2
#define STM32_BAUDRATE 115200
#define STM32_RX      16
#define STM32_TX      17

#define STM32_ACK     0x79
#define STM32_NACK    0x1F
#define STM32_INIT    0x7F

WebServer server(80);
uint8_t packet[100];
uint32_t currentAddress = 0x08000000;

const char* serverIndex = R"rawliteral(
<!DOCTYPE HTML><html>
<head><title>STM32 FOTA</title><meta name="viewport" content="width=device-width, initial-scale=1"></head>
<body><h2>STM32 Firmware Upload</h2>
<form method='POST' action='/update' enctype='multipart/form-data' id='upload_form'>
<input type='file' name='update' accept='.bin'><input type='submit' value='Upload'></form>
<div id='prg'>Progress: 0%</div>
<script>
document.getElementById('upload_form').onsubmit = function(e) {
  e.preventDefault();
  var form = document.getElementById('upload_form');
  var data = new FormData(form);
  var xhr = new XMLHttpRequest();
  xhr.open('POST', '/update', true);
  xhr.upload.onprogress = function(e) {
    if (e.lengthComputable) {
      var percentComplete = (e.loaded / e.total) * 100;
      document.getElementById('prg').innerHTML = 'Progress: ' + Math.round(percentComplete) + '%';
    }
  };
  xhr.onload = function() {
    alert(xhr.status === 200 ? 'Upload successful' : 'Upload failed');
  };
  xhr.send(data);
};
</script></body></html>
)rawliteral";

void setup() {
  Serial.begin(115200);
  UART_PORT.begin(STM32_BAUDRATE, SERIAL_8E1, STM32_RX, STM32_TX);
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  while (WiFi.status() != WL_CONNECTED) {
    delay(300);
    Serial.print(".");
  }
  Serial.println("\nConnected! IP: " + WiFi.localIP().toString());

  LittleFS.begin();

  server.on("/", HTTP_GET, []() {
    server.send(200, "text/html", serverIndex);
  });

  server.on("/update", HTTP_POST, []() {
    server.send(200, "text/plain", "Upload Complete");
  }, []() {
    HTTPUpload& upload = server.upload();
    if (upload.status == UPLOAD_FILE_START) {
      Serial.println("[BOOT] Initializing bootloader...");
      currentAddress = 0x08000000; // reset address for new upload
      if (!stm32InitBootloader()) {
        Serial.println("[BOOT] Failed to sync with STM32 bootloader");
        return;
      }
      Send_CMD_Erase_Flash();
    } else if (upload.status == UPLOAD_FILE_WRITE) {
      SendBinaryToSTM32(upload.buf, upload.currentSize, currentAddress);
      currentAddress += upload.currentSize;
    } else if (upload.status == UPLOAD_FILE_END) {
      Send_CMD_Jump_To_Application();
    }
  });

  server.begin();
}

void loop() {
  server.handleClient();
}

bool waitForAck(uint32_t timeout = 1000) {
  unsigned long start = millis();
  while (millis() - start < timeout) {
    if (UART_PORT.available()) {
      uint8_t b = UART_PORT.read();
      if (b == STM32_ACK) {
        Serial.println("[ACK] Received");
        return true;
      } else if (b == STM32_NACK) {
        Serial.println("[NACK] Received");
        return false;
      }
    }
  }
  Serial.println("[TIMEOUT] No ACK/NACK received");
  return false;
}

bool stm32InitBootloader() {
  UART_PORT.write(STM32_INIT);
  UART_PORT.flush();
  return waitForAck();
}

void Send_CMD_Erase_Flash() {
  Serial.println("[CMD] Sending Erase Flash");
  packet[0] = 0x43;
  packet[1] = ~packet[0];
  UART_PORT.write(packet, 2);
  if (!waitForAck()) return;

  packet[0] = 0xFF; // N = 0xFF means global erase
  packet[1] = 0x00; // XOR = 0xFF
  UART_PORT.write(packet, 2);
  waitForAck();
}

void Send_CMD_Jump_To_Application() {
  Serial.println("[CMD] Jump to application");
  packet[0] = 0x21;
  packet[1] = ~packet[0];
  UART_PORT.write(packet, 2);
  waitForAck();
}

void SendBinaryToSTM32(uint8_t* data, size_t len, uint32_t address) {
  if (!data || len == 0 || len > 256) return;

  Serial.printf("[WRITE] Sending %d bytes to 0x%08X\n", len, address);

  // Send Write Memory command
  packet[0] = 0x31;
  packet[1] = ~packet[0];
  UART_PORT.write(packet, 2);
  if (!waitForAck()) return;

  // Send address
  uint8_t addr[5];
  addr[0] = (address >> 24) & 0xFF;
  addr[1] = (address >> 16) & 0xFF;
  addr[2] = (address >> 8)  & 0xFF;
  addr[3] = address & 0xFF;
  addr[4] = addr[0] ^ addr[1] ^ addr[2] ^ addr[3]; // checksum
  UART_PORT.write(addr, 5);
  if (!waitForAck()) return;

  // Send data
  uint8_t length = len - 1;
  uint8_t checksum = length;
  UART_PORT.write(length);

  for (size_t i = 0; i < len; i++) {
    UART_PORT.write(data[i]);
    checksum ^= data[i];
  }

  UART_PORT.write(checksum);
  waitForAck();
}