00001 /* flashWrite.c 00002 00003 Copyright 2008 Sean Keys 00004 00005 This file is part of the FreeEMS project. 00006 00007 FreeEMS software is free software: you can redistribute it and/or modify 00008 it under the terms of the GNU General Public License as published by 00009 the Free Software Foundation, either version 3 of the License, or 00010 (at your option) any later version. 00011 00012 FreeEMS software is distributed in the hope that it will be useful, 00013 but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 GNU General Public License for more details. 00016 00017 You should have received a copy of the GNU General Public License 00018 along with any FreeEMS software. If not, see <http://www.gnu.org/licenses/>. 00019 00020 We ask that if you make any changes to this file you send them upstream to us at admin@diyefi.org 00021 00022 Thank you for choosing FreeEMS to run your engine! */ 00023 00024 #define FLASHWRITE_C 00025 #include "inc/freeEMS.h" 00026 #include "inc/flashWrite.h" 00027 #include "inc/flashBurn.h" 00028 #include "inc/commsISRs.h" 00029 00030 00031 /**************************************************************************************************************/ 00032 /* 27.4.2.4 Sector Erase Command 00033 00034 The sector erase operation will erase all addresses in a 1 Kbyte sector of Flash memory using an embedded 00035 algorithm. 00036 00037 An example flow to execute the sector erase operation is shown in Figure 27-29. The sector erase 00038 command write sequence is as follows: 00039 00040 1. Write to a Flash block address to start the command write sequence for the sector erase command. 00041 The Flash address written determines the sector to be erased while global address bits [9:0] and the 00042 data written are ignored. Multiple Flash sectors can be simultaneously erased by writing to the 00043 same relative address in each Flash block. 00044 00045 2. Write the sector erase command, 0x40, to the FCMD register. 00046 00047 3. Clear the CBEIF flag in the FSTAT register by writing a 1 to CBEIF to launch the sector erase 00048 command. 00049 00050 If a Flash sector to be erased is in a protected area of the Flash block, the PVIOL flag in the FSTAT register 00051 will set and the sector erase command will not launch. Once the sector erase command has successfully 00052 launched, the CCIF flag in the FSTAT register will set after the sector erase operation has completed unless 00053 a new command write sequence has been buffered. */ 00054 unsigned char eraseSector(unsigned short *flashAddr){ 00055 unsigned short FlashSectorSize = 1024; 00056 00057 if ((unsigned short)flashAddr & 0x001){ 00058 return Flash_Address_Not_Aligned; 00059 } 00060 00061 if ((unsigned short)flashAddr % FlashSectorSize != 0){ 00062 return Address_Not_Start_Of_Flash_Sector; 00063 } 00064 00065 FSTAT = (PVIOL|ACCERR); /* clear any errors */ 00066 (*flashAddr) = 0xFFFF; /* Dummy data to first word of page to be erased it will write FFFF regardless with the erase command*/ 00067 FCMD = SECTOR_ERASE; /* set the flash command register mode to ERASE */ 00068 StackBurner(55); //PPAGE loaded into Register B, PPAGE to be implemented 55 is a dummy value 00069 00070 //TODO add return for accerr and pviol error bits 00071 00072 return Command_Successful; 00073 } 00074 00075 00076 /******************************************************************************* 00077 * writeBlock will use writeWord to write a 1k block from RAM to flash. 00078 * Give it the starting memory address and the destination flash address. 00079 * Both addresses will be incremented by 1 word after a successful writeWord, 00080 * until the whole 1024 byte sector has been written. Before any writing occurs 00081 * eraseSector is called to make sure the destination is blank. */ 00082 unsigned char writeAlignedBlock(unsigned short *flashAddr, unsigned short *RAMAddr){ 00083 00084 unsigned short offSet = 0x2000; //TODO Figure out why this offset is needed, without it it will always write 0x4000 below your target 00085 flashAddr = flashAddr + offSet; 00086 00087 if ((unsigned short)flashAddr % FlashSectorSize != 0){ 00088 return Address_Not_Start_Of_Flash_Sector; 00089 } 00090 00091 eraseSector((unsigned short*)flashAddr); /* First Erase our destination block */ 00092 unsigned short wordCount = 512; /* 512 words to a 1024k sector */ 00093 00094 while (wordCount > 0) 00095 { 00096 00097 unsigned short sourceData = *RAMAddr; /*Convert the RAMAddr to data(dereference) */ 00098 writeWord(flashAddr, sourceData); 00099 RAMAddr++; 00100 flashAddr++; 00101 ping(sourceData); // TODO figure out why this is needed ,without it it will not write 00102 wordCount--; /* Decrement our word counter */ 00103 } 00104 00105 return 1; 00106 } 00107 00108 void ping(unsigned short pong) 00109 { 00110 pong++; 00111 } 00112 /* 27.4.2.3 Program Command 00113 00114 The program operation will program a previously erased word in the Flash memory using an embedded 00115 algorithm. 00116 00117 An example flow to execute the program operation is shown in Figure 27-28. The program command write 00118 sequence is as follows: 00119 00120 1. Write to a Flash block address to start the command write sequence for the program command. The 00121 data written will be programmed to the address written. Multiple Flash blocks can be 00122 simultaneously programmed by writing to the same relative address in each Flash block. 00123 00124 2. Write the program command, 0x20, to the FCMD register. 00125 00126 3. Clear the CBEIF flag in the FSTAT register by writing a 1 to CBEIF to launch the program 00127 command. 00128 00129 If a word to be programmed is in a protected area of the Flash block, the PVIOL flag in the FSTAT register 00130 will set and the program command will not launch. Once the program command has successfully launched, 00131 the CCIF flag in the FSTAT register will set after the program operation has completed unless a new 00132 command write sequence has been buffered. By executing a new program command write sequence on 00133 sequential words after the CBEIF flag in the FSTAT register has been set, up to 55% faster programming 00134 time per word can be effectively achieved than by waiting for the CCIF flag to set after each program 00135 operation.*/ 00136 unsigned char writeWord(unsigned short *flashDestination, unsigned short data){ 00137 // TODO Create error check methods to get rid of redundant code 00138 if ((unsigned short)flashDestination & 0x0001){ 00139 return Flash_Address_Not_Aligned; 00140 } 00141 00142 FSTAT=(ACCERR | PVIOL); 00143 (*flashDestination)= data; 00144 FCMD = WORD_PROGRAM; //Load Flash Command Register With Word_Program mask 00145 StackBurner(55); //PPAGE loaded into Register B, PPAGE to be implemented 55 is a dummy value 00146 00147 return Command_Successful; 00148 }