.

Dependencies:   mbed EthernetInterface mbed-rtos

Fork of Bootloader_K64F by Erik -

Committer:
Sissors
Date:
Sat Apr 23 18:24:07 2016 +0000
Revision:
8:00cefe0d59ed
Basic functionality works over HTTP!

Who changed what in which revision?

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