Self_programming.c

Go to the documentation of this file.
00001 // This file has been prepared for Doxygen automatic documentation generation.
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 } // Returns data from Flash
00058 
00065 unsigned char ReadFlashPage(MyAddressType flashStartAdr, unsigned char *dataPage){
00066   unsigned int index;
00067   if(!(flashStartAdr & (PAGESIZE-1))){      // If input address is a page address
00068     for(index = 0; index < PAGESIZE; index++){
00069       dataPage[index] = ReadFlashByte(flashStartAdr + index);
00070     }
00071     return TRUE;                            // Return TRUE if valid page address
00072   }
00073   else{
00074     return FALSE;                           // Return FALSE if not valid page address
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); // Stores EEPROM interrupt mask
00088     EECR &= ~(1<<EERIE);                    // Disable EEPROM interrupt
00089     while(EECR & (1<<EEWE));                // Wait if ongoing EEPROM write
00090 
00091     pageAdr=flashAddr & ~(PAGESIZE-1);      // Gets Flash page address from byte address
00092 
00093     #ifdef __FLASH_RECOVER
00094     FlashBackup.status=0;                   // Inicate that Flash buffer does
00095                                             // not contain data for writing
00096     while(EECR & (1<<EEWE));
00097     LpmReplaceSpm(flashAddr, data);         // Fills Flash write buffer
00098     WriteBufToFlash(ADR_FLASH_BUFFER);      // Writes to Flash recovery buffer
00099     FlashBackup.pageNumber = (unsigned int) (pageAdr/PAGESIZE); // Stores page address
00100                                                        // data should be written to
00101     FlashBackup.status = FLASH_BUFFER_FULL_ID; // Indicates that Flash recovery buffer
00102                                                // contains unwritten data
00103     while(EECR & (1<<EEWE));
00104     #endif
00105 
00106     LpmReplaceSpm(flashAddr, data);         // Fills Flash write buffer
00107     WriteBufToFlash(pageAdr);               // Writes to Flash
00108 
00109     #ifdef __FLASH_RECOVER
00110     FlashBackup.status = 0;                 // Indicates that Flash recovery buffer
00111                                             // does not contain unwritten data
00112     while(EECR & (1<<EEWE));
00113     #endif
00114 
00115     EECR |= eepromInterruptSettings;        // Restore EEPROM interrupt mask
00116     return TRUE;                            // Return TRUE if address
00117                                             // valid for writing
00118   }
00119   else
00120     return FALSE;                           // Return FALSE if address not
00121                                             // valid for writing
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); // Stoes EEPROM interrupt mask
00136     EECR &= ~(1<<EERIE);                    // Disable EEPROM interrupt
00137     while(EECR & (1<<EEWE));                // Wait if ongoing EEPROM write
00138 
00139     #ifdef __FLASH_RECOVER
00140     FlashBackup.status=0;                   // Inicate that Flash buffer does
00141                                             // not contain data for writing
00142     while(EECR & (1<<EEWE));
00143     for(index = 0; index < PAGESIZE; index+=2){ // Fills Flash write buffer
00144       _SPM_FILLTEMP(index, (unsigned int)dataPage[index]+((unsigned int)dataPage[index+1] << 8));
00145     }
00146     WriteBufToFlash(ADR_FLASH_BUFFER);      // Writes to Flash recovery buffer
00147     FlashBackup.pageNumber=(unsigned int)(flashStartAdr/PAGESIZE);
00148     FlashBackup.status = FLASH_BUFFER_FULL_ID; // Indicates that Flash recovery buffer
00149                                            // contains unwritten data
00150     while(EECR & (1<<EEWE));
00151     #endif
00152     for(index = 0; index < PAGESIZE; index+=2){ // Fills Flash write buffer
00153       _SPM_FILLTEMP(index, (unsigned int)dataPage[index]+((unsigned int)dataPage[index+1] << 8));
00154     }
00155     WriteBufToFlash(flashStartAdr);         // Writes to Flash
00156     #ifdef __FLASH_RECOVER
00157       FlashBackup.status=0;                 // Inicate that Flash buffer does
00158                                             // not contain data for writing
00159       while(EECR & (1<<EEWE));
00160     #endif
00161 
00162     EECR |= eepromInterruptSettings;        // Restore EEPROM interrupt mask
00163     return TRUE;                            // Return TRUE if address
00164                                             // valid for writing
00165   }
00166   else
00167     return FALSE;                           // Return FALSE if not address not
00168                                             // valid for writing
00169 }
00170 
00178 unsigned char RecoverFlash(){
00179 #ifdef __FLASH_RECOVER
00180   unsigned int index;
00181   if(FlashBackup.status == FLASH_BUFFER_FULL_ID){ // Checks if Flash recovery
00182                                                   //  buffer contains data
00183     for(index=0; index < PAGESIZE; index+=2){     // Writes to Flash write buffer
00184         _SPM_FILLTEMP( index, *((MyFlashIntPointer)(ADR_FLASH_BUFFER+index)) );
00185     }
00186     WriteBufToFlash((MyAddressType)FlashBackup.pageNumber * PAGESIZE);
00187     FlashBackup.status=0;                   // Inicate that Flash buffer does
00188                                             // not contain data for writing
00189     while(EECR & (1<<EEWE));
00190     return TRUE;                            // Returns TRUE if recovery has
00191                                             // taken place
00192   }
00193 #endif
00194   return FALSE;
00195 }
00196 
00197 
00207 unsigned char AddressCheck(MyAddressType flashAdr){
00208   #ifdef __FLASH_RECOVER
00209   // The next line gives a warning 'pointless comparison with zero' if ADR_LIMIT_LOW is 0. Ignore it.
00210   if( (flashAdr >= ADR_LIMIT_LOW) && (flashAdr <= ADR_LIMIT_HIGH) &&
00211       (flashAdr != ADR_FLASH_BUFFER) && !(flashAdr & (PAGESIZE-1)) )
00212     return TRUE;                            // Address is a valid page address
00213   else
00214     return FALSE;                           // Address is not a valid page address
00215   #else
00216   if((flashAdr >= ADR_LIMIT_LOW) && (flashAdr <= ADR_LIMIT_HIGH) && !(flashAdr & (PAGESIZE-1) ) )
00217     return TRUE;                            // Address is a valid page address
00218   else
00219     return FALSE;                           // Address is not a valid page address
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) ); // Wait until Flash write completed
00235   _SPM_PAGEWRITE(flashStartAdr);
00236   while( SPMControllRegister & (1<<SPMEN) ); // Wait until Flash write completed
00237   #ifdef RWWSRE
00238   __DataToR0ByteToSPMCR_SPM( 0, (unsigned char)(1<<RWWSRE)|(1<<SPMEN)); // Enable RWW
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); // Used when writing FLASH temp buffer
00253   pageAdr=flashAddr & ~(PAGESIZE-1);        // Get FLASH page address from byte address
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       }                                     // Write odd byte in temporary buffer
00259       else{
00260         _SPM_FILLTEMP( index, ( (*( (MyFlashCharPointer)flashAddr+1)<<8)  | data ) );
00261       }                                     // Write even byte in temporary buffer
00262     }
00263     else{
00264       _SPM_FILLTEMP(index, *( (MyFlashIntPointer)(pageAdr+index) ) );
00265     }                                       // Write Flash word directly to temporary buffer
00266   }
00267 #pragma diag_default=Pe1053 // Back to default.
00268 }

Generated on Wed Jan 18 16:19:21 2006 for AVR106 - C Functions for Reading and Writing to Flash Memory by  doxygen 1.4.5