IAP code for Freescale platforms

Dependents:   18_PT1000 RDA5807M-FM-Radio flashaccess TF_conops_BAEFLAGIMAN ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers FreescaleIAP.cpp Source File

FreescaleIAP.cpp

00001 #include "FreescaleIAP.h"
00002 
00003 #ifdef TARGET_Freescale
00004 
00005 //#define IAPDEBUG
00006 
00007 #ifdef TARGET_K64F
00008 //For K64F
00009 #   include "MK64F12.h"
00010 #   define USE_ProgramPhrase 1
00011 #   define FTFA                        FTFE
00012 #   define FTFA_FSTAT_FPVIOL_MASK      FTFE_FSTAT_FPVIOL_MASK 
00013 #   define FTFA_FSTAT_ACCERR_MASK      FTFE_FSTAT_ACCERR_MASK
00014 #   define FTFA_FSTAT_RDCOLERR_MASK    FTFE_FSTAT_RDCOLERR_MASK
00015 #   define FTFA_FSTAT_CCIF_MASK        FTFE_FSTAT_CCIF_MASK
00016 #   define FTFA_FSTAT_MGSTAT0_MASK     FTFE_FSTAT_MGSTAT0_MASK
00017 #else
00018 //Different names used on at least the K20:
00019 #   ifndef FTFA_FSTAT_FPVIOL_MASK
00020 #       define FTFA                        FTFL
00021 #       define FTFA_FSTAT_FPVIOL_MASK      FTFL_FSTAT_FPVIOL_MASK 
00022 #       define FTFA_FSTAT_ACCERR_MASK      FTFL_FSTAT_ACCERR_MASK
00023 #       define FTFA_FSTAT_RDCOLERR_MASK    FTFL_FSTAT_RDCOLERR_MASK
00024 #       define FTFA_FSTAT_CCIF_MASK        FTFL_FSTAT_CCIF_MASK
00025 #       define FTFA_FSTAT_MGSTAT0_MASK     FTFL_FSTAT_MGSTAT0_MASK
00026 #   endif
00027 #endif
00028 
00029 
00030 enum FCMD {
00031     Read1s = 0x01,
00032     ProgramCheck = 0x02,
00033     ReadResource = 0x03,
00034     ProgramLongword = 0x06,
00035     ProgramPhrase = 0x07,    
00036     EraseSector = 0x09,
00037     Read1sBlock = 0x40,
00038     ReadOnce = 0x41,
00039     ProgramOnce = 0x43,
00040     EraseAll = 0x44,
00041     VerifyBackdoor = 0x45
00042     };
00043 
00044 inline void run_command(void);
00045 bool check_boundary(int address, unsigned int length);
00046 bool check_align(int address);
00047 IAPCode verify_erased(int address, unsigned int length);
00048 IAPCode check_error(void);
00049 IAPCode program_word(int address, char *data);
00050     
00051 IAPCode erase_sector(int address) {
00052     #ifdef IAPDEBUG
00053     printf("IAP: Erasing at %x\r\n", address);
00054     #endif
00055     if (check_align(address))
00056         return AlignError;
00057     
00058     //Setup command
00059     FTFA->FCCOB0 = EraseSector;
00060     FTFA->FCCOB1 = (address >> 16) & 0xFF;
00061     FTFA->FCCOB2 = (address >> 8) & 0xFF;
00062     FTFA->FCCOB3 = address & 0xFF;
00063     
00064     run_command();
00065     
00066     return check_error();
00067 }
00068 
00069 IAPCode program_flash(int address, char *data, unsigned int length) {
00070     #ifdef IAPDEBUG
00071     printf("IAP: Programming flash at %x with length %d\r\n", address, length);
00072     #endif
00073     if (check_align(address))
00074         return AlignError;
00075         
00076     IAPCode eraseCheck = verify_erased(address, length);
00077     if (eraseCheck != Success)
00078         return eraseCheck;
00079     
00080     IAPCode progResult;
00081 #ifdef USE_ProgramPhrase
00082     for (int i = 0; i < length; i+=8) {
00083         progResult = program_word(address + i, data + i);
00084         if (progResult != Success)
00085             return progResult;
00086     }
00087 #else
00088     for (int i = 0; i < length; i+=4) {
00089         progResult = program_word(address + i, data + i);
00090         if (progResult != Success)
00091             return progResult;
00092     }
00093 #endif    
00094     return Success;
00095 }
00096 
00097 uint32_t flash_size(void) {
00098     uint32_t retval = (SIM->FCFG2 & 0x7F000000u) >> (24-13);
00099     if (SIM->FCFG2 & (1<<23))           //Possible second flash bank
00100         retval += (SIM->FCFG2 & 0x007F0000u) >> (16-13);
00101     return retval;
00102 }
00103 
00104 IAPCode program_word(int address, char *data) {
00105     #ifdef IAPDEBUG
00106     #ifdef USE_ProgramPhrase
00107     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]);
00108     #else
00109     printf("IAP: Programming word at %x, %d - %d - %d - %d\r\n", address, data[0], data[1], data[2], data[3]);
00110     #endif
00111     
00112     #endif
00113     if (check_align(address))
00114         return AlignError;
00115 #ifdef USE_ProgramPhrase
00116     FTFA->FCCOB0 = ProgramPhrase;
00117     FTFA->FCCOB1 = (address >> 16) & 0xFF;
00118     FTFA->FCCOB2 = (address >> 8) & 0xFF;
00119     FTFA->FCCOB3 = address & 0xFF;
00120     FTFA->FCCOB4 = data[3];
00121     FTFA->FCCOB5 = data[2];
00122     FTFA->FCCOB6 = data[1];
00123     FTFA->FCCOB7 = data[0];
00124     FTFA->FCCOB8 = data[7];
00125     FTFA->FCCOB9 = data[6];
00126     FTFA->FCCOBA = data[5];
00127     FTFA->FCCOBB = data[4];    
00128 #else
00129     //Setup command
00130     FTFA->FCCOB0 = ProgramLongword;
00131     FTFA->FCCOB1 = (address >> 16) & 0xFF;
00132     FTFA->FCCOB2 = (address >> 8) & 0xFF;
00133     FTFA->FCCOB3 = address & 0xFF;
00134     FTFA->FCCOB4 = data[3];
00135     FTFA->FCCOB5 = data[2];
00136     FTFA->FCCOB6 = data[1];
00137     FTFA->FCCOB7 = data[0];
00138 #endif    
00139     run_command();
00140     
00141     return check_error();
00142 }
00143 
00144 /* Clear possible flags which are set, run command, wait until done */
00145 inline void run_command(void) {
00146     //Clear possible old errors, start command, wait until done
00147     __disable_irq();            //Disable IRQs, preventing IRQ routines from trying to access flash (thanks to https://mbed.org/users/mjr/)
00148     FTFA->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK;
00149     FTFA->FSTAT = FTFA_FSTAT_CCIF_MASK;
00150     while (!(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK));
00151     __enable_irq();
00152 }    
00153     
00154     
00155 
00156 /* Check if no flash boundary is violated
00157    Returns true on violation */
00158 bool check_boundary(int address, unsigned int length) {
00159     int temp = (address+length - 1) / SECTOR_SIZE;
00160     address /= SECTOR_SIZE;
00161     bool retval = (address != temp);
00162     #ifdef IAPDEBUG
00163     if (retval)
00164         printf("IAP: Boundary violation\r\n");
00165     #endif
00166     return retval;
00167 }
00168 
00169 /* Check if address is correctly aligned
00170    Returns true on violation */
00171 bool check_align(int address) {
00172     bool retval = address & 0x03;
00173     #ifdef IAPDEBUG
00174     if (retval)
00175         printf("IAP: Alignment violation\r\n");
00176     #endif
00177     return retval;
00178 }
00179 
00180 /* Check if an area of flash memory is erased
00181    Returns error code or Success (in case of fully erased) */
00182 IAPCode verify_erased(int address, unsigned int length) {
00183     #ifdef IAPDEBUG
00184     printf("IAP: Verify erased at %x with length %d\r\n", address, length);
00185     #endif
00186     
00187     if (check_align(address))
00188         return AlignError;
00189     
00190     #ifdef USE_ProgramPhrase
00191     //Check erase is per 16 bytes, we round up
00192     length = (length + 15) >> 4;
00193     #else
00194     //Otherwise per 4 byte (should check if this is true)
00195     length = (length + 3) >> 2;
00196     #endif
00197     
00198     //Setup command
00199     FTFA->FCCOB0 = Read1s;
00200     FTFA->FCCOB1 = (address >> 16) & 0xFF;
00201     FTFA->FCCOB2 = (address >> 8) & 0xFF;
00202     FTFA->FCCOB3 = address & 0xFF;
00203     FTFA->FCCOB4 = (length >> 8) & 0xFF;
00204     FTFA->FCCOB5 = length & 0xFF;
00205     FTFA->FCCOB6 = 0;
00206     
00207     run_command();
00208     
00209     IAPCode retval = check_error();
00210     if (retval == RuntimeError) {
00211         #ifdef IAPDEBUG
00212         printf("IAP: Flash was not erased\r\n");
00213         #endif
00214         return EraseError;
00215     }
00216     return retval;
00217         
00218 }
00219 
00220 /* Check if an error occured 
00221    Returns error code or Success*/
00222 IAPCode check_error(void) {
00223     if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) {
00224         #ifdef IAPDEBUG
00225         printf("IAP: Protection violation\r\n");
00226         #endif
00227         return ProtectionError;
00228     }
00229     if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) {
00230         #ifdef IAPDEBUG
00231         printf("IAP: Flash access error\r\n");
00232         #endif
00233         return AccessError;
00234     }
00235     if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) {
00236         #ifdef IAPDEBUG
00237         printf("IAP: Collision error\r\n");
00238         #endif
00239         return CollisionError;
00240     }
00241     if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) {
00242         #ifdef IAPDEBUG
00243         printf("IAP: Runtime error\r\n");
00244         #endif
00245         return RuntimeError;
00246     }
00247     #ifdef IAPDEBUG
00248     printf("IAP: No error reported\r\n");
00249     #endif
00250     return Success;
00251 }
00252 
00253 
00254 #endif