IAP code for Freescale platforms
Dependents: 18_PT1000 RDA5807M-FM-Radio flashaccess TF_conops_BAEFLAGIMAN ... more
FreescaleIAP.cpp
00001 #include "FreescaleIAP.h" 00002 00003 #ifdef TARGET_Freescale 00004 00005 //#define IAPDEBUG 00006 00007 #ifdef TARGET_K64F 00008 //For K64F 00009 # include "MK64F12.h" 00010 # define USE_ProgramPhrase 1 00011 # define FTFA FTFE 00012 # define FTFA_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK 00013 # define FTFA_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK 00014 # define FTFA_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK 00015 # define FTFA_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK 00016 # define FTFA_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK 00017 #else 00018 //Different names used on at least the K20: 00019 # ifndef FTFA_FSTAT_FPVIOL_MASK 00020 # define FTFA FTFL 00021 # define FTFA_FSTAT_FPVIOL_MASK FTFL_FSTAT_FPVIOL_MASK 00022 # define FTFA_FSTAT_ACCERR_MASK FTFL_FSTAT_ACCERR_MASK 00023 # define FTFA_FSTAT_RDCOLERR_MASK FTFL_FSTAT_RDCOLERR_MASK 00024 # define FTFA_FSTAT_CCIF_MASK FTFL_FSTAT_CCIF_MASK 00025 # define FTFA_FSTAT_MGSTAT0_MASK FTFL_FSTAT_MGSTAT0_MASK 00026 # endif 00027 #endif 00028 00029 00030 enum FCMD { 00031 Read1s = 0x01, 00032 ProgramCheck = 0x02, 00033 ReadResource = 0x03, 00034 ProgramLongword = 0x06, 00035 ProgramPhrase = 0x07, 00036 EraseSector = 0x09, 00037 Read1sBlock = 0x40, 00038 ReadOnce = 0x41, 00039 ProgramOnce = 0x43, 00040 EraseAll = 0x44, 00041 VerifyBackdoor = 0x45 00042 }; 00043 00044 inline void run_command(void); 00045 bool check_boundary(int address, unsigned int length); 00046 bool check_align(int address); 00047 IAPCode verify_erased(int address, unsigned int length); 00048 IAPCode check_error(void); 00049 IAPCode program_word(int address, char *data); 00050 00051 IAPCode erase_sector(int address) { 00052 #ifdef IAPDEBUG 00053 printf("IAP: Erasing at %x\r\n", address); 00054 #endif 00055 if (check_align(address)) 00056 return AlignError; 00057 00058 //Setup command 00059 FTFA->FCCOB0 = EraseSector; 00060 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00061 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00062 FTFA->FCCOB3 = address & 0xFF; 00063 00064 run_command(); 00065 00066 return check_error(); 00067 } 00068 00069 IAPCode program_flash(int address, char *data, unsigned int length) { 00070 #ifdef IAPDEBUG 00071 printf("IAP: Programming flash at %x with length %d\r\n", address, length); 00072 #endif 00073 if (check_align(address)) 00074 return AlignError; 00075 00076 IAPCode eraseCheck = verify_erased(address, length); 00077 if (eraseCheck != Success) 00078 return eraseCheck; 00079 00080 IAPCode progResult; 00081 #ifdef USE_ProgramPhrase 00082 for (int i = 0; i < length; i+=8) { 00083 progResult = program_word(address + i, data + i); 00084 if (progResult != Success) 00085 return progResult; 00086 } 00087 #else 00088 for (int i = 0; i < length; i+=4) { 00089 progResult = program_word(address + i, data + i); 00090 if (progResult != Success) 00091 return progResult; 00092 } 00093 #endif 00094 return Success; 00095 } 00096 00097 uint32_t flash_size(void) { 00098 uint32_t retval = (SIM->FCFG2 & 0x7F000000u) >> (24-13); 00099 if (SIM->FCFG2 & (1<<23)) //Possible second flash bank 00100 retval += (SIM->FCFG2 & 0x007F0000u) >> (16-13); 00101 return retval; 00102 } 00103 00104 IAPCode program_word(int address, char *data) { 00105 #ifdef IAPDEBUG 00106 #ifdef USE_ProgramPhrase 00107 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]); 00108 #else 00109 printf("IAP: Programming word at %x, %d - %d - %d - %d\r\n", address, data[0], data[1], data[2], data[3]); 00110 #endif 00111 00112 #endif 00113 if (check_align(address)) 00114 return AlignError; 00115 #ifdef USE_ProgramPhrase 00116 FTFA->FCCOB0 = ProgramPhrase; 00117 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00118 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00119 FTFA->FCCOB3 = address & 0xFF; 00120 FTFA->FCCOB4 = data[3]; 00121 FTFA->FCCOB5 = data[2]; 00122 FTFA->FCCOB6 = data[1]; 00123 FTFA->FCCOB7 = data[0]; 00124 FTFA->FCCOB8 = data[7]; 00125 FTFA->FCCOB9 = data[6]; 00126 FTFA->FCCOBA = data[5]; 00127 FTFA->FCCOBB = data[4]; 00128 #else 00129 //Setup command 00130 FTFA->FCCOB0 = ProgramLongword; 00131 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00132 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00133 FTFA->FCCOB3 = address & 0xFF; 00134 FTFA->FCCOB4 = data[3]; 00135 FTFA->FCCOB5 = data[2]; 00136 FTFA->FCCOB6 = data[1]; 00137 FTFA->FCCOB7 = data[0]; 00138 #endif 00139 run_command(); 00140 00141 return check_error(); 00142 } 00143 00144 /* Clear possible flags which are set, run command, wait until done */ 00145 inline void run_command(void) { 00146 //Clear possible old errors, start command, wait until done 00147 __disable_irq(); //Disable IRQs, preventing IRQ routines from trying to access flash (thanks to https://mbed.org/users/mjr/) 00148 FTFA->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK; 00149 FTFA->FSTAT = FTFA_FSTAT_CCIF_MASK; 00150 while (!(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK)); 00151 __enable_irq(); 00152 } 00153 00154 00155 00156 /* Check if no flash boundary is violated 00157 Returns true on violation */ 00158 bool check_boundary(int address, unsigned int length) { 00159 int temp = (address+length - 1) / SECTOR_SIZE; 00160 address /= SECTOR_SIZE; 00161 bool retval = (address != temp); 00162 #ifdef IAPDEBUG 00163 if (retval) 00164 printf("IAP: Boundary violation\r\n"); 00165 #endif 00166 return retval; 00167 } 00168 00169 /* Check if address is correctly aligned 00170 Returns true on violation */ 00171 bool check_align(int address) { 00172 bool retval = address & 0x03; 00173 #ifdef IAPDEBUG 00174 if (retval) 00175 printf("IAP: Alignment violation\r\n"); 00176 #endif 00177 return retval; 00178 } 00179 00180 /* Check if an area of flash memory is erased 00181 Returns error code or Success (in case of fully erased) */ 00182 IAPCode verify_erased(int address, unsigned int length) { 00183 #ifdef IAPDEBUG 00184 printf("IAP: Verify erased at %x with length %d\r\n", address, length); 00185 #endif 00186 00187 if (check_align(address)) 00188 return AlignError; 00189 00190 #ifdef USE_ProgramPhrase 00191 //Check erase is per 16 bytes, we round up 00192 length = (length + 15) >> 4; 00193 #else 00194 //Otherwise per 4 byte (should check if this is true) 00195 length = (length + 3) >> 2; 00196 #endif 00197 00198 //Setup command 00199 FTFA->FCCOB0 = Read1s; 00200 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00201 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00202 FTFA->FCCOB3 = address & 0xFF; 00203 FTFA->FCCOB4 = (length >> 8) & 0xFF; 00204 FTFA->FCCOB5 = length & 0xFF; 00205 FTFA->FCCOB6 = 0; 00206 00207 run_command(); 00208 00209 IAPCode retval = check_error(); 00210 if (retval == RuntimeError) { 00211 #ifdef IAPDEBUG 00212 printf("IAP: Flash was not erased\r\n"); 00213 #endif 00214 return EraseError; 00215 } 00216 return retval; 00217 00218 } 00219 00220 /* Check if an error occured 00221 Returns error code or Success*/ 00222 IAPCode check_error(void) { 00223 if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) { 00224 #ifdef IAPDEBUG 00225 printf("IAP: Protection violation\r\n"); 00226 #endif 00227 return ProtectionError; 00228 } 00229 if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) { 00230 #ifdef IAPDEBUG 00231 printf("IAP: Flash access error\r\n"); 00232 #endif 00233 return AccessError; 00234 } 00235 if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) { 00236 #ifdef IAPDEBUG 00237 printf("IAP: Collision error\r\n"); 00238 #endif 00239 return CollisionError; 00240 } 00241 if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) { 00242 #ifdef IAPDEBUG 00243 printf("IAP: Runtime error\r\n"); 00244 #endif 00245 return RuntimeError; 00246 } 00247 #ifdef IAPDEBUG 00248 printf("IAP: No error reported\r\n"); 00249 #endif 00250 return Success; 00251 } 00252 00253 00254 #endif
Generated on Wed Jul 13 2022 04:24:00 by 1.7.2