A fork of Erik Olieman's bootloader for the KL05Z32. The bootloader is placed in the 29th sector allowing for 28kB of program memory. The 32nd sector is left empty after the bootloader to allow for use of the non volatile storage without the risk of overwriting it during serial firmware update.
Fork of Bootloader_K64F by
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_0x7268"))) 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_0x7300"))) 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_0x7500"))) 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_0x7600"))) 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_0x7700"))) inline 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_0x7800"))) 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_0x7900"))) 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_0x7A00"))) 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_0x7B00"))) 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 Thu Jul 14 2022 03:27:57 by 1.7.2