This program hasn't been modified yet it breaks my FRDMK64 board

Dependencies:   mbed

Committer:
STEPHER2
Date:
Fri Jan 06 11:11:18 2017 +0000
Revision:
1:03c972a91ee2
Parent:
0:b963b1cb4a1a
Latest with flash clock enable

Who changed what in which revision?

UserRevisionLine numberNew contents of line
STEPHER2 0:b963b1cb4a1a 1 #include "FreescaleIAP.h"
STEPHER2 0:b963b1cb4a1a 2
STEPHER2 1:03c972a91ee2 3 //#define IAPDEBUG
STEPHER2 0:b963b1cb4a1a 4
STEPHER2 0:b963b1cb4a1a 5 #ifdef TARGET_K64F
STEPHER2 0:b963b1cb4a1a 6 //For K64F
STEPHER2 0:b963b1cb4a1a 7 # include "MK64F12.h"
STEPHER2 0:b963b1cb4a1a 8 # define USE_ProgramPhrase 1
STEPHER2 0:b963b1cb4a1a 9 # define FTFA FTFE
STEPHER2 0:b963b1cb4a1a 10 # define FTFA_FSTAT_FPVIOL_MASK FTFE_FSTAT_FPVIOL_MASK
STEPHER2 0:b963b1cb4a1a 11 # define FTFA_FSTAT_ACCERR_MASK FTFE_FSTAT_ACCERR_MASK
STEPHER2 0:b963b1cb4a1a 12 # define FTFA_FSTAT_RDCOLERR_MASK FTFE_FSTAT_RDCOLERR_MASK
STEPHER2 0:b963b1cb4a1a 13 # define FTFA_FSTAT_CCIF_MASK FTFE_FSTAT_CCIF_MASK
STEPHER2 0:b963b1cb4a1a 14 # define FTFA_FSTAT_MGSTAT0_MASK FTFE_FSTAT_MGSTAT0_MASK
STEPHER2 0:b963b1cb4a1a 15 #else
STEPHER2 0:b963b1cb4a1a 16 //Different names used on at least the K20:
STEPHER2 0:b963b1cb4a1a 17 # ifndef FTFA_FSTAT_FPVIOL_MASK
STEPHER2 0:b963b1cb4a1a 18 # define FTFA FTFL
STEPHER2 0:b963b1cb4a1a 19 # define FTFA_FSTAT_FPVIOL_MASK FTFL_FSTAT_FPVIOL_MASK
STEPHER2 0:b963b1cb4a1a 20 # define FTFA_FSTAT_ACCERR_MASK FTFL_FSTAT_ACCERR_MASK
STEPHER2 0:b963b1cb4a1a 21 # define FTFA_FSTAT_RDCOLERR_MASK FTFL_FSTAT_RDCOLERR_MASK
STEPHER2 0:b963b1cb4a1a 22 # define FTFA_FSTAT_CCIF_MASK FTFL_FSTAT_CCIF_MASK
STEPHER2 0:b963b1cb4a1a 23 # define FTFA_FSTAT_MGSTAT0_MASK FTFL_FSTAT_MGSTAT0_MASK
STEPHER2 0:b963b1cb4a1a 24 # endif
STEPHER2 0:b963b1cb4a1a 25 #endif
STEPHER2 0:b963b1cb4a1a 26
STEPHER2 0:b963b1cb4a1a 27
STEPHER2 0:b963b1cb4a1a 28 enum FCMD {
STEPHER2 0:b963b1cb4a1a 29 Read1s = 0x01,
STEPHER2 0:b963b1cb4a1a 30 ProgramCheck = 0x02,
STEPHER2 0:b963b1cb4a1a 31 ReadResource = 0x03,
STEPHER2 0:b963b1cb4a1a 32 ProgramLongword = 0x06,
STEPHER2 0:b963b1cb4a1a 33 ProgramPhrase = 0x07,
STEPHER2 0:b963b1cb4a1a 34 EraseSector = 0x09,
STEPHER2 0:b963b1cb4a1a 35 Read1sBlock = 0x40,
STEPHER2 0:b963b1cb4a1a 36 ReadOnce = 0x41,
STEPHER2 0:b963b1cb4a1a 37 ProgramOnce = 0x43,
STEPHER2 0:b963b1cb4a1a 38 EraseAll = 0x44,
STEPHER2 0:b963b1cb4a1a 39 VerifyBackdoor = 0x45
STEPHER2 0:b963b1cb4a1a 40 };
STEPHER2 0:b963b1cb4a1a 41
STEPHER2 0:b963b1cb4a1a 42 __attribute__((section(".ARM.__at_0x5E500"))) inline void run_command(void);
STEPHER2 0:b963b1cb4a1a 43 bool check_boundary(int address, unsigned int length);
STEPHER2 0:b963b1cb4a1a 44 bool check_align(int address);
STEPHER2 0:b963b1cb4a1a 45 IAPCode verify_erased(int address, unsigned int length);
STEPHER2 0:b963b1cb4a1a 46 IAPCode check_error(void);
STEPHER2 0:b963b1cb4a1a 47 IAPCode program_word(int address, char *data);
STEPHER2 0:b963b1cb4a1a 48
STEPHER2 0:b963b1cb4a1a 49 __attribute__((section(".ARM.__at_0x5E000"))) IAPCode erase_sector(int address) {
STEPHER2 0:b963b1cb4a1a 50 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 51 //printf("IAP: Erasing at %x\r\n", address);
STEPHER2 0:b963b1cb4a1a 52 #endif
STEPHER2 0:b963b1cb4a1a 53 if (check_align(address))
STEPHER2 0:b963b1cb4a1a 54 return AlignError;
STEPHER2 0:b963b1cb4a1a 55
STEPHER2 0:b963b1cb4a1a 56 //Setup command
STEPHER2 0:b963b1cb4a1a 57 FTFA->FCCOB0 = EraseSector;
STEPHER2 0:b963b1cb4a1a 58 FTFA->FCCOB1 = (address >> 16) & 0xFF;
STEPHER2 0:b963b1cb4a1a 59 FTFA->FCCOB2 = (address >> 8) & 0xFF;
STEPHER2 0:b963b1cb4a1a 60 FTFA->FCCOB3 = address & 0xFF;
STEPHER2 0:b963b1cb4a1a 61
STEPHER2 0:b963b1cb4a1a 62 run_command();
STEPHER2 0:b963b1cb4a1a 63
STEPHER2 0:b963b1cb4a1a 64 return check_error();
STEPHER2 0:b963b1cb4a1a 65 }
STEPHER2 0:b963b1cb4a1a 66
STEPHER2 0:b963b1cb4a1a 67 __attribute__((section(".ARM.__at_0x5E100"))) IAPCode program_flash(int address, char *data, unsigned int length) {
STEPHER2 0:b963b1cb4a1a 68 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 69 printf("IAP: Programming flash at %x with length %d\r\n", address, length);
STEPHER2 0:b963b1cb4a1a 70 #endif
STEPHER2 0:b963b1cb4a1a 71 if (check_align(address))
STEPHER2 0:b963b1cb4a1a 72 return AlignError;
STEPHER2 0:b963b1cb4a1a 73
STEPHER2 0:b963b1cb4a1a 74 IAPCode eraseCheck = verify_erased(address, length);
STEPHER2 0:b963b1cb4a1a 75 if (eraseCheck != Success)
STEPHER2 0:b963b1cb4a1a 76 return eraseCheck;
STEPHER2 0:b963b1cb4a1a 77
STEPHER2 0:b963b1cb4a1a 78 IAPCode progResult;
STEPHER2 0:b963b1cb4a1a 79 #ifdef USE_ProgramPhrase
STEPHER2 0:b963b1cb4a1a 80 for (int i = 0; i < length; i+=8) {
STEPHER2 0:b963b1cb4a1a 81 progResult = program_word(address + i, data + i);
STEPHER2 0:b963b1cb4a1a 82 if (progResult != Success)
STEPHER2 0:b963b1cb4a1a 83 return progResult;
STEPHER2 0:b963b1cb4a1a 84 }
STEPHER2 0:b963b1cb4a1a 85 #else
STEPHER2 0:b963b1cb4a1a 86 for (int i = 0; i < length; i+=4) {
STEPHER2 0:b963b1cb4a1a 87 progResult = program_word(address + i, data + i);
STEPHER2 0:b963b1cb4a1a 88 if (progResult != Success)
STEPHER2 0:b963b1cb4a1a 89 return progResult;
STEPHER2 0:b963b1cb4a1a 90 }
STEPHER2 0:b963b1cb4a1a 91 #endif
STEPHER2 0:b963b1cb4a1a 92 return Success;
STEPHER2 0:b963b1cb4a1a 93 }
STEPHER2 0:b963b1cb4a1a 94
STEPHER2 0:b963b1cb4a1a 95 __attribute__((section(".ARM.__at_0x5E300"))) uint32_t flash_size(void) {
STEPHER2 0:b963b1cb4a1a 96 uint32_t retval = (SIM->FCFG2 & 0x7F000000u) >> (24-13);
STEPHER2 0:b963b1cb4a1a 97 if (SIM->FCFG2 & (1<<23)) //Possible second flash bank
STEPHER2 0:b963b1cb4a1a 98 retval += (SIM->FCFG2 & 0x007F0000u) >> (16-13);
STEPHER2 0:b963b1cb4a1a 99 return retval;
STEPHER2 0:b963b1cb4a1a 100 }
STEPHER2 0:b963b1cb4a1a 101
STEPHER2 0:b963b1cb4a1a 102 __attribute__((section(".ARM.__at_0x5E400"))) IAPCode program_word(int address, char *data) {
STEPHER2 0:b963b1cb4a1a 103 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 104 #ifdef USE_ProgramPhrase
STEPHER2 0:b963b1cb4a1a 105 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]);
STEPHER2 0:b963b1cb4a1a 106 #else
STEPHER2 0:b963b1cb4a1a 107 printf("IAP: Programming word at %x, %d - %d - %d - %d\r\n", address, data[0], data[1], data[2], data[3]);
STEPHER2 0:b963b1cb4a1a 108 #endif
STEPHER2 0:b963b1cb4a1a 109
STEPHER2 0:b963b1cb4a1a 110 #endif
STEPHER2 0:b963b1cb4a1a 111 if (check_align(address))
STEPHER2 0:b963b1cb4a1a 112 return AlignError;
STEPHER2 0:b963b1cb4a1a 113 #ifdef USE_ProgramPhrase
STEPHER2 0:b963b1cb4a1a 114 FTFA->FCCOB0 = ProgramPhrase;
STEPHER2 0:b963b1cb4a1a 115 FTFA->FCCOB1 = (address >> 16) & 0xFF;
STEPHER2 0:b963b1cb4a1a 116 FTFA->FCCOB2 = (address >> 8) & 0xFF;
STEPHER2 0:b963b1cb4a1a 117 FTFA->FCCOB3 = address & 0xFF;
STEPHER2 0:b963b1cb4a1a 118 FTFA->FCCOB4 = data[3];
STEPHER2 0:b963b1cb4a1a 119 FTFA->FCCOB5 = data[2];
STEPHER2 0:b963b1cb4a1a 120 FTFA->FCCOB6 = data[1];
STEPHER2 0:b963b1cb4a1a 121 FTFA->FCCOB7 = data[0];
STEPHER2 0:b963b1cb4a1a 122 FTFA->FCCOB8 = data[7];
STEPHER2 0:b963b1cb4a1a 123 FTFA->FCCOB9 = data[6];
STEPHER2 0:b963b1cb4a1a 124 FTFA->FCCOBA = data[5];
STEPHER2 0:b963b1cb4a1a 125 FTFA->FCCOBB = data[4];
STEPHER2 0:b963b1cb4a1a 126 #else
STEPHER2 0:b963b1cb4a1a 127 //Setup command
STEPHER2 0:b963b1cb4a1a 128 FTFA->FCCOB0 = ProgramLongword;
STEPHER2 0:b963b1cb4a1a 129 FTFA->FCCOB1 = (address >> 16) & 0xFF;
STEPHER2 0:b963b1cb4a1a 130 FTFA->FCCOB2 = (address >> 8) & 0xFF;
STEPHER2 0:b963b1cb4a1a 131 FTFA->FCCOB3 = address & 0xFF;
STEPHER2 0:b963b1cb4a1a 132 FTFA->FCCOB4 = data[3];
STEPHER2 0:b963b1cb4a1a 133 FTFA->FCCOB5 = data[2];
STEPHER2 0:b963b1cb4a1a 134 FTFA->FCCOB6 = data[1];
STEPHER2 0:b963b1cb4a1a 135 FTFA->FCCOB7 = data[0];
STEPHER2 0:b963b1cb4a1a 136 #endif
STEPHER2 0:b963b1cb4a1a 137 run_command();
STEPHER2 0:b963b1cb4a1a 138
STEPHER2 0:b963b1cb4a1a 139 return check_error();
STEPHER2 0:b963b1cb4a1a 140 }
STEPHER2 0:b963b1cb4a1a 141
STEPHER2 0:b963b1cb4a1a 142 /* Clear possible flags which are set, run command, wait until done */
STEPHER2 0:b963b1cb4a1a 143 __attribute__((section(".ARM.__at_0x5E500"))) void run_command(void) {
STEPHER2 0:b963b1cb4a1a 144 //Clear possible old errors, start command, wait until done
STEPHER2 0:b963b1cb4a1a 145 __disable_irq(); //Disable IRQs, preventing IRQ routines from trying to access flash (thanks to https://mbed.org/users/mjr/)
STEPHER2 0:b963b1cb4a1a 146 FTFA->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK;
STEPHER2 0:b963b1cb4a1a 147 FTFA->FSTAT = FTFA_FSTAT_CCIF_MASK;
STEPHER2 0:b963b1cb4a1a 148 while (!(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK));
STEPHER2 0:b963b1cb4a1a 149 __enable_irq();
STEPHER2 0:b963b1cb4a1a 150 }
STEPHER2 0:b963b1cb4a1a 151
STEPHER2 0:b963b1cb4a1a 152
STEPHER2 0:b963b1cb4a1a 153
STEPHER2 0:b963b1cb4a1a 154 /* Check if no flash boundary is violated
STEPHER2 0:b963b1cb4a1a 155 Returns true on violation */
STEPHER2 0:b963b1cb4a1a 156 __attribute__((section(".ARM.__at_0x5E600"))) bool check_boundary(int address, unsigned int length) {
STEPHER2 0:b963b1cb4a1a 157 int temp = (address+length - 1) / SECTOR_SIZE;
STEPHER2 0:b963b1cb4a1a 158 address /= SECTOR_SIZE;
STEPHER2 0:b963b1cb4a1a 159 bool retval = (address != temp);
STEPHER2 0:b963b1cb4a1a 160 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 161 if (retval)
STEPHER2 0:b963b1cb4a1a 162 printf("IAP: Boundary violation\r\n");
STEPHER2 0:b963b1cb4a1a 163 #endif
STEPHER2 0:b963b1cb4a1a 164 return retval;
STEPHER2 0:b963b1cb4a1a 165 }
STEPHER2 0:b963b1cb4a1a 166
STEPHER2 0:b963b1cb4a1a 167 /* Check if address is correctly aligned
STEPHER2 0:b963b1cb4a1a 168 Returns true on violation */
STEPHER2 0:b963b1cb4a1a 169 __attribute__((section(".ARM.__at_0x5E700"))) bool check_align(int address) {
STEPHER2 0:b963b1cb4a1a 170 bool retval = address & 0x03;
STEPHER2 0:b963b1cb4a1a 171 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 172 if (retval)
STEPHER2 0:b963b1cb4a1a 173 printf("IAP: Alignment violation\r\n");
STEPHER2 0:b963b1cb4a1a 174 #endif
STEPHER2 0:b963b1cb4a1a 175 return retval;
STEPHER2 0:b963b1cb4a1a 176 }
STEPHER2 0:b963b1cb4a1a 177
STEPHER2 0:b963b1cb4a1a 178 /* Check if an area of flash memory is erased
STEPHER2 0:b963b1cb4a1a 179 Returns error code or Success (in case of fully erased) */
STEPHER2 0:b963b1cb4a1a 180 __attribute__((section(".ARM.__at_0x5E800"))) IAPCode verify_erased(int address, unsigned int length) {
STEPHER2 0:b963b1cb4a1a 181 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 182 printf("IAP: Verify erased at %x with length %d\r\n", address, length);
STEPHER2 0:b963b1cb4a1a 183 #endif
STEPHER2 0:b963b1cb4a1a 184
STEPHER2 0:b963b1cb4a1a 185 if (check_align(address))
STEPHER2 0:b963b1cb4a1a 186 return AlignError;
STEPHER2 0:b963b1cb4a1a 187
STEPHER2 0:b963b1cb4a1a 188 //Setup command
STEPHER2 0:b963b1cb4a1a 189 FTFA->FCCOB0 = Read1s;
STEPHER2 0:b963b1cb4a1a 190 FTFA->FCCOB1 = (address >> 16) & 0xFF;
STEPHER2 0:b963b1cb4a1a 191 FTFA->FCCOB2 = (address >> 8) & 0xFF;
STEPHER2 0:b963b1cb4a1a 192 FTFA->FCCOB3 = address & 0xFF;
STEPHER2 0:b963b1cb4a1a 193 FTFA->FCCOB4 = (length >> 10) & 0xFF;
STEPHER2 0:b963b1cb4a1a 194 FTFA->FCCOB5 = (length >> 2) & 0xFF;
STEPHER2 0:b963b1cb4a1a 195 FTFA->FCCOB6 = 0;
STEPHER2 0:b963b1cb4a1a 196
STEPHER2 0:b963b1cb4a1a 197 run_command();
STEPHER2 0:b963b1cb4a1a 198
STEPHER2 0:b963b1cb4a1a 199 IAPCode retval = check_error();
STEPHER2 0:b963b1cb4a1a 200 if (retval == RuntimeError) {
STEPHER2 0:b963b1cb4a1a 201 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 202 printf("IAP: Flash was not erased\r\n");
STEPHER2 0:b963b1cb4a1a 203 #endif
STEPHER2 0:b963b1cb4a1a 204 return EraseError;
STEPHER2 0:b963b1cb4a1a 205 }
STEPHER2 0:b963b1cb4a1a 206 return retval;
STEPHER2 0:b963b1cb4a1a 207
STEPHER2 0:b963b1cb4a1a 208 }
STEPHER2 0:b963b1cb4a1a 209
STEPHER2 0:b963b1cb4a1a 210 /* Check if an error occured
STEPHER2 0:b963b1cb4a1a 211 Returns error code or Success*/
STEPHER2 0:b963b1cb4a1a 212 __attribute__((section(".ARM.__at_0x5E900"))) IAPCode check_error(void) {
STEPHER2 0:b963b1cb4a1a 213 if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) {
STEPHER2 0:b963b1cb4a1a 214 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 215 printf("IAP: Protection violation\r\n");
STEPHER2 0:b963b1cb4a1a 216 #endif
STEPHER2 0:b963b1cb4a1a 217 return ProtectionError;
STEPHER2 0:b963b1cb4a1a 218 }
STEPHER2 0:b963b1cb4a1a 219 if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) {
STEPHER2 0:b963b1cb4a1a 220 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 221 printf("IAP: Flash access error\r\n");
STEPHER2 0:b963b1cb4a1a 222 #endif
STEPHER2 0:b963b1cb4a1a 223 return AccessError;
STEPHER2 0:b963b1cb4a1a 224 }
STEPHER2 0:b963b1cb4a1a 225 if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) {
STEPHER2 0:b963b1cb4a1a 226 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 227 printf("IAP: Collision error\r\n");
STEPHER2 0:b963b1cb4a1a 228 #endif
STEPHER2 0:b963b1cb4a1a 229 return CollisionError;
STEPHER2 0:b963b1cb4a1a 230 }
STEPHER2 0:b963b1cb4a1a 231 if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) {
STEPHER2 0:b963b1cb4a1a 232 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 233 printf("IAP: Runtime error\r\n");
STEPHER2 0:b963b1cb4a1a 234 #endif
STEPHER2 0:b963b1cb4a1a 235 return RuntimeError;
STEPHER2 0:b963b1cb4a1a 236 }
STEPHER2 0:b963b1cb4a1a 237 #ifdef IAPDEBUG
STEPHER2 0:b963b1cb4a1a 238 printf("IAP: No error reported\r\n");
STEPHER2 0:b963b1cb4a1a 239 #endif
STEPHER2 0:b963b1cb4a1a 240 return Success;
STEPHER2 0:b963b1cb4a1a 241 }