ESP8266 programming ATmega1284p via serial (Nixie Clock)

Hi everyone,
i've built my own nixie clock with Atmega1284p, programming in Bascom. Everything is working fine. I also have on the same board ESP8266 and using it to get time and making a webserver for the clock (displaying some information).
I tried to upload a *.hex file to ESP8266 a write it to Atmega over serial using Optiboot (optiboot_flash_atmega1284p_UART0_115200_16000000L_B0_BIGBOOT)
As i've found in documentation i use these procedures to write it:

void handleFileUpload() {
  HTTPUpload& upload = server.upload();
  if (upload.status == UPLOAD_FILE_START) {
    String filename = "/" + upload.filename;
    if (!filename.startsWith("/")) filename = "/" + filename;
    fsUploadFile = LittleFS.open(filename, "w");
    uploadStatus = "Uploading file: " + filename;
  } else if (upload.status == UPLOAD_FILE_WRITE) {
    if (fsUploadFile) fsUploadFile.write(upload.buf, upload.currentSize);
  } else if (upload.status == UPLOAD_FILE_END) {
    if (fsUploadFile) fsUploadFile.close();
    uploadStatus += "File Uploaded: " + upload.filename;
    uploadToBootloader(upload.filename); // Spustíme nahrávání do bootloaderu
    server.send(200, "text/plain", uploadStatus);
  } else {
    server.send(500, "text/plain", "File upload failed");
  }
}

void uploadToBootloader(String filename) {
    File file = LittleFS.open("/" + filename, "r");
  if (!file) {
    uploadStatus = "Failed to open file for reading";
    return;
  }
  resetATmega();

  if (!syncWithBootloader()) {
    uploadStatus += "Failed to sync with bootloader";
    return;
  }

  // Enter programming mode
  sendByte(0x50); // STK_ENTER_PROGMODE
  sendByte(0x20); // CRC_EOP
  if (!waitForAck()) {
    uploadStatus = "Failed to enter programming mode";
    return;
  }

  uploadStatus += "\nUploading to bootloader...";
  int baseAddress = 0;
  int segmentAddress = 0;
 
  while (file.available()) {
   
    String line = file.readStringUntil('\n');
    if (line[0] != ':') continue;

 int byteCount = strtol(line.substring(1, 3).c_str(), nullptr, 16);
int address = strtol(line.substring(3, 7).c_str(), nullptr, 16);
int recordType = strtol(line.substring(7, 9).c_str(), nullptr, 16);
String data = line.substring(9, 9 + byteCount * 2);
int checksum = strtol(line.substring(9 + byteCount * 2, 9 + byteCount * 2 + 2).c_str(), nullptr, 16);


    if (!validateChecksum(line)) {
      uploadStatus += "\nChecksum validation failed";
      return;
    }

    switch (recordType) {
      case 0x00: { // Data record
        int fullAddress = (segmentAddress << 4) + address;
        if (!setAddress(fullAddress)) {
          uploadStatus += "\nFailed to set address at: 0x" + String(fullAddress, HEX);
          return;
        }

        uint8_t page[byteCount];
        for (int i = 0; i < byteCount; i++) {
          page[i] = strtol(data.substring(i * 2, i * 2 + 2).c_str(), nullptr, 16);
        }

        if (!writePage(page, byteCount)) {
          uploadStatus += "\nFailed to write page at: 0x" + String(fullAddress, HEX);
          return;
        }
        break;
      }
      case 0x02: { // Extended Segment Address Record
        segmentAddress = strtol(data.c_str(), nullptr, 16);
        break;
      }
      case 0x04: { // Extended Linear Address Record
        baseAddress = strtol(data.c_str(), nullptr, 16) << 16;
        break;
      }
      case 0x01: { // End Of File record
        leaveProgramMode();
        uploadStatus += "\nUpload complete";
        file.close();
        return;
      }
    }
  }

  // leaveProgramMode();
  // uploadStatus += "\nUpload complete";
  // file.close();
}

bool validateChecksum(const String &line) {
  int sum = 0;
  for (int i = 1; i < line.length() - 1; i += 2) {
    sum += strtol(line.substring(i, i + 2).c_str(), nullptr, 16);
  }
  return (sum & 0xFF) == 0;
}

void resetATmega() {
  
  digitalWrite(ATMEGA_RESET_PIN, LOW);
  delay(1000);
  digitalWrite(ATMEGA_RESET_PIN, HIGH);
  uploadStatus += "\nATMega reset";
}



bool syncWithBootloader() {
  // Pošle několik synchronizačních bajtů a čeká na odpověď
  uploadStatus += "\nSynchronizing with bootloader...";
  for (int i = 0; i < 5; i++) {
    sendByte(0x30); // STK_GET_SYNC
    sendByte(0x20); // Sync command
    if (waitForAck()) {
      uploadStatus += "\nSync successful";
      return true;
    }
    delay(100);
  }
  uploadStatus += "\nSync failed";
  return false;
}

bool setAddress(int address) {
  //uploadStatus += "\nSetting address to: 0x" + String(address, HEX);
  sendByte(0x55); // STK_LOAD_ADDRESS
  sendByte(address & 0xFF); // Address LSB
  sendByte((address >> 8) & 0xFF); // Address MSB
  sendByte(0x20); // CRC_EOP
  
  // Podrobnější kontrola odezvy
  if (waitForAck()) {
    //uploadStatus += " Addr set to 0x" + String(address, HEX);
    return true;
  } else {
    uploadStatus += "\nFailed to set address to 0x" + String(address, HEX);
    return false;
  }
}

bool writePage(uint8_t* page, int size) {
  sendByte(0x64); // STK_PROG_PAGE
  sendByte((size >> 8) & 0xFF); // Size high byte
  sendByte(size & 0xFF); // Size low byte
  sendByte(0x46); // Flash memory type
  for (int i = 0; i < size; i++) {
    sendByte(page[i]);
  }
  sendByte(0x20); // CRC_EOP
  return waitForAck();
} 

void leaveProgramMode() {
  sendByte(0x51); // STK_LEAVE_PROGMODE
  sendByte(0x20); // CRC_EOP
  waitForAck();
}

void sendByte(uint8_t data) {
  Serial.write(data); // Použití Serial.write k odeslání surového bajtu
 //uploadStatus += "\nSent: 0x" + String(data, HEX); // Tiskne hexadecimální reprezentaci bajtu pro ladění
}



bool waitForAck() {
  unsigned long startTime = millis();
  bool gotInSync = false;
  
  while (millis() - startTime < 1000) {
    if (Serial.available()) {
      uint8_t response = Serial.read();
      //uploadStatus += "\nReceived: 0x" + String(response, HEX);
      
      if (response == 0x14) { // STK_INSYNC
        gotInSync = true;
      } else if (gotInSync && response == 0x10) { // STK_OK
        return true;
      } else {
        gotInSync = false; // Reset if unexpected byte is received
      }
    }
  }

  return false;
}

And i can't get it to work.
The output says it's ok and completed, but if i try to read Atmega using USBASP programmer, theres notihing there, only the bootloader.
Output after upload looks likde this.:

Uploading file: /hodiny.hexFile Uploaded: hodiny.hex
ATMega reset
Synchronizing with bootloader...
Sync successful
Uploading to bootloader...
Upload complete

Am I missing something?
Thanks for your answers a advice.

Vojta B.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.