OPTA Upload program from USB memory stick

Hello,

I’m having an issue uploading a program from a USB drive. I have two OPTA WiFi controllers – one manufactured by Finder, the other by Arduino (I assume this based on their FCC IDs). The target program (.OTA file) is located on the appropriate partition of the USB drive, and the controllers are loaded with the StepByStepUpdate program from the OptaUSBUpdate library examples.

Here’s what I noticed:

  • On the Arduino controller, the upload process completes successfully.
  • On the Finder controller, the upload process fails at Step 4 (blink(LED_D3)).

Both controllers are tested under the exact same conditions with identical programs.

Additionally, I tested the logging feature to write logs to the USB drive – it works correctly and identically on both controllers.

Has anyone encountered a similar issue? Any ideas on what might be causing the difference?

Code i'm using:

#include <OptaUSBUpdate.h>

void setup()
{
    Serial.begin(9600);
}

void loop()
{
    if (digitalRead(BTN_USER) == LOW)
    {
        // Button should be pressed for at least 2 seconds, then released.
        unsigned long now = millis();
        while (digitalRead(BTN_USER) == LOW) {
            delay(1);
            if (millis() - now > 2000) {
                digitalWrite(LED_D0, HIGH);
                digitalWrite(LED_D1, HIGH);
                digitalWrite(LED_D2, HIGH);
                digitalWrite(LED_D3, HIGH);
            }
        }
        if (millis() - now > 2000) {
            digitalWrite(LED_D0, LOW);
            digitalWrite(LED_D1, LOW);
            digitalWrite(LED_D2, LOW);
            digitalWrite(LED_D3, LOW);
            doUSBUpdate();
        }
    }
}

void doUSBUpdate()
{
    OptaUSBUpdate_QSPI update(QSPI_FLASH_FATFS_MBR, 2);
    OptaUSBUpdate::Error update_error = OptaUSBUpdate::Error::None;

    Serial.println("Starting firmware update from USB storage");

    digitalWrite(LED_D0, HIGH);
    if ((update_error = update.begin()) != OptaUSBUpdate::Error::None)
    {
        Serial.println("[ERROR] USB update error: " + String((int)update_error));
        blink(LED_D0);
    }

    digitalWrite(LED_D1, HIGH);
    if ((update_error = update.mount()) != OptaUSBUpdate::Error::None)
    {
        Serial.println("[ERROR] USB update error: " + String((int)update_error));
        blink(LED_D1);
    }

    digitalWrite(LED_D2, HIGH);
    if ((update_error = update.decompress("ADR1.OTA")) != OptaUSBUpdate::Error::None)
    {
        Serial.println("[ERROR] USB update error: " + String((int)update_error));
        blink(LED_D2);
    }

    digitalWrite(LED_D3, HIGH);
    if ((update_error = update.update()) != OptaUSBUpdate::Error::None)
    {
        Serial.println("[ERROR] USB update error: " + String((int)update_error));
        blink(LED_D3);
    }

    delay(1000);

    digitalWrite(LED_D0, LOW);
    digitalWrite(LED_D1, LOW);
    digitalWrite(LED_D2, LOW);
    digitalWrite(LED_D3, LOW);

    delay(1000);

    digitalWrite(LED_D0, HIGH);
    digitalWrite(LED_D1, HIGH);
    digitalWrite(LED_D2, HIGH);
    digitalWrite(LED_D3, HIGH);

    delay(1000);

    update.reset();
}

void blink(unsigned int led)
{
    while (true) {
        digitalWrite(led, LOW);
        delay(250);
        digitalWrite(led, HIGH);
        delay(250);
    }
}

Hi @darrag212 I'm using a GIGA and the Portenta_OTA library so not the same, however they look similar enough for me to suggest it may be the MAGIC in https://github.com/dndg/OptaUSBUpdate/blob/main/src/OptaUSBUpdate_Config.h

Each board seems to have a different value, maybe this Finder controller needs something different. For example, the Portenta_OTA config file has these boards and their MAGIC

#if defined(ARDUINO_PORTENTA_H7_M7)
  #define ARDUINO_PORTENTA_OTA_MAGIC 0x2341025b
  #define ARDUINO_PORTENTA_OTA_SDMMC_SUPPORT
  #define ARDUINO_PORTENTA_OTA_QSPI_SUPPORT
#endif

#if defined(ARDUINO_NICLA_VISION)
  #define ARDUINO_PORTENTA_OTA_MAGIC 0x2341025f
  #define ARDUINO_PORTENTA_OTA_QSPI_SUPPORT
#endif

#if defined(ARDUINO_OPTA)
  #define ARDUINO_PORTENTA_OTA_MAGIC 0x23410064
  #define ARDUINO_PORTENTA_OTA_QSPI_SUPPORT
#endif

#if defined(ARDUINO_GIGA)
  #define ARDUINO_PORTENTA_OTA_MAGIC 0x23410266
  #define ARDUINO_PORTENTA_OTA_QSPI_SUPPORT
#endif

p.s. I've no idea what they're used for (it's all like magic to me)

1 Like

Hi steve9, thanks for advice, I'll check that after weekend.

I use a similar thing when generating an .OTA file (it's required by the bin2ota.py file), where I have to specify the parameter as OPTA. Unfortunately, as far as I know, it's not possible to define this more precisely.

As for MAGIC, if you're using the latest version of the Arduino IDE, you can navigate to its definition by right-clicking on the element you're interested in.