Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
flash.c
00001 /** 00002 * @file flash_hal_stub.c 00003 * @brief 00004 * 00005 * DAPLink Interface Firmware 00006 * Copyright (c) 2009-2016, ARM Limited, All Rights Reserved 00007 * SPDX-License-Identifier: Apache-2.0 00008 * 00009 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00010 * not use this file except in compliance with the License. 00011 * You may obtain a copy of the License at 00012 * 00013 * http://www.apache.org/licenses/LICENSE-2.0 00014 * 00015 * Unless required by applicable law or agreed to in writing, software 00016 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00017 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00018 * See the License for the specific language governing permissions and 00019 * limitations under the License. 00020 */ 00021 00022 #include "flash_hal.h" 00023 #include "system_LPC43xx.h" 00024 #include "daplink_addr.h" 00025 #include "cortex_m.h" 00026 00027 #define END_SECTOR 14 /* 15 sectors per bank */ 00028 #define FLASH_BANK_A 0 00029 #define FLASH_BANK_B 1 00030 00031 /* IAP Structure */ 00032 struct sIAP { 00033 uint32_t cmd; // Command 00034 uint32_t par[4]; // Parameters 00035 uint32_t stat; // Status 00036 uint32_t res[2]; // Result 00037 } IAP; 00038 00039 /* IAP Call */ 00040 typedef void (*IAP_Entry) (uint32_t *cmd, uint32_t *stat); 00041 #define IAP_Call ((IAP_Entry) (*(volatile unsigned int *)(0x10400100))) 00042 00043 uint32_t GetSecNum (uint32_t adr) { 00044 uint32_t n; 00045 uint32_t flashadr = (adr & 0xFFFFFF); 00046 00047 if (flashadr < 0x10000) { 00048 n = flashadr >> 13; // 8kB Sector 00049 } else { 00050 n = (flashadr >> 16) + 7; // 64kB Sector 00051 } 00052 00053 return n; // Sector Number 00054 } 00055 00056 00057 uint32_t Init(uint32_t adr, uint32_t clk, uint32_t fnc) 00058 { 00059 cortex_int_state_t local_state = cortex_int_get_and_disable(); 00060 00061 IAP.cmd = 49; // Initialize 00062 IAP.par[0] = 0; 00063 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command 00064 00065 cortex_int_restore(local_state); 00066 00067 return 0; 00068 } 00069 00070 uint32_t UnInit(uint32_t fnc) 00071 { 00072 return 0; 00073 } 00074 00075 uint32_t EraseChip(void) 00076 { 00077 cortex_int_state_t local_state = cortex_int_get_and_disable(); 00078 00079 IAP.cmd = 50; // Prepare Sector for Erase 00080 IAP.par[0] = 0; // Start Sector 00081 IAP.par[1] = END_SECTOR; // End Sector 00082 IAP.par[2] = FLASH_BANK_A; // Flash Bank 00083 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command 00084 if (IAP.stat) { 00085 cortex_int_restore(local_state); 00086 return 1; // Command Failed 00087 } 00088 00089 IAP.cmd = 52; // Erase Sector 00090 IAP.par[0] = 0; // Start Sector 00091 IAP.par[1] = END_SECTOR; // End Sector 00092 IAP.par[2] = SystemCoreClock / 1000; // CCLK in kHz 00093 IAP.par[3] = FLASH_BANK_A; // Flash Bank 00094 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command 00095 if (IAP.stat) { 00096 cortex_int_restore(local_state); 00097 return 1; // Command Failed 00098 } 00099 00100 cortex_int_restore(local_state); 00101 00102 return 0; 00103 } 00104 00105 uint32_t EraseSector(uint32_t adr) 00106 { 00107 uint32_t n; 00108 00109 n = GetSecNum(adr); // Get Sector Number 00110 00111 cortex_int_state_t local_state = cortex_int_get_and_disable(); 00112 00113 IAP.cmd = 50; // Prepare Sector for Erase 00114 IAP.par[0] = n; // Start Sector 00115 IAP.par[1] = n; // End Sector 00116 IAP.par[2] = FLASH_BANK_A; // Flash Bank 00117 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command 00118 if (IAP.stat) { 00119 cortex_int_restore(local_state); 00120 return 1; // Command Failed 00121 } 00122 00123 IAP.cmd = 52; // Erase Sector 00124 IAP.par[0] = n; // Start Sector 00125 IAP.par[1] = n; // End Sector 00126 IAP.par[2] = SystemCoreClock / 1000; // CCLK in kHz 00127 IAP.par[3] = FLASH_BANK_A; // Flash Bank 00128 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command 00129 if (IAP.stat) { 00130 cortex_int_restore(local_state); 00131 return 1; // Command Failed 00132 } 00133 00134 cortex_int_restore(local_state); 00135 00136 return 0; 00137 } 00138 00139 uint32_t ProgramPage(uint32_t adr, uint32_t sz, uint32_t *buf) 00140 { 00141 uint32_t n; 00142 00143 if (adr == DAPLINK_ROM_START) { // Check for Vector Table 00144 n = *((unsigned long *)(buf + 0)) + 00145 *((unsigned long *)(buf + 1)) + 00146 *((unsigned long *)(buf + 2)) + 00147 *((unsigned long *)(buf + 3)) + 00148 *((unsigned long *)(buf + 4)) + 00149 *((unsigned long *)(buf + 5)) + 00150 *((unsigned long *)(buf + 6)); 00151 *((unsigned long *)(buf + 7)) = 0 - n; // Signature at Reserved Vector 00152 } 00153 n = GetSecNum(adr); // Get Sector Number 00154 00155 cortex_int_state_t local_state = cortex_int_get_and_disable(); 00156 00157 IAP.cmd = 50; // Prepare Sector for Write 00158 IAP.par[0] = n; // Start Sector 00159 IAP.par[1] = n; // End Sector 00160 IAP.par[2] = FLASH_BANK_A; // Flash Bank 00161 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command 00162 if (IAP.stat) { 00163 cortex_int_restore(local_state); 00164 return 1; // Command Failed 00165 } 00166 00167 IAP.cmd = 51; // Copy RAM to Flash 00168 IAP.par[0] = adr; // Destination Flash Address 00169 IAP.par[1] = (unsigned long)buf; // Source RAM Address 00170 IAP.par[2] = 0x400; // Fixed Page Size 00171 IAP.par[3] = SystemCoreClock / 1000; // CCLK in kHz 00172 IAP_Call(&IAP.cmd, &IAP.stat); // Call IAP Command 00173 if (IAP.stat) { 00174 cortex_int_restore(local_state); 00175 return 1; // Command Failed 00176 } 00177 00178 cortex_int_restore(local_state); 00179 00180 return 0; 00181 }
Generated on Tue Jul 12 2022 15:37:16 by
