Update sketch OTA on Arduino MKR1000

Hello!!

I am trying to update a sketch OTA a MKR1000 from inside the sketch. I'm using the IoT platform thethings.io. It detects correctly when there is a new version available and the sketch downloads it and theoretically it gets written to the flash memory. But then, after rebooting, the same code as before gets executed, nothing changed.
I basically copied the function that writes to the flash memory from here: Arduino-FlowerOTA/FlowerOTA.h at master · flower-platform/Arduino-FlowerOTA · GitHub

Before I put the code here, my first question would, is it possible? Can overwrite the sketch on the MKR1000 and then reboot?

Thank you!!

Hello,

So, the method I use is basically use the funtion I post… It writes the downloaded code to flash memory and then I use NVIC_SystemReset(); // equivalent to this:  *((uint32_t*) 0xE000ED0C) = (uint32_t) 0x05FA0004; to reset the MKR1000. But the same code as before gets executed and not the new one… I would like to know if this is possible with the MKR1000 without writing a custom boards file and/or bootloader, etc…?

Thank you very much!

This is the function.

/**
   * This code is based on the Arduino bootloader code for writing into flash memory.
   */
  void flashWrite(const volatile void* address, const volatile void* data, uint32_t size) {
    const uint32_t pageSizes[] = { 8, 16, 32, 64, 128, 256, 512, 1024 };
    const uint32_t PAGE_SIZE = pageSizes[NVMCTRL->PARAM.bit.PSZ];
    const uint32_t ROW_SIZE = PAGE_SIZE * 4;
//      const uint32_t NUM_PAGES = NVMCTRL->PARAM.bit.NVMP;

    size = (size + 3) / 4; // size <-- number of 32-bit integers
    volatile uint32_t* src_addr = (volatile uint32_t*) data;
    volatile uint32_t* dst_addr = (volatile uint32_t*) address;

    // Disable automatic page write
    NVMCTRL->CTRLB.bit.MANW = 1;

    // Do writes in pages
    while (size) {
      // if we are at the beginning of a row, erase it first
      if (((uint32_t) dst_addr & (ROW_SIZE - 1)) == 0) {
        NVMCTRL->ADDR.reg = ((uint32_t) dst_addr) / 2;
        NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY
            | NVMCTRL_CTRLA_CMD_ER;
        while (!NVMCTRL->INTFLAG.bit.READY) {
        }
      }

      // Execute "PBC" Page Buffer Clear
      NVMCTRL->CTRLA.reg =
          NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_PBC;
      while (NVMCTRL->INTFLAG.bit.READY == 0) {
      }

      // Fill page buffer
      uint32_t i;
      for (i = 0; i < (PAGE_SIZE / 4) && size; i++) {
        *dst_addr = *src_addr;
        src_addr++;
        dst_addr++;
        size--;
      }

      // Execute "WP" Write Page
      NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP;
      while (NVMCTRL->INTFLAG.bit.READY == 0) {
      }
    }
  }