flashWrite.c

Go to the documentation of this file.
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 }

Generated on Mon Nov 10 21:18:50 2008 for freeems by  doxygen 1.5.2