This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088

Dependents:   MbedFileServer_1768MiniDK2 RedWireBridge IssueDebug_gcc MiMicRemoteMCU-for-Mbed ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers K64F_IAP.c Source File

K64F_IAP.c

00001 /**
00002  * Copyright 2014 MiMicProject
00003  * Licensed under the Apache License, Version 2.0 (the "License");
00004  * you may not use this file except in compliance with the License.
00005  * You may obtain a copy of the License at
00006  * 
00007  *     http://www.apache.org/licenses/LICENSE-2.0
00008  * 
00009  * Unless required by applicable law or agreed to in writing, software
00010  * distributed under the License is distributed on an "AS IS" BASIS,
00011  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012  * See the License for the specific language governing permissions and
00013  * limitations under the License.
00014  */
00015 /**
00016  * This file based on https://mbed.org/users/Sissors/code/FreescaleIAP/
00017  */
00018 #include "NyLPC_config.h"
00019 #if NyLPC_MCU==NyLPC_MCU_K64F
00020 #include "K64F_IAP.h"
00021 //For K64F
00022 #   include "MK64F12.h"
00023 #   define USE_ProgramPhrase 1
00024 #   define FTFA                        FTFE
00025 #   define FTFA_FSTAT_FPVIOL_MASK      FTFE_FSTAT_FPVIOL_MASK 
00026 #   define FTFA_FSTAT_ACCERR_MASK      FTFE_FSTAT_ACCERR_MASK
00027 #   define FTFA_FSTAT_RDCOLERR_MASK    FTFE_FSTAT_RDCOLERR_MASK
00028 #   define FTFA_FSTAT_CCIF_MASK        FTFE_FSTAT_CCIF_MASK
00029 #   define FTFA_FSTAT_MGSTAT0_MASK     FTFE_FSTAT_MGSTAT0_MASK
00030 
00031 enum FCMD {
00032     Read1s = 0x01,
00033     ProgramCheck = 0x02,
00034     ReadResource = 0x03,
00035     ProgramLongword = 0x06,
00036     ProgramPhrase = 0x07,    
00037     EraseSector = 0x09,
00038     Read1sBlock = 0x40,
00039     ReadOnce = 0x41,
00040     ProgramOnce = 0x43,
00041     EraseAll = 0x44,
00042     VerifyBackdoor = 0x45
00043     };
00044 
00045 
00046 #define INT_FALSE (0!=0)
00047 #define INT_TRUE (0==0)
00048 
00049 static inline void run_command(void);
00050 //static int check_boundary(int address, unsigned int length);
00051 static int check_align(int address);
00052 
00053 static K64F_IAP_TIAPCode verify_erased(int address, unsigned int length);
00054 static K64F_IAP_TIAPCode check_error(void);
00055 static K64F_IAP_TIAPCode program_word(int address, char *data);
00056     
00057 K64F_IAP_TIAPCode K64F_IAP_erase_sector(int address) {
00058     #ifdef IAPDEBUG
00059     printf("IAP: Erasing at %x\r\n", address);
00060     #endif
00061     if (check_align(address))
00062         return K64F_IAP_TIAPCode_AlignError;
00063     
00064     //Setup command
00065     FTFA->FCCOB0 = EraseSector;
00066     FTFA->FCCOB1 = (address >> 16) & 0xFF;
00067     FTFA->FCCOB2 = (address >> 8) & 0xFF;
00068     FTFA->FCCOB3 = address & 0xFF;
00069     
00070     run_command();
00071     
00072     return check_error();
00073 }
00074 
00075 K64F_IAP_TIAPCode K64F_IAP_program_flash(int address, char *data, unsigned int length) {
00076     #ifdef IAPDEBUG
00077     printf("IAP: Programming flash at %x with length %d\r\n", address, length);
00078     #endif
00079     if (check_align(address))
00080         return K64F_IAP_TIAPCode_AlignError;
00081         
00082     K64F_IAP_TIAPCode eraseCheck = verify_erased(address, length);
00083     if (eraseCheck != K64F_IAP_TIAPCode_Success)
00084         return eraseCheck;
00085     
00086     K64F_IAP_TIAPCode progResult;
00087     for (int i = 0; i < length; i+=8) {
00088         progResult = program_word(address + i, data + i);
00089         if (progResult != K64F_IAP_TIAPCode_Success)
00090             return progResult;
00091     }
00092     return K64F_IAP_TIAPCode_Success;
00093 }
00094 
00095 unsigned int K64F_IAP_flash_size(void) {
00096     unsigned int 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 static K64F_IAP_TIAPCode program_word(int address, char *data) {
00103     #ifdef IAPDEBUG
00104     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]);
00105     #endif
00106     if (check_align(address)){
00107         return K64F_IAP_TIAPCode_AlignError;
00108     }
00109     FTFA->FCCOB0 = ProgramPhrase;
00110     FTFA->FCCOB1 = (address >> 16) & 0xFF;
00111     FTFA->FCCOB2 = (address >> 8) & 0xFF;
00112     FTFA->FCCOB3 = address & 0xFF;
00113     FTFA->FCCOB4 = data[3];
00114     FTFA->FCCOB5 = data[2];
00115     FTFA->FCCOB6 = data[1];
00116     FTFA->FCCOB7 = data[0];
00117     FTFA->FCCOB8 = data[7];
00118     FTFA->FCCOB9 = data[6];
00119     FTFA->FCCOBA = data[5];
00120     FTFA->FCCOBB = data[4];    
00121     run_command();    
00122     return check_error();
00123 }
00124 
00125 /* Clear possible flags which are set, run command, wait until done */
00126 static inline void run_command(void) {
00127     //Clear possible old errors, start command, wait until done
00128     __disable_irq();            //Disable IRQs, preventing IRQ routines from trying to access flash (thanks to https://mbed.org/users/mjr/)
00129     FTFA->FSTAT = FTFA_FSTAT_FPVIOL_MASK | FTFA_FSTAT_ACCERR_MASK | FTFA_FSTAT_RDCOLERR_MASK;
00130     FTFA->FSTAT = FTFA_FSTAT_CCIF_MASK;
00131     while (!(FTFA->FSTAT & FTFA_FSTAT_CCIF_MASK));
00132     __enable_irq();
00133 }    
00134     
00135     
00136 
00137 /* Check if no flash boundary is violated
00138    Returns true on violation *//*
00139 static int check_boundary(int address, unsigned int length) {
00140     int temp = (address+length - 1) / K64F_IAP_SECTOR_SIZE;
00141     address /= K64F_IAP_SECTOR_SIZE;
00142     int retval = (address != temp);
00143     #ifdef IAPDEBUG
00144     if (retval)
00145         printf("IAP: Boundary violation\r\n");
00146     #endif
00147     return retval;
00148 }*/
00149 
00150 /* Check if address is correctly aligned
00151    Returns true on violation */
00152 static int check_align(int address) {
00153     int retval = address & 0x03;
00154     #ifdef IAPDEBUG
00155     if (retval)
00156         printf("IAP: Alignment violation\r\n");
00157     #endif
00158     return retval;
00159 }
00160 
00161 /* Check if an area of flash memory is erased
00162    Returns error code or Success (in case of fully erased) */
00163 static K64F_IAP_TIAPCode verify_erased(int address, unsigned int length) {
00164     #ifdef IAPDEBUG
00165     printf("IAP: Verify erased at %x with length %d\r\n", address, length);
00166     #endif
00167     
00168     if (check_align(address)){
00169         return K64F_IAP_TIAPCode_AlignError;
00170     }
00171     
00172     //Setup command
00173     FTFA->FCCOB0 = Read1s;
00174     FTFA->FCCOB1 = (address >> 16) & 0xFF;
00175     FTFA->FCCOB2 = (address >> 8) & 0xFF;
00176     FTFA->FCCOB3 = address & 0xFF;
00177     FTFA->FCCOB4 = (length >> 10) & 0xFF;
00178     FTFA->FCCOB5 = (length >> 2) & 0xFF;
00179     FTFA->FCCOB6 = 0;
00180     
00181     run_command();
00182     
00183     K64F_IAP_TIAPCode retval = check_error();
00184     if (retval == K64F_IAP_TIAPCode_RuntimeError) {
00185         #ifdef IAPDEBUG
00186         printf("IAP: Flash was not erased\r\n");
00187         #endif
00188         return K64F_IAP_TIAPCode_EraseError;
00189     }
00190     return retval;        
00191 }
00192 
00193 /* Check if an error occured 
00194    Returns error code or Success*/
00195 static K64F_IAP_TIAPCode check_error(void) {
00196     if (FTFA->FSTAT & FTFA_FSTAT_FPVIOL_MASK) {
00197         #ifdef IAPDEBUG
00198         printf("IAP: Protection violation\r\n");
00199         #endif
00200         return K64F_IAP_TIAPCode_ProtectionError;
00201     }
00202     if (FTFA->FSTAT & FTFA_FSTAT_ACCERR_MASK) {
00203         #ifdef IAPDEBUG
00204         printf("IAP: Flash access error\r\n");
00205         #endif
00206         return K64F_IAP_TIAPCode_AccessError;
00207     }
00208     if (FTFA->FSTAT & FTFA_FSTAT_RDCOLERR_MASK) {
00209         #ifdef IAPDEBUG
00210         printf("IAP: Collision error\r\n");
00211         #endif
00212         return K64F_IAP_TIAPCode_CollisionError;
00213     }
00214     if (FTFA->FSTAT & FTFA_FSTAT_MGSTAT0_MASK) {
00215         #ifdef IAPDEBUG
00216         printf("IAP: Runtime error\r\n");
00217         #endif
00218         return K64F_IAP_TIAPCode_RuntimeError;
00219     }
00220     #ifdef IAPDEBUG
00221     printf("IAP: No error reported\r\n");
00222     #endif
00223     return K64F_IAP_TIAPCode_Success;
00224 }
00225 #endif