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