00001
00033 #include <ioavr.h>
00034 #include <inavr.h>
00035 #include "Self_programming.h"
00036
00043 #ifdef __FLASH_RECOVER
00044 __eeprom struct {
00045 unsigned int pageNumber;
00046 unsigned char status;
00047 }FlashBackup = {0};
00048 #endif
00049
00053 unsigned char ReadFlashByte(MyAddressType flashStartAdr){
00054 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00055 return (unsigned char)*((MyFlashCharPointer)flashStartAdr);
00056 #pragma diag_default=Pe1053 // Back to default.
00057 }
00058
00065 unsigned char ReadFlashPage(MyAddressType flashStartAdr, unsigned char *dataPage){
00066 unsigned int index;
00067 if(!(flashStartAdr & (PAGESIZE-1))){
00068 for(index = 0; index < PAGESIZE; index++){
00069 dataPage[index] = ReadFlashByte(flashStartAdr + index);
00070 }
00071 return TRUE;
00072 }
00073 else{
00074 return FALSE;
00075 }
00076 }
00077
00082 unsigned char WriteFlashByte(MyAddressType flashAddr, unsigned char data){
00083 MyAddressType pageAdr;
00084 unsigned char eepromInterruptSettings;
00085 if( AddressCheck( flashAddr & ~(PAGESIZE-1) )){
00086
00087 eepromInterruptSettings= EECR & (1<<EERIE);
00088 EECR &= ~(1<<EERIE);
00089 while(EECR & (1<<EEWE));
00090
00091 pageAdr=flashAddr & ~(PAGESIZE-1);
00092
00093 #ifdef __FLASH_RECOVER
00094 FlashBackup.status=0;
00095
00096 while(EECR & (1<<EEWE));
00097 LpmReplaceSpm(flashAddr, data);
00098 WriteBufToFlash(ADR_FLASH_BUFFER);
00099 FlashBackup.pageNumber = (unsigned int) (pageAdr/PAGESIZE);
00100
00101 FlashBackup.status = FLASH_BUFFER_FULL_ID;
00102
00103 while(EECR & (1<<EEWE));
00104 #endif
00105
00106 LpmReplaceSpm(flashAddr, data);
00107 WriteBufToFlash(pageAdr);
00108
00109 #ifdef __FLASH_RECOVER
00110 FlashBackup.status = 0;
00111
00112 while(EECR & (1<<EEWE));
00113 #endif
00114
00115 EECR |= eepromInterruptSettings;
00116 return TRUE;
00117
00118 }
00119 else
00120 return FALSE;
00121
00122 }
00123
00130 unsigned char WriteFlashPage(MyAddressType flashStartAdr, unsigned char *dataPage)
00131 {
00132 unsigned int index;
00133 unsigned char eepromInterruptSettings;
00134 if( AddressCheck(flashStartAdr) ){
00135 eepromInterruptSettings = EECR & (1<<EERIE);
00136 EECR &= ~(1<<EERIE);
00137 while(EECR & (1<<EEWE));
00138
00139 #ifdef __FLASH_RECOVER
00140 FlashBackup.status=0;
00141
00142 while(EECR & (1<<EEWE));
00143 for(index = 0; index < PAGESIZE; index+=2){
00144 _SPM_FILLTEMP(index, (unsigned int)dataPage[index]+((unsigned int)dataPage[index+1] << 8));
00145 }
00146 WriteBufToFlash(ADR_FLASH_BUFFER);
00147 FlashBackup.pageNumber=(unsigned int)(flashStartAdr/PAGESIZE);
00148 FlashBackup.status = FLASH_BUFFER_FULL_ID;
00149
00150 while(EECR & (1<<EEWE));
00151 #endif
00152 for(index = 0; index < PAGESIZE; index+=2){
00153 _SPM_FILLTEMP(index, (unsigned int)dataPage[index]+((unsigned int)dataPage[index+1] << 8));
00154 }
00155 WriteBufToFlash(flashStartAdr);
00156 #ifdef __FLASH_RECOVER
00157 FlashBackup.status=0;
00158
00159 while(EECR & (1<<EEWE));
00160 #endif
00161
00162 EECR |= eepromInterruptSettings;
00163 return TRUE;
00164
00165 }
00166 else
00167 return FALSE;
00168
00169 }
00170
00178 unsigned char RecoverFlash(){
00179 #ifdef __FLASH_RECOVER
00180 unsigned int index;
00181 if(FlashBackup.status == FLASH_BUFFER_FULL_ID){
00182
00183 for(index=0; index < PAGESIZE; index+=2){
00184 _SPM_FILLTEMP( index, *((MyFlashIntPointer)(ADR_FLASH_BUFFER+index)) );
00185 }
00186 WriteBufToFlash((MyAddressType)FlashBackup.pageNumber * PAGESIZE);
00187 FlashBackup.status=0;
00188
00189 while(EECR & (1<<EEWE));
00190 return TRUE;
00191
00192 }
00193 #endif
00194 return FALSE;
00195 }
00196
00197
00207 unsigned char AddressCheck(MyAddressType flashAdr){
00208 #ifdef __FLASH_RECOVER
00209
00210 if( (flashAdr >= ADR_LIMIT_LOW) && (flashAdr <= ADR_LIMIT_HIGH) &&
00211 (flashAdr != ADR_FLASH_BUFFER) && !(flashAdr & (PAGESIZE-1)) )
00212 return TRUE;
00213 else
00214 return FALSE;
00215 #else
00216 if((flashAdr >= ADR_LIMIT_LOW) && (flashAdr <= ADR_LIMIT_HIGH) && !(flashAdr & (PAGESIZE-1) ) )
00217 return TRUE;
00218 else
00219 return FALSE;
00220 #endif
00221 }
00222
00223
00228 void WriteBufToFlash(MyAddressType flashStartAdr){
00229 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00230 #ifdef __HAS_RAMPZ__
00231 RAMPZ = (unsigned char)(flashStartAdr >> 16);
00232 #endif
00233 _SPM_ERASE(flashStartAdr);
00234 while( SPMControllRegister & (1<<SPMEN) );
00235 _SPM_PAGEWRITE(flashStartAdr);
00236 while( SPMControllRegister & (1<<SPMEN) );
00237 #ifdef RWWSRE
00238 __DataToR0ByteToSPMCR_SPM( 0, (unsigned char)(1<<RWWSRE)|(1<<SPMEN));
00239 #endif
00240 #pragma diag_default=Pe1053 // Back to default.
00241 }
00242
00247 void LpmReplaceSpm(MyAddressType flashAddr, unsigned char data){
00248 #pragma diag_suppress=Pe1053 // Suppress warning for conversion from long-type address to flash ptr.
00249 unsigned int index, oddByte, pcWord;
00250 MyAddressType pageAdr;
00251 oddByte=(unsigned char)flashAddr & 1;
00252 pcWord=(unsigned int)flashAddr & (PAGESIZE-2);
00253 pageAdr=flashAddr & ~(PAGESIZE-1);
00254 for(index=0; index < PAGESIZE; index+=2){
00255 if(index==pcWord){
00256 if(oddByte){
00257 _SPM_FILLTEMP( index, (*(MyFlashCharPointer)(flashAddr & ~1) | ((unsigned int)data<<8)) );
00258 }
00259 else{
00260 _SPM_FILLTEMP( index, ( (*( (MyFlashCharPointer)flashAddr+1)<<8) | data ) );
00261 }
00262 }
00263 else{
00264 _SPM_FILLTEMP(index, *( (MyFlashIntPointer)(pageAdr+index) ) );
00265 }
00266 }
00267 #pragma diag_default=Pe1053 // Back to default.
00268 }