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
00038 #define FLASHWRITE_C
00039 #include "inc/freeEMS.h"
00040 #include "inc/flashWrite.h"
00041 #include "inc/flashBurn.h"
00042 #include "inc/commsISRs.h"
00043 #include "inc/commsCore.h"
00044 #include <string.h>
00045
00046
00063 unsigned short eraseSector(unsigned char PPage, unsigned short *flashAddr){
00064
00065 if (((unsigned short)flashAddr % flashSectorSize) != 0){
00066 return addressNotSectorAligned;
00067 }
00068 unsigned char currentPage = PPAGE;
00069 PPAGE = PPage;
00070 FSTAT = (PVIOL|ACCERR);
00071 (*flashAddr) = 0xFFFF;
00072 PPAGE = currentPage;
00073 FCMD = SECTOR_ERASE;
00074 StackBurner();
00075
00076
00077 return 0;
00078 }
00079
00080
00107 unsigned short writeBlock(blockDetails* details, void* buffer){
00108 unsigned char sectors;
00109 unsigned char RAMPage;
00110
00111 unsigned short* RAMAddress;
00112 unsigned short* FlashAddress;
00113
00114
00115 if(details->size == 0){
00116 return sizeOfBlockToBurnIsZero;
00117 }else if(details->size < 1024){
00118 unsigned short chunkFlashAddress = (unsigned short)details->FlashAddress;
00119
00120 unsigned short offset = chunkFlashAddress % flashSectorSize;
00121
00122
00123 if((offset + details->size) > 1024){
00124 return smallBlockCrossesSectorBoundary;
00125 }
00126
00127
00128 sectors = 1;
00129 RAMPage = RPAGE;
00130 RAMAddress = buffer;
00131 FlashAddress = (unsigned short*)(chunkFlashAddress - offset);
00132
00133
00134
00135
00136 unsigned char oldFlashPage = PPAGE;
00137 PPAGE = details->FlashPage;
00138
00139
00140 if(offset != 0){
00141 memcpy(buffer, FlashAddress, offset);
00142 buffer += offset;
00143 }
00144
00145
00146 unsigned char oldRAMPage = RPAGE;
00147 RPAGE = details->RAMPage;
00148 memcpy(buffer, details->RAMAddress, details->size);
00149 buffer += details->size;
00150 RPAGE = oldRAMPage;
00151
00152
00153 if((offset + details->size) < 1024){
00154 void* chunkFlashEndAddress = details->FlashAddress + details->size;
00155 memcpy(buffer, chunkFlashEndAddress, (1024 - (offset + details->size)));
00156 }
00157
00158
00159 PPAGE = oldFlashPage;
00160 } else {
00161
00162 if((details->size % flashSectorSize) != 0){
00163 return sizeNotMultipleOfSectorSize;
00164 }
00165
00166
00167 sectors = details->size / flashSectorSize;
00168 RAMPage = details->RAMPage;
00169 RAMAddress = (unsigned short*)details->RAMAddress;
00170 FlashAddress = (unsigned short*)details->FlashAddress;
00171 }
00172
00173 unsigned char i;
00174 for(i=0;i<sectors;i++){
00175 unsigned short errorID = writeSector(RAMPage, RAMAddress, details->FlashPage, FlashAddress);
00176 if(errorID != 0){
00177 return errorID;
00178 }
00179
00180 RAMAddress += flashSectorSizeInWords;
00181 FlashAddress += flashSectorSizeInWords;
00182 }
00183 return 0;
00184 }
00185
00186
00205 unsigned short writeSector(unsigned char RPage, unsigned short* RAMSourceAddress, unsigned char PPage , unsigned short* flashDestinationAddress){
00206
00207 if(((unsigned short)flashDestinationAddress % flashSectorSize) != 0){
00208 return addressNotSectorAligned;
00209 }
00210
00211 if(((unsigned short)flashDestinationAddress) < 0x4000){
00212 return addressNotFlashRegion;
00213 }
00214
00216 eraseSector((unsigned char)PPage, (unsigned short*)flashDestinationAddress);
00217
00218 unsigned short wordCount = flashSectorSizeInWords;
00219
00220
00221 unsigned char currentRPage = RPAGE;
00222 unsigned char currentPPage = PPAGE;
00223
00224
00225 RPAGE = RPage;
00226 PPAGE = PPage;
00227
00228 while (wordCount > 0)
00229 {
00230 unsigned short sourceData = *RAMSourceAddress;
00231 unsigned short errorID = writeWord(flashDestinationAddress, sourceData);
00232 if(errorID != 0){
00233 return errorID;
00234 }
00235 RAMSourceAddress++;
00236 flashDestinationAddress++;
00237 wordCount--;
00238 }
00239
00240
00241 RPAGE = currentRPage;
00242 PPAGE = currentPPage;
00243 return 0;
00244 }
00245
00246
00264 unsigned short writeWord(unsigned short* flashDestination, unsigned short data){
00265 if((unsigned short)flashDestination & 0x0001){
00266 return addressNotWordAligned;
00267 }
00268
00269 FSTAT=(ACCERR | PVIOL);
00270 *flashDestination = data;
00271 FCMD = WORD_PROGRAM;
00272 StackBurner();
00273
00274 return 0;
00275 }