Core IAP code. NOT TESTED.
authorNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 27 Sep 2016 21:11:00 +0000 (23:11 +0200)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 16:03:05 +0000 (17:03 +0100)
core/iap.c [new file with mode: 0644]
core/vector_table.c [new file with mode: 0644]
include/core/iap.h

diff --git a/core/iap.c b/core/iap.c
new file mode 100644 (file)
index 0000000..2a611fe
--- /dev/null
@@ -0,0 +1,107 @@
+/****************************************************************************
+ *   core/iap.c
+ *
+ *
+ * Copyright 2015 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This file is derived from Work covered by the Apache 2.0 licence.
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * Original sources should be found there :
+ *     https://github.com/mbedmicro/CMSIS-DAP.git
+ * Original file name is bootloader/hal/TARGET_NXP/TARGET_LPC11U35/flash_hal.c
+ *
+ * Original copyright notice :
+ *    CMSIS-DAP Interface Firmware
+ *    Copyright (c) 2009-2013 ARM Limited
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *****************************************************************************/
+
+#include "lib/stdint.h"
+#include "core/iap.h"
+
+
+/* IAP - In-Application Programming
+ * Driver for the IAP interface of the LPC122x.
+ * This interface allows In-Application programming of the internal flash memory of the LPC122x
+ *   microcontroller.
+ * Refer to LPC122x documentation (UM10441.pdf) for more information.
+ */
+
+static uint32_t get_sector_number(uint32_t addr)
+{
+       uint32_t sector = 0;
+
+       sector = addr >> 12;  /* 4kB Sector */
+       if (sector >= 0x10) {
+               sector = 0x0E + (sector >> 3); /* 32kB Sector */
+       }
+
+       return sector;
+}
+
+/* Erase one sector, given a flash address
+ * return 0 on success.
+ */
+int flash_hal_erase_sector(uint32_t addr)
+{
+       uint32_t sector = get_sector_number(addr);
+       int ret = 0;
+
+       /* Prepare sector for erase */
+       ret = iap_prepare_flash(sector, sector);
+       if (ret != IAP_STATUS_CMD_SUCCESS) {
+               return ret;
+       }
+       /* Erase sector */
+       return iap_erase_flash_sectors(sector, sector); 
+}
+
+/* Flash a binary image chunk to a sector. */
+int flash_hal_program_page(uint32_t addr, uint32_t size, unsigned char *buf)
+{
+       uint32_t sector = 0;
+       int ret = 0;
+
+       /* If this goes to the beginning of the Flash image, check that the image is valid. */
+       if (addr == 0) {
+               uint32_t crp = *((uint32_t *)(buf + CRP_ADDRESS));
+               uint32_t checksum = 0;
+
+               if (IS_CRP_VALUE(crp)) {
+                       /* CRP is enabled, exit. */
+                       return -1;
+               }
+
+               /* Compute a valid user code */
+               checksum = *((uint32_t *)(buf + 0x00)) + *((uint32_t *)(buf + 0x04)) +
+                                       *((uint32_t *)(buf + 0x08)) + *((uint32_t *)(buf + 0x0C)) +
+                                       *((uint32_t *)(buf + 0x10)) + *((uint32_t *)(buf + 0x14)) +
+                                       *((uint32_t *)(buf + 0x18));
+               *((uint32_t *)(buf + 0x1C)) = 0 - checksum;
+       }
+
+       sector = get_sector_number(addr);
+
+       /* Prepare sector for write */
+       ret = iap_prepare_flash(sector, sector);
+       if (ret != IAP_STATUS_CMD_SUCCESS) {
+               return ret;
+       }
+
+       /* FIXME : in original code, size was hardcoded to 1024 */
+       return iap_copy_ram_to_flash(addr, (uint32_t)buf, size);
+}
+
diff --git a/core/vector_table.c b/core/vector_table.c
new file mode 100644 (file)
index 0000000..b46bbc0
--- /dev/null
@@ -0,0 +1,59 @@
+/****************************************************************************
+ *   core/vector_table.c
+ *
+ *
+ * Copyright 2015 Nathael Pajani <nathael.pajani@ed3l.fr>
+ *
+ * This file is derived from Work covered by the Apache 2.0 licence.
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * Original sources should be found there :
+ *     https://github.com/mbedmicro/CMSIS-DAP.git
+ * Original file name is bootloader/hal/TARGET_NXP/TARGET_LPC11U35/vector_table.c
+ *
+ * Original copyright notice :
+ *    CMSIS-DAP Interface Firmware
+ *    Copyright (c) 2009-2013 ARM Limited
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ *****************************************************************************/
+
+/* This file holds the code related to the vector table relocation in RAM.
+ * This mechanism is used by the IAP code before re-programming the first sector of the internal
+ *   flash memory which usually holds the active vector table.
+ */
+
+#include "lib/stdint.h"
+#include "core/system.h"
+#include "core/iap.h"
+
+#define NVIC_NUM_VECTORS (16 + 32)            /* CORE + MCU Peripherals */
+#define NVIC_RAM_VECTOR_ADDRESS (0x10000000)  /* Vectors positioned at start of RAM */
+
+void relocate_vector_table(void)
+{
+       struct lpc_sys_config* sysctrl = LPC_SYS_CONFIG;
+    int i;
+    /* Space for dynamic vectors, initialised to allocate in R/W */
+    static volatile uint32_t * vectors = (uint32_t*)NVIC_RAM_VECTOR_ADDRESS;
+
+    /* Copy and switch to dynamic vectors if first time called */
+    if((sysctrl->sys_mem_remap & 0x3) != 0x1) {
+        uint32_t *old_vectors = (uint32_t *)START_APP_ADDRESS;
+        for(i = 0; i < NVIC_NUM_VECTORS; i++) {
+            vectors[i] = old_vectors[i];
+        }
+               sysctrl->sys_mem_remap = 0x1;
+    }
+}
index 5c6fa8f..ae760ce 100644 (file)
  *   of the micro-controller (for bootloaders, drivers, loadable RTOS tasks, ....)
  */
 
