.

Dependencies:   mbed EthernetInterface mbed-rtos

Fork of Bootloader_K64F by Erik -

Committer:
Sissors
Date:
Thu Mar 12 19:04:30 2015 +0000
Revision:
2:8c44f28c122c
Parent:
1:782a3ddc329e
Child:
4:8d109a566486
v0.9, works on K20 :D

Who changed what in which revision?

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