From: Nathael Pajani Date: Tue, 27 Sep 2016 21:11:00 +0000 (+0200) Subject: Core IAP code. NOT TESTED. X-Git-Url: http://git.techno-innov.fr/?a=commitdiff_plain;h=b336f09cf033fdadfe09757e0421ae4e0a511bdd;p=soft%2Flpc122x%2Fcore Core IAP code. NOT TESTED. --- diff --git a/core/iap.c b/core/iap.c new file mode 100644 index 0000000..2a611fe --- /dev/null +++ b/core/iap.c @@ -0,0 +1,107 @@ +/**************************************************************************** + * core/iap.c + * + * + * Copyright 2015 Nathael Pajani + * + * 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 . + * + *****************************************************************************/ + +#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 index 0000000..b46bbc0 --- /dev/null +++ b/core/vector_table.c @@ -0,0 +1,59 @@ +/**************************************************************************** + * core/vector_table.c + * + * + * Copyright 2015 Nathael Pajani + * + * 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 . + * + *****************************************************************************/ + +/* 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; + } +} diff --git a/include/core/iap.h b/include/core/iap.h index 5c6fa8f..ae760ce 100644 --- a/include/core/iap.h +++ b/include/core/iap.h @@ -33,6 +33,26 @@ * 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 */