00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00039 #define FLASHWRITE_C
00040 #include "inc/freeEMS.h"
00041 #include "inc/utils.h"
00042 #include "inc/flashWrite.h"
00043 #include "inc/flashBurn.h"
00044 #include "inc/commsISRs.h"
00045 #include "inc/commsCore.h"
00046 #include <string.h>
00047
00048
00065 unsigned short eraseSector(unsigned char PPage, unsigned short *flashAddr){
00066
00067 if (((unsigned short)flashAddr % flashSectorSize) != 0){
00068 return addressNotSectorAligned;
00069 }
00070 unsigned char currentPage = PPAGE;
00071 PPAGE = PPage;
00072 FSTAT = (PVIOL|ACCERR);
00073 (*flashAddr) = 0xFFFF;
00074 PPAGE = currentPage;
00075 FCMD = SECTOR_ERASE;
00076 StackBurner();
00077
00078
00079
00080 return 0;
00081 }
00082
00083
00110 unsigned short writeBlock(blockDetails* details, void* buffer){
00111 unsigned char sectors;
00112 unsigned char RAMPage;
00113
00114 unsigned short* RAMAddress;
00115 unsigned short* FlashAddress;
00116
00117
00118 if(details->size == 0){
00119 return sizeOfBlockToBurnIsZero;
00120 }else if(details->size < 1024){
00121 unsigned short chunkFlashAddress = (unsigned short)details->FlashAddress;
00122
00123 unsigned short offset = chunkFlashAddress % flashSectorSize;
00124
00125
00126 if((offset + details->size) > 1024){
00127 return smallBlockCrossesSectorBoundary;
00128 }
00129
00130
00131 sectors = 1;
00132 RAMPage = RPAGE;
00133 RAMAddress = buffer;
00134 FlashAddress = (unsigned short*)(chunkFlashAddress - offset);
00135
00136
00137
00138
00139 unsigned char oldFlashPage = PPAGE;
00140 PPAGE = details->FlashPage;
00141
00142
00143 if(offset != 0){
00144 memcpy(buffer, FlashAddress, offset);
00145 buffer += offset;
00146 }
00147
00148
00149 unsigned char oldRAMPage = RPAGE;
00150 RPAGE = details->RAMPage;
00151 memcpy(buffer, details->RAMAddress, details->size);
00152 buffer += details->size;
00153 RPAGE = oldRAMPage;
00154
00155
00156 if((offset + details->size) < 1024){
00157 void* chunkFlashEndAddress = details->FlashAddress + details->size;
00158 memcpy(buffer, chunkFlashEndAddress, (1024 - (offset + details->size)));
00159 }
00160
00161
00162 PPAGE = oldFlashPage;
00163 } else {
00164
00165 if((details->size % flashSectorSize) != 0){
00166 return sizeNotMultipleOfSectorSize;
00167 }
00168
00169
00170 sectors = details->size / flashSectorSize;
00171 RAMPage = details->RAMPage;
00172 RAMAddress = (unsigned short*)details->RAMAddress;
00173 FlashAddress = (unsigned short*)details->FlashAddress;
00174 }
00175
00176 unsigned char i;
00177 for(i=0;i<sectors;i++){
00178 unsigned short errorID = writeSector(RAMPage, RAMAddress, details->FlashPage, FlashAddress);
00179 if(errorID != 0){
00180 return errorID;
00181 }
00182
00183 RAMAddress += flashSectorSizeInWords;
00184 FlashAddress += flashSectorSizeInWords;
00185 }
00186
00187 return 0;
00188 }
00189
00190
00209 unsigned short writeSector(unsigned char RPage, unsigned short* RAMSourceAddress, unsigned char PPage , unsigned short* flashDestinationAddress){
00210
00211 if(((unsigned short)flashDestinationAddress % flashSectorSize) != 0){
00212 return addressNotSectorAligned;
00213 }
00214
00215 if(((unsigned short)flashDestinationAddress) < 0x4000){
00216 return addressNotFlashRegion;
00217 }
00218
00220 eraseSector((unsigned char)PPage, (unsigned short*)flashDestinationAddress);
00221
00222 unsigned short wordCount = flashSectorSizeInWords;
00223
00224
00225 unsigned char currentRPage = RPAGE;
00226 unsigned char currentPPage = PPAGE;
00227
00228
00229 RPAGE = RPage;
00230 PPAGE = PPage;
00231
00232 while (wordCount > 0)
00233 {
00234 unsigned short sourceData = *RAMSourceAddress;
00235 unsigned short errorID = writeWord(flashDestinationAddress, sourceData);
00236 if(errorID != 0){
00237 return errorID;
00238 }
00239 RAMSourceAddress++;
00240 flashDestinationAddress++;
00241 wordCount--;
00242 }
00243
00244
00245 RPAGE = currentRPage;
00246 PPAGE = currentPPage;
00247
00248 return 0;
00249 }
00250
00251
00269 unsigned short writeWord(unsigned short* flashDestination, unsigned short data){
00270 if((unsigned short)flashDestination & 0x0001){
00271 return addressNotWordAligned;
00272 }
00273
00274 FSTAT=(ACCERR | PVIOL);
00275 *flashDestination = data;
00276 FCMD = WORD_PROGRAM;
00277 StackBurner();
00278
00279
00280 return 0;
00281 }