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.
Fork of libMiMic by
K64F_IAP.c
00001 /** 00002 * Copyright 2014 MiMicProject 00003 * Licensed under the Apache License, Version 2.0 (the "License"); 00004 * you may not use this file except in compliance with the License. 00005 * You may obtain a copy of the License at 00006 * 00007 * http://www.apache.org/licenses/LICENSE-2.0 00008 * 00009 * Unless required by applicable law or agreed to in writing, software 00010 * distributed under the License is distributed on an "AS IS" BASIS, 00011 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00012 * See the License for the specific language governing permissions and 00013 * limitations under the License. 00014 */ 00015 /** 00016 * This file based on https://mbed.org/users/Sissors/code/FreescaleIAP/ 00017 */ 00018 #include "NyLPC_config.h" 00019 #if NyLPC_MCU==NyLPC_MCU_K64F 00020 #include "K64F_IAP.h" 00021 //For K64F 00022 # include "MK64F12.h" 00023 # define USE_ProgramPhrase 1 00024 # define FTFA FTFE 00025 # define FTFA_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK 00026 # define FTFA_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK 00027 # define FTFA_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK 00028 # define FTFA_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK 00029 # define FTFA_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK 00030 00031 enum FCMD { 00032 Read1s = 0x01, 00033 ProgramCheck = 0x02, 00034 ReadResource = 0x03, 00035 ProgramLongword = 0x06, 00036 ProgramPhrase = 0x07, 00037 EraseSector = 0x09, 00038 Read1sBlock = 0x40, 00039 ReadOnce = 0x41, 00040 ProgramOnce = 0x43, 00041 EraseAll = 0x44, 00042 VerifyBackdoor = 0x45 00043 }; 00044 00045 00046 #define INT_FALSE (0!=0) 00047 #define INT_TRUE (0==0) 00048 00049 static inline void run_command(void); 00050 //static int check_boundary(int address, unsigned int length); 00051 static int check_align(int address); 00052 00053 static K64F_IAP_TIAPCode verify_erased(int address, unsigned int length); 00054 static K64F_IAP_TIAPCode check_error(void); 00055 static K64F_IAP_TIAPCode program_word(int address, char *data); 00056 00057 K64F_IAP_TIAPCode K64F_IAP_erase_sector(int address) { 00058 #ifdef IAPDEBUG 00059 printf("IAP: Erasing at %x\r\n", address); 00060 #endif 00061 if (check_align(address)) 00062 return K64F_IAP_TIAPCode_AlignError; 00063 00064 //Setup command 00065 FTFA->FCCOB0 = EraseSector; 00066 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00067 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00068 FTFA->FCCOB3 = address & 0xFF; 00069 00070 run_command(); 00071 00072 return check_error(); 00073 } 00074 00075 K64F_IAP_TIAPCode K64F_IAP_program_flash(int address, char *data, unsigned int length) { 00076 #ifdef IAPDEBUG 00077 printf("IAP: Programming flash at %x with length %d\r\n", address, length); 00078 #endif 00079 if (check_align(address)) 00080 return K64F_IAP_TIAPCode_AlignError; 00081 00082 K64F_IAP_TIAPCode eraseCheck = verify_erased(address, length); 00083 if (eraseCheck != K64F_IAP_TIAPCode_Success) 00084 return eraseCheck; 00085 00086 K64F_IAP_TIAPCode progResult; 00087 for (int i = 0; i < length; i+=8) { 00088 progResult = program_word(address + i, data + i); 00089 if (progResult != K64F_IAP_TIAPCode_Success) 00090 return progResult; 00091 } 00092 return K64F_IAP_TIAPCode_Success; 00093 } 00094 00095 unsigned int K64F_IAP_flash_size(void) { 00096 unsigned int retval = (SIM->FCFG2 & 0x7F000000u) >> (24-13); 00097 if (SIM->FCFG2 & (1<<23)) //Possible second flash bank 00098 retval += (SIM->FCFG2 & 0x007F0000u) >> (16-13); 00099 return retval; 00100 } 00101 00102 static K64F_IAP_TIAPCode program_word(int address, char *data) { 00103 #ifdef IAPDEBUG 00104 printf("IAP: Programming word at %x, %d - %d - %d - %d - %d - %d - %d - %d\r\n", address, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); 00105 #endif 00106 if (check_align(address)){ 00107 return K64F_IAP_TIAPCode_AlignError; 00108 } 00109 FTFA->FCCOB0 = ProgramPhrase; 00110 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00111 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00112 FTFA->FCCOB3 = address & 0xFF; 00113 FTFA->FCCOB4 = data[3]; 00114 FTFA->FCCOB5 = data[2]; 00115 FTFA->FCCOB6 = data[1]; 00116 FTFA->FCCOB7 = data[0]; 00117 FTFA->FCCOB8 = data[7]; 00118 FTFA->FCCOB9 = data[6]; 00119 FTFA->FCCOBA = data[5]; 00120 FTFA->FCCOBB = data[4]; 00121 run_command(); 00122 return check_error(); 00123 } 00124 00125 /* Clear possible flags which are set, run command, wait until done */ 00126 static inline void run_command(void) { 00127 //Clear possible old errors, start command, wait until done 00128 __disable_irq(); //Disable IRQs, preventing IRQ routines from trying to access flash (thanks to https://mbed.org/users/mjr/) 00129 FTFA->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK; 00130 FTFA->FSTAT = FTFA_FSTAT_CCIF_MASK; 00131 while (!(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK)); 00132 __enable_irq(); 00133 } 00134 00135 00136 00137 /* Check if no flash boundary is violated 00138 Returns true on violation *//* 00139 static int check_boundary(int address, unsigned int length) { 00140 int temp = (address+length - 1) / K64F_IAP_SECTOR_SIZE; 00141 address /= K64F_IAP_SECTOR_SIZE; 00142 int retval = (address != temp); 00143 #ifdef IAPDEBUG 00144 if (retval) 00145 printf("IAP: Boundary violation\r\n"); 00146 #endif 00147 return retval; 00148 }*/ 00149 00150 /* Check if address is correctly aligned 00151 Returns true on violation */ 00152 static int check_align(int address) { 00153 int retval = address & 0x03; 00154 #ifdef IAPDEBUG 00155 if (retval) 00156 printf("IAP: Alignment violation\r\n"); 00157 #endif 00158 return retval; 00159 } 00160 00161 /* Check if an area of flash memory is erased 00162 Returns error code or Success (in case of fully erased) */ 00163 static K64F_IAP_TIAPCode verify_erased(int address, unsigned int length) { 00164 #ifdef IAPDEBUG 00165 printf("IAP: Verify erased at %x with length %d\r\n", address, length); 00166 #endif 00167 00168 if (check_align(address)){ 00169 return K64F_IAP_TIAPCode_AlignError; 00170 } 00171 00172 //Setup command 00173 FTFA->FCCOB0 = Read1s; 00174 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00175 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00176 FTFA->FCCOB3 = address & 0xFF; 00177 FTFA->FCCOB4 = (length >> 10) & 0xFF; 00178 FTFA->FCCOB5 = (length >> 2) & 0xFF; 00179 FTFA->FCCOB6 = 0; 00180 00181 run_command(); 00182 00183 K64F_IAP_TIAPCode retval = check_error(); 00184 if (retval == K64F_IAP_TIAPCode_RuntimeError) { 00185 #ifdef IAPDEBUG 00186 printf("IAP: Flash was not erased\r\n"); 00187 #endif 00188 return K64F_IAP_TIAPCode_EraseError; 00189 } 00190 return retval; 00191 } 00192 00193 /* Check if an error occured 00194 Returns error code or Success*/ 00195 static K64F_IAP_TIAPCode check_error(void) { 00196 if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) { 00197 #ifdef IAPDEBUG 00198 printf("IAP: Protection violation\r\n"); 00199 #endif 00200 return K64F_IAP_TIAPCode_ProtectionError; 00201 } 00202 if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) { 00203 #ifdef IAPDEBUG 00204 printf("IAP: Flash access error\r\n"); 00205 #endif 00206 return K64F_IAP_TIAPCode_AccessError; 00207 } 00208 if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) { 00209 #ifdef IAPDEBUG 00210 printf("IAP: Collision error\r\n"); 00211 #endif 00212 return K64F_IAP_TIAPCode_CollisionError; 00213 } 00214 if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) { 00215 #ifdef IAPDEBUG 00216 printf("IAP: Runtime error\r\n"); 00217 #endif 00218 return K64F_IAP_TIAPCode_RuntimeError; 00219 } 00220 #ifdef IAPDEBUG 00221 printf("IAP: No error reported\r\n"); 00222 #endif 00223 return K64F_IAP_TIAPCode_Success; 00224 } 00225 #endif
Generated on Tue Jul 12 2022 16:22:56 by
