ec521

Dependencies:   mbed

Committer:
gaving
Date:
Sun Apr 22 19:20:10 2018 +0000
Revision:
0:e2f78ce2a5cf
For EC521 only

Who changed what in which revision?

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