Partial IAP ROM helpers support
authorNathael Pajani <nathael.pajani@ed3l.fr>
Thu, 28 Aug 2014 11:43:59 +0000 (13:43 +0200)
committerNathael Pajani <nathael.pajani@ed3l.fr>
Tue, 8 Nov 2022 16:03:04 +0000 (17:03 +0100)
core/rom_helpers.c
include/core/iap.h [new file with mode: 0644]

index ec823ea..bc3ad3d 100644 (file)
@@ -19,6 +19,8 @@
  *************************************************************************** */
 
 #include <stdint.h>
+#include "core/system.h"
+#include "core/lpc_core_cm0.h"
 
 /*******************************************************************************/
 /*            Integer division using ROM based division routines               */
@@ -73,13 +75,118 @@ void __aeabi_uidivmod(unsigned numerator, unsigned denominator)
 }
 
 
+/*******************************************************************************/
+/*            In Application Programming ROM based routines                    */
+/*******************************************************************************/
+
+enum iap_status {
+       IAP_STATUS_CMD_SUCCESS = 0,
+       IAP_STATUS_INVALID_COMMAND,
+       IAP_STATUS_SRC_ADDR_ERROR,
+       IAP_STATUS_DST_ADDR_ERROR,
+       IAP_STATUS_SRC_ADDR_NOT_MAPPED,
+       IAP_STATUS_DST_ADDR_NOT_MAPPED,
+       IAP_STATUS_COUNT_ERROR,
+       IAP_STATUS_INVALID_SECTOR,
+       IAP_STATUS_SECTOR_NOT_BLANK,
+       IAP_STATUS_SECTOR_NOT_PREPARED_FOR_WRITE_OPERATION,
+       IAP_STATUS_COMPARE_ERROR,
+       IAP_STATUS_BUSY,
+};
+
+enum iap_commands {
+       IAP_CMD_PREPARE_SECTORS_FOR_WRITE = 50,
+       IAP_CMD_COPY_RAM_TO_FLASH = 51,
+       IAP_CMD_ERASE_SECTORS = 52,
+       IAP_CMD_BLANK_CHECK_SECTORS = 53,
+       IAP_CMD_READ_PART_ID = 54,
+       IAP_CMD_READ_BOOT_CODE_VERSION = 55,
+       IAP_CMD_COMPARE = 56,
+       IAP_CMD_REINVOQUE_ISP = 57,
+       IAP_CMD_READ_UID = 58,
+       IAP_CMD_ERASE_PAGE = 59,
+       IAP_CMD_ERASE_INFO_PAGE = 60,
+};
+
+void (*iap_entry)(unsigned int*, unsigned int*);
+
+static uint32_t params[5];
+static uint32_t results[4];
+
+int iap_erase_info_page(uint32_t start_page, uint32_t end_page)
+{
+       params[0] = IAP_CMD_ERASE_INFO_PAGE;
+       params[1] = start_page;
+       params[2] = end_page;
+       params[3] = (get_main_clock() / 1000);
+       lpc_disable_irq();
+       iap_entry(params, results);
+       lpc_enable_irq();
+       return results[0];
+}
+
+int iap_prepare_flash(uint32_t start_sector, uint32_t end_sector)
+{
+       params[0] = IAP_CMD_PREPARE_SECTORS_FOR_WRITE;
+       params[1] = start_sector;
+       params[2] = end_sector;
+       iap_entry(params, results);
+       return results[0];
+}
+
+int iap_erase_flash_sectors(uint32_t start_sector, uint32_t end_sector)
+{
+       params[0] = IAP_CMD_ERASE_SECTORS;
+       params[1] = start_sector;
+       params[2] = end_sector;
+       params[3] = (get_main_clock() / 1000);
+       lpc_disable_irq();
+       iap_entry(params, results);
+       lpc_enable_irq();
+       return results[0];
+}
+
+int iap_erase_flash_pages(uint32_t start_page, uint32_t end_page)
+{
+       params[0] = IAP_CMD_ERASE_PAGE;
+       params[1] = start_page;
+       params[2] = end_page;
+       params[3] = (get_main_clock() / 1000);
+       lpc_disable_irq();
+       iap_entry(params, results);
+       lpc_enable_irq();
+       return results[0];
+}
+int iap_copy_ram_to_flash(uint32_t dest, uint32_t src, uint32_t size)
+{
+       params[0] = IAP_CMD_COPY_RAM_TO_FLASH;
+       params[1] = dest & ~(0x03);
+       params[2] = src & ~(0x03);
+       params[3] = size & ~(0x03);
+       params[4] = (get_main_clock() / 1000);
+       lpc_disable_irq();
+       iap_entry(params, results);
+       lpc_enable_irq();
+       return results[0];
+}
+
+uint32_t iap_read_part_id(void)
+{
+       params[0] = IAP_CMD_READ_PART_ID;
+       iap_entry(params, results);
+       return results[1];
+}
+
+
 /*******************************************************************************/
 /*            Rom based routines initialisation                                */
 /*******************************************************************************/
-#define LPC_122x_DIVROM_LOC (0x1FFC0000)
+#define LPC_122x_DIV_ROM_LOC (0x1FFC0000)
+#define LPC_122x_IAP_ROM_LOC (0x1FFF1FF1)
 
 void rom_helpers_init(void)
 {
-       rom_div_helpers = *((struct lpc_rom_div_helpers**)LPC_122x_DIVROM_LOC);
+       rom_div_helpers = *((struct lpc_rom_div_helpers**)LPC_122x_DIV_ROM_LOC);
+       iap_entry = *((void(*)(unsigned int*, unsigned int*))LPC_122x_IAP_ROM_LOC);
 }
 
diff --git a/include/core/iap.h b/include/core/iap.h
new file mode 100644 (file)
index 0000000..c13499c
--- /dev/null
@@ -0,0 +1,96 @@
+/****************************************************************************
+ *   core/iap.h
+ *
+ *
+ *
+ * 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 2 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/>.
+ *
+ *************************************************************************** */
+
+#ifndef CORE_IAP_H
+#define CORE_IAP_H
+
+#include <stdint.h>
+
+
+/*******************************************************************************/
+/*            In Application Programming ROM based routines                    */
+/*******************************************************************************/
+
+/* Provide access to IAP ROM based routines.
+ * This is the only access to User information block, and allows in-application re-programming
+ *   of the micro-controller (for bootloaders, drivers, loadable RTOS tasks, ....)
+ */
+
+
+/* Erase some pages from the user information block.
+ * Page numbers may be 0, 1 or 2 for the LPC1224.
+ * Provide the same page number as start and end to erase a single page.
+ * Of course, end page number MUST be higher than (or equal to) start page number.
+ * There is no way to erase only parts of a page.
+ * Interrputs are disabled during this operation.
+ */
+int iap_erase_info_page(uint32_t start_page, uint32_t end_page);
+
+
+/* Prepare sectors from the programm flash memory for erasing or writting
+ * Sectors numbers start at 0. A flash sector size is 4kB (0x1000 bytes)
+ * Provide the same sector number as start and end to prepare a single sector.
+ * Of course, end sector number MUST be higher than (or equal to) start sector number.
+ */
+int iap_prepare_flash(uint32_t start_sector, uint32_t end_sector);
+
+/* Erase full flash sectors from the programm memory
+ * Sectors numbers start at 0. A flash sector size is 4kB (0x1000 bytes)
+ * Provide the same sector number as start and end to erase a single sector.
+ * Of course, end sector number MUST be higher than (or equal to) start sector number.
+ * Use iap_erase_flash_pages() to erase a single page within a sector.
+ * A sector must be prepared for writing before the erase operation.
+ * Interrputs are disabled during this operation.
+ */
+int iap_erase_flash_sectors(uint32_t start_sector, uint32_t end_sector);
+
+/* Erase pages  from the programm memory
+ * Page numbers start at 0. A flash page size is 512 bytes.
+ * Provide the same page number as start and end to erase a single page.
+ * Of course, end page number MUST be higher than (or equal to) start page number.
+ * There is no way to erase only parts of a page.
+ * The sector in which the page reside must be prepared for writing before the page erase
+ *    operation.
+ * Interrputs are disabled during this operation.
+ */
+int iap_erase_flash_pages(uint32_t start_page, uint32_t end_page);
+
+
+/* Copy some data from RAM to Flash.
+ * When writting to the programm flash memory, the sectors must be prepared for writing
+ *   before the copy operation.
+ * Both dest and src parameters must be aligned to 4 bytes boundary and size must be a
+ *   multiple of 4.
+ * dest is the destination address and must be the address of some flash memory.
+ * ser is the source address and must be the address of some RAM memory.
+ * The sector or page in dest must have been erased before writing and no writing operation
+ *   performed between (dest) and (dest+size) addresses. (Writting in other parts of the
+ *   page or sector is OK)
+ * Interrputs are disabled during this operation.
+ */
+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);
+
+
+#endif /* CORE_IAP_H */
+