From: Nathael Pajani Date: Thu, 28 Aug 2014 11:43:59 +0000 (+0200) Subject: Partial IAP ROM helpers support X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=d18d767d0892a5a245d840faef5fe740782ee44d;p=soft%2Flpc122x%2Fcore Partial IAP ROM helpers support --- diff --git a/core/rom_helpers.c b/core/rom_helpers.c index ec823ea..bc3ad3d 100644 --- a/core/rom_helpers.c +++ b/core/rom_helpers.c @@ -19,6 +19,8 @@ *************************************************************************** */ #include +#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 index 0000000..c13499c --- /dev/null +++ b/include/core/iap.h @@ -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 . + * + *************************************************************************** */ + +#ifndef CORE_IAP_H +#define CORE_IAP_H + +#include + + +/*******************************************************************************/ +/* 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 */ +