*************************************************************************** */
#include <stdint.h>
+#include "core/system.h"
+#include "core/lpc_core_cm0.h"
/*******************************************************************************/
/* Integer division using ROM based division routines */
}
+/*******************************************************************************/
+/* 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);
}
--- /dev/null
+/****************************************************************************
+ * 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 */
+