Ryan Stephen
/
frdmk64_bootloader
This program hasn't been modified yet it breaks my FRDMK64 board
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 __attribute__((section(".ARM.__at_0x5E500"))) 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_0x5E000"))) 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_0x5E100"))) 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_0x5E300"))) 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_0x5E400"))) 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_0x5E500"))) void run_command(void) { 00144 //Clear possible old errors, start command, wait until done 00145 __disable_irq(); //Disable IRQs, preventing IRQ routines from trying to access flash (thanks to https://mbed.org/users/mjr/) 00146 FTFA->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK; 00147 FTFA->FSTAT = FTFA_FSTAT_CCIF_MASK; 00148 while (!(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK)); 00149 __enable_irq(); 00150 } 00151 00152 00153 00154 /* Check if no flash boundary is violated 00155 Returns true on violation */ 00156 __attribute__((section(".ARM.__at_0x5E600"))) bool check_boundary(int address, unsigned int length) { 00157 int temp = (address+length - 1) / SECTOR_SIZE; 00158 address /= SECTOR_SIZE; 00159 bool retval = (address != temp); 00160 #ifdef IAPDEBUG 00161 if (retval) 00162 printf("IAP: Boundary violation\r\n"); 00163 #endif 00164 return retval; 00165 } 00166 00167 /* Check if address is correctly aligned 00168 Returns true on violation */ 00169 __attribute__((section(".ARM.__at_0x5E700"))) bool check_align(int address) { 00170 bool retval = address & 0x03; 00171 #ifdef IAPDEBUG 00172 if (retval) 00173 printf("IAP: Alignment violation\r\n"); 00174 #endif 00175 return retval; 00176 } 00177 00178 /* Check if an area of flash memory is erased 00179 Returns error code or Success (in case of fully erased) */ 00180 __attribute__((section(".ARM.__at_0x5E800"))) IAPCode verify_erased(int address, unsigned int length) { 00181 #ifdef IAPDEBUG 00182 printf("IAP: Verify erased at %x with length %d\r\n", address, length); 00183 #endif 00184 00185 if (check_align(address)) 00186 return AlignError; 00187 00188 //Setup command 00189 FTFA->FCCOB0 = Read1s; 00190 FTFA->FCCOB1 = (address >> 16) & 0xFF; 00191 FTFA->FCCOB2 = (address >> 8) & 0xFF; 00192 FTFA->FCCOB3 = address & 0xFF; 00193 FTFA->FCCOB4 = (length >> 10) & 0xFF; 00194 FTFA->FCCOB5 = (length >> 2) & 0xFF; 00195 FTFA->FCCOB6 = 0; 00196 00197 run_command(); 00198 00199 IAPCode retval = check_error(); 00200 if (retval == RuntimeError) { 00201 #ifdef IAPDEBUG 00202 printf("IAP: Flash was not erased\r\n"); 00203 #endif 00204 return EraseError; 00205 } 00206 return retval; 00207 00208 } 00209 00210 /* Check if an error occured 00211 Returns error code or Success*/ 00212 __attribute__((section(".ARM.__at_0x5E900"))) IAPCode check_error(void) { 00213 if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) { 00214 #ifdef IAPDEBUG 00215 printf("IAP: Protection violation\r\n"); 00216 #endif 00217 return ProtectionError; 00218 } 00219 if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) { 00220 #ifdef IAPDEBUG 00221 printf("IAP: Flash access error\r\n"); 00222 #endif 00223 return AccessError; 00224 } 00225 if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) { 00226 #ifdef IAPDEBUG 00227 printf("IAP: Collision error\r\n"); 00228 #endif 00229 return CollisionError; 00230 } 00231 if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) { 00232 #ifdef IAPDEBUG 00233 printf("IAP: Runtime error\r\n"); 00234 #endif 00235 return RuntimeError; 00236 } 00237 #ifdef IAPDEBUG 00238 printf("IAP: No error reported\r\n"); 00239 #endif 00240 return Success; 00241 }
Generated on Wed Jul 13 2022 17:12:28 by 1.7.2