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.
FlashPrg.c
00001 /* CMSIS-DAP Interface Firmware 00002 * Copyright (c) 2009-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #include "FlashOS.h" 00018 #include "max32620.h" 00019 #include "flc_regs.h" 00020 00021 /******************************************************************************/ 00022 static inline int FLC_Busy(void) 00023 { 00024 return (MXC_FLC->ctrl & (MXC_F_FLC_CTRL_WRITE | MXC_F_FLC_CTRL_MASS_ERASE | MXC_F_FLC_CTRL_PAGE_ERASE)); 00025 } 00026 00027 /******************************************************************************/ 00028 uint32_t Init(uint32_t adr, uint32_t clk, uint32_t fnc) 00029 { 00030 /* Check if the flash controller is busy */ 00031 if (FLC_Busy()) { 00032 return 1; 00033 } 00034 00035 /* Enable automatic calculation of the clock divider to generate a 1MHz clock from the APB clock */ 00036 MXC_FLC->perform |= MXC_F_FLC_PERFORM_AUTO_CLKDIV; 00037 00038 /* The flash controller will stall any reads while flash operations are in 00039 * progress. Disable the legacy failure detection logic that would flag reads 00040 * during flash operations as errors. 00041 */ 00042 MXC_FLC->perform |= MXC_F_FLC_PERFORM_EN_PREVENT_FAIL; 00043 00044 return 0; 00045 } 00046 00047 /******************************************************************************/ 00048 uint32_t UnInit(uint32_t fnc) 00049 { 00050 /* Lock flash */ 00051 MXC_FLC->ctrl &= ~MXC_F_FLC_CTRL_FLSH_UNLOCK; 00052 00053 return 0; // Finished without Errors 00054 } 00055 00056 /******************************************************************************/ 00057 /* 00058 * Erase complete Flash Memory 00059 * Return Value: 0 - OK, 1 - Failed 00060 */ 00061 int EraseChip(void) 00062 { 00063 /* Check if the flash controller is busy */ 00064 if (FLC_Busy()) { 00065 return 1; 00066 } 00067 00068 /* Clear stale errors. Interrupt flags can only be written to zero, so this is safe */ 00069 MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; 00070 00071 /* Unlock flash */ 00072 MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_FLSH_UNLOCK) | (MXC_V_FLC_FLSH_UNLOCK_KEY << MXC_F_FLC_CTRL_FLSH_UNLOCK_POS); 00073 00074 /* Write the Erase Code */ 00075 MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_ERASE_CODE) | (MXC_V_FLC_ERASE_CODE_MASS_ERASE << MXC_F_FLC_CTRL_ERASE_CODE_POS); 00076 00077 /* Start the mass erase */ 00078 MXC_FLC->ctrl |= MXC_F_FLC_CTRL_MASS_ERASE; 00079 00080 /* Wait until flash operation is complete */ 00081 while (FLC_Busy()); 00082 00083 /* Lock flash */ 00084 MXC_FLC->ctrl &= ~(MXC_F_FLC_CTRL_FLSH_UNLOCK | MXC_F_FLC_CTRL_ERASE_CODE); 00085 00086 /* Check for failures */ 00087 if (MXC_FLC->intr & MXC_F_FLC_INTR_FAILED_IF) { 00088 /* Interrupt flags can only be written to zero, so this is safe */ 00089 MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; 00090 return 1; 00091 } 00092 00093 return 0; 00094 } 00095 00096 /******************************************************************************/ 00097 /* 00098 * Erase Sector in Flash Memory 00099 * Parameter: address: Sector Address 00100 * Return Value: 0 - OK, 1 - Failed 00101 */ 00102 int EraseSector(unsigned long address) 00103 { 00104 /* Wait until flash operation is complete */ 00105 while (FLC_Busy()); 00106 00107 /* Clear stale errors. Interrupt flags can only be written to zero, so this is safe */ 00108 MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; 00109 00110 /* Unlock flash */ 00111 MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_FLSH_UNLOCK) | (MXC_V_FLC_FLSH_UNLOCK_KEY << MXC_F_FLC_CTRL_FLSH_UNLOCK_POS); 00112 00113 /* Write page erase code */ 00114 MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_ERASE_CODE) | (MXC_V_FLC_ERASE_CODE_PAGE_ERASE << MXC_F_FLC_CTRL_ERASE_CODE_POS); 00115 00116 /* Erase the request page */ 00117 MXC_FLC->faddr = address; 00118 MXC_FLC->ctrl |= MXC_F_FLC_CTRL_PAGE_ERASE; 00119 00120 /* Wait until flash operation is complete */ 00121 while (FLC_Busy()); 00122 00123 /* Lock flash */ 00124 MXC_FLC->ctrl &= ~(MXC_F_FLC_CTRL_FLSH_UNLOCK | MXC_F_FLC_CTRL_ERASE_CODE); 00125 00126 /* Check for failures */ 00127 if (MXC_FLC->intr & MXC_F_FLC_INTR_FAILED_IF) { 00128 /* Interrupt flags can only be written to zero, so this is safe */ 00129 MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; 00130 return 1; 00131 } 00132 00133 return 0; 00134 } 00135 00136 /******************************************************************************/ 00137 /* 00138 * Program Page in Flash Memory 00139 * Parameter: address: Page Start Address 00140 * size: Page Size 00141 * buffer: Page Data 00142 * Return Value: 0 - OK, 1 - Failed 00143 */ 00144 int ProgramPage(unsigned long address, unsigned long size, unsigned char *buffer8) 00145 { 00146 unsigned long remaining = size; 00147 unsigned long *buffer = (unsigned long *)buffer8; 00148 00149 // Only accept 32-bit aligned pointers 00150 if ((unsigned long)buffer8 & 0x3) { 00151 return 1; 00152 } 00153 buffer = (unsigned long *)buffer8; 00154 00155 /* Check if the flash controller is busy */ 00156 if (FLC_Busy()) { 00157 return 1; 00158 } 00159 00160 /* Unlock flash */ 00161 MXC_FLC->ctrl = (MXC_FLC->ctrl & ~MXC_F_FLC_CTRL_FLSH_UNLOCK) | (MXC_V_FLC_FLSH_UNLOCK_KEY << MXC_F_FLC_CTRL_FLSH_UNLOCK_POS); 00162 00163 while (remaining >= 4) { 00164 MXC_FLC->faddr = address; 00165 MXC_FLC->fdata = *buffer++; 00166 MXC_FLC->ctrl |= MXC_F_FLC_CTRL_WRITE_ENABLE; 00167 MXC_FLC->ctrl |= MXC_F_FLC_CTRL_WRITE; 00168 00169 /* Wait until flash operation is complete */ 00170 while (FLC_Busy()); 00171 00172 address += 4; 00173 remaining -= 4; 00174 } 00175 00176 if (remaining > 0) { 00177 uint32_t last_word; 00178 uint32_t mask; 00179 00180 last_word = 0xffffffff; 00181 mask = 0xff; 00182 00183 while (remaining > 0) { 00184 last_word &= (*buffer | ~mask); 00185 mask <<= 8; 00186 remaining--; 00187 } 00188 00189 MXC_FLC->faddr = address; 00190 MXC_FLC->fdata = last_word; 00191 MXC_FLC->ctrl |= MXC_F_FLC_CTRL_WRITE_ENABLE; 00192 00193 /* Wait until flash operation is complete */ 00194 while (FLC_Busy()); 00195 } 00196 00197 /* Lock flash */ 00198 MXC_FLC->ctrl &= ~MXC_F_FLC_CTRL_FLSH_UNLOCK; 00199 00200 /* Check for failures */ 00201 if (MXC_FLC->intr & MXC_F_FLC_INTR_FAILED_IF) { 00202 /* Interrupt flags can only be written to zero, so this is safe */ 00203 MXC_FLC->intr &= ~MXC_F_FLC_INTR_FAILED_IF; 00204 return 1; 00205 } 00206 00207 return 0; 00208 }
Generated on Tue Jul 12 2022 15:37:17 by
