1/*
2  Copyright (c) 2020 Arduino LLC.  All right reserved.
3
4  This library is free software; you can redistribute it and/or
5  modify it under the terms of the GNU Lesser General Public
6  License as published by the Free Software Foundation; either
7  version 2.1 of the License, or (at your option) any later version.
8
9  This library is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12  See the GNU Lesser General Public License for more details.
13
14  You should have received a copy of the GNU Lesser General Public
15  License along with this library; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
17*/
18
19/**************************************************************************************
20   INCLUDE
21 **************************************************************************************/
22
23#include <FlashStorage.h>
24#include "MKRGSM.h"
25
26/**************************************************************************************
27   DEFINE
28 **************************************************************************************/
29
30#define SSU_START    0x2000
31#define SSU_SIZE     0x8000
32
33#define SKETCH_START (uint32_t*)(SSU_START + SSU_SIZE)
34
35/**************************************************************************************
36   GLOBAL CONSTANTS
37 **************************************************************************************/
38
39static char const UPDATE_FILE_NAME[] = "UPDATE.BIN";
40
41/**************************************************************************************
42   GLOBAL VARIABLES
43 **************************************************************************************/
44
45FlashClass mcu_flash;
46GSMFileUtils  fileUtils(false);
47/**************************************************************************************
48   FUNCTION DECLARATION
49 **************************************************************************************/
50
51extern "C" void __libc_init_array(void);
52
53/**************************************************************************************
54   MAIN
55 **************************************************************************************/
56
57int main()
58{
59  init();
60
61  __libc_init_array();
62
63  delay(1);
64
65  String filename = UPDATE_FILE_NAME;
66
67  const size_t  blockSize = 512;
68
69  MODEM.begin();
70  fileUtils.begin();
71  bool update_success = false;
72  if (fileUtils.listFile("UPDATE.OK") == 1) {
73    auto size = fileUtils.listFile(filename);
74    auto cycles = (size / blockSize) + 1;
75    if (size > SSU_SIZE) {
76      size -= SSU_SIZE;
77
78      /* Erase the MCU flash */
79      uint32_t flash_address = (uint32_t)SKETCH_START;
80      mcu_flash.erase((void*)flash_address, size);
81
82      for (auto i = 0; i < cycles; i++) {
83        uint8_t block[blockSize] { 0 };
84        digitalWrite(LED_BUILTIN,LOW);
85        auto read = fileUtils.readBlock(filename, (i * blockSize) + SSU_SIZE, blockSize, block);
86        digitalWrite(LED_BUILTIN,HIGH);
87        mcu_flash.write((void*)flash_address, block, read);
88        flash_address += read;
89      }
90      update_success = true;
91    }
92    if (update_success) {
93      fileUtils.deleteFile(filename);
94      fileUtils.deleteFile("UPDATE.OK");
95    }
96  }
97  /* Jump to the sketch */
98  __set_MSP(*SKETCH_START);
99
100  /* Reset vector table address */
101  SCB->VTOR = ((uint32_t)(SKETCH_START) & SCB_VTOR_TBLOFF_Msk);
102
103  /* Address of Reset_Handler is written by the linker at the beginning of the .text section (see linker script) */
104  uint32_t resetHandlerAddress = (uint32_t) * (SKETCH_START + 1);
105  /* Jump to reset handler */
106  asm("bx %0"::"r"(resetHandlerAddress));
107}
108