Initial commit, code based on LPC1224 support and LPC812-MAX CMSIS-DAP interface...
[lpc11u3x] / core / iap.c
1 /****************************************************************************
2  *   core/iap.c
3  *
4  *
5  * Copyright 2015 Nathael Pajani <nathael.pajani@ed3l.fr>
6  *
7  * This file is derived from Work covered by the Apache 2.0 licence.
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  * Original sources should be found there :
10  *     https://github.com/mbedmicro/CMSIS-DAP.git
11  * Original file name is bootloader/hal/TARGET_NXP/TARGET_LPC11U35/flash_hal.c
12  *
13  * Original copyright notice :
14  *    CMSIS-DAP Interface Firmware
15  *    Copyright (c) 2009-2013 ARM Limited
16  *
17  * This program is free software: you can redistribute it and/or modify
18  * it under the terms of the GNU General Public License as published by
19  * the Free Software Foundation, either version 3 of the License, or
20  * (at your option) any later version.
21  *
22  * This program is distributed in the hope that it will be useful,
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25  * GNU General Public License for more details.
26  *
27  * You should have received a copy of the GNU General Public License
28  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
29  *
30  *****************************************************************************/
32 #include <stdint.h>
33 #include "core/lpc_regs_11u3x.h"
34 #include "core/iap.h"
37 static uint32_t get_sector_number(uint32_t addr)
38 {
39         uint32_t sector = 0;
41         sector = addr >> 12;  /* 4kB Sector */
42         if (sector >= 0x10) {
43                 sector = 0x0E + (sector >> 3); /* 32kB Sector */
44         }
46         return sector;
47 }
49 /* Erase one sector, given a flash address
50  * return 0 on success.
51  */
52 int flash_hal_erase_sector(uint32_t addr)
53 {
54         uint32_t sector = get_sector_number(addr);
55         int ret = 0;
57         /* Prepare sector for erase */
58         ret = iap_prepare_flash(sector, sector);
59         if (ret != IAP_STATUS_CMD_SUCCESS) {
60                 return ret;
61         }
62         /* Erase sector */
63         return iap_erase_flash_sectors(sector, sector);
64 }
66 /* Flash a binary image chunk to a sector. */
67 int flash_hal_program_page(uint32_t addr, uint32_t sz, unsigned char *buf)
68 {
69         uint32_t sector = 0;
70         int ret = 0;
72         /* If this goes to the beginning of the Flash image, check that the image is valid. */
73         if (addr == 0) {
74                 uint32_t crp = *((uint32_t *)(buf + CRP_ADDRESS));
75                 uint32_t checksum = 0;
77                 if (IS_CRP_VALUE(crp)) {
78                         /* CRP is enabled, exit. */
79                         return -1;
80                 }
82                 /* Compute a valid user code */
83                 checksum = *((uint32_t *)(buf + 0x00)) + *((uint32_t *)(buf + 0x04)) +
84                                         *((uint32_t *)(buf + 0x08)) + *((uint32_t *)(buf + 0x0C)) +
85                                         *((uint32_t *)(buf + 0x10)) + *((uint32_t *)(buf + 0x14)) +
86                                         *((uint32_t *)(buf + 0x18));
87                 *((uint32_t *)(buf + 0x1C)) = 0 - checksum;
88         }
90         sector = get_sector_number(addr);
92         /* Prepare sector for write */
93         ret = iap_prepare_flash(sector, sector);
94         if (ret != IAP_STATUS_CMD_SUCCESS) {
95                 return ret;
96         }
98         /* FIXME : in original code, size was hardcoded to 1024 */
99         return iap_copy_ram_to_flash(addr, (uint32_t)buf, sz);