+#define START_APP_ADDRESS (0x5000)
+#define INITIAL_SP      (*(uint32_t *)(START_APP_ADDRESS))
+#define RESET_HANDLER   (*(uint32_t *)(START_APP_ADDRESS + 4))
+/* CRP Handling */
+#define CRP_ADDRESS    (0x000002FC)
+#define NO_ISP   (0x4E697370)
+#define CRP1     (0x12345678)
+#define CRP2     (0x87654321)
+#define CRP3     (0x43218765)
+#define IS_CRP_VALUE(v)  ((v==NO_ISP) || (v==CRP1) || (v==CRP2) || (v==CRP3))
+
+#define LPC12XX_SECTOR_SIZE  (0x1000)
+#define LPC1224_101_NB_SECTOR    (8)
+#define LPC1224_121_NB_SECTOR    (12)
+#define LPC1225_301_NB_SECTOR    (16)
+#define LPC1225_321_NB_SECTOR    (20)
+#define LPC1226_301_NB_SECTOR    (24)
+#define LPC1227_301_NB_SECTOR    (32)
+#define LPC12XX_END_FLASH(version)    (((version) ## _NB_SECTOR) * LPC12xx_SECTOR_SIZE)
+
 
 
 /* Return values */
@@ -111,6 +131,32 @@ int iap_copy_ram_to_flash(uint32_t dest, uint32_t src, uint32_t size);
 /* Return the part ID */
 uint32_t iap_read_part_id(void);
 
+/* Copy the whole unique id table (four 32bits words) in the memory pointed by uid_table.
+ * uid_table must have enougth room for the whole unique id table.
+ * Returns the IAP status.
+ */
+uint32_t iap_read_unique_id(uint32_t* uid_table);
+
+
+
+/*******************************************************************************/
+/* IAP Helpers */
+
+/* Relocate the vector table so that the first sector of the internal flash can be erased
+ * and written
+*/
+void relocate_vector_table(void);
+
+/* Erase one sector, given a flash address
+ * return 0 on success.
+ */
+int flash_hal_erase_sector(uint32_t addr);
+
+/* Flash a binary image chunk to flash.
+ * Flash must have been erased first.
+ * return 0 on success.
+ */
+int flash_hal_program_page (uint32_t addr, uint32_t sz, unsigned char *buf);
 
 #endif /* CORE_IAP_H */