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

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FreescaleIAP.cpp Source File

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 __attribute__((section(".ARM.__at_0x5E500"))) 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_0x5E000"))) 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_0x5E100"))) 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_0x5E300"))) 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_0x5E400"))) 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_0x5E500"))) 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_0x5E600"))) 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_0x5E700"))) 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_0x5E800"))) 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_0x5E900"))) 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 }