avr/cpp/EEPROM.cpp

Go to the documentation of this file.
00001 /**********************************************************************************************************************\
00002 
00003         C++ library for Atmel AVR microcontrollers
00004         Copyright (C) 2007 Lauri Kirikal, Mikk Leini, MT� TT� Robotiklubi
00005 
00006         This program is free software; you can redistribute it and/or
00007         modify it under the terms of the GNU General Public License
00008         as published by the Free Software Foundation; either version 2
00009         of the License, or (at your option) any later version.
00010 
00011         This program is distributed in the hope that it will be useful,
00012         but WITHOUT ANY WARRANTY; without even the implied warranty of
00013         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014         GNU General Public License for more details.
00015 
00016         You should have received a copy of the GNU General Public License
00017         along with this program; if not, write to the Free Software
00018         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019 
00020         See http://creativecommons.org/licenses/GPL/2.0/
00021 
00022         MT� TT� Robotiklubi  http://www.robotiklubi.ee robotiklubi@gmail.com
00023         Lauri Kirikal        laurikirikal@gmail.com
00024         Mikk Leini           mikk.leini@gmail.com
00025 
00026 \**********************************************************************************************************************/
00027 
00028 #include "EEPROM.h"
00029 #include "Interrupt.h"
00030 
00031 
00032 namespace AVRCpp
00033 {
00034         namespace EEPROM
00035         {
00036 
00037                 // Waits while CPU is programming Flash. Only needed if boot loader is present.
00038                 static inline bool IsWritingFlash() {   return IsBitsSet<__SPMCSR__>(__SPMEN__); }
00039                 static inline void WaitWhileWritingFlash() { while (IsWritingFlash() ); }
00040                 
00041                 static void WriteOperation()
00042                 {
00043                         // Save SREG_I bit.
00044                         uint8_t savedSREG = SREG;
00045                         
00046                         // __EEPE__ must be set immediately after setting __EEMPE__
00047                         GlobalInterrupts::Disable();
00048                         
00049                         SetBits<_EECR>(__EEMPE__);
00050                         SetBits<_EECR>(__EEPE__);
00051                         
00052                         // Restore the interrupt bit in Status Register
00053                         SREG = savedSREG;
00054 
00055                 } // WriteOperation
00056                 
00057                 
00058                 bool MoveNext()
00059                 {
00060                         if (EEAR < EEPROM_SIZE - 1)
00061                         {
00062                                 WaitWhileWriting();
00063                                 EEAR++;
00064                                 
00065                                 return true;
00066                         }
00067                         
00068                         return false;
00069                         
00070                 } // MoveNext
00071                 
00072                 
00073                 void Write(uint8_t data)
00074                 {
00075                         WaitWhileWriting();
00076                         
00077                         WaitWhileWritingFlash();
00078                         
00079                         EEDR = data;
00080                         
00081                         WriteOperation();
00082 
00083                 } // Write 1
00084                 
00085                 
00086                 void Write(uint16_t address, uint8_t data)
00087                 {
00088                         WaitWhileWriting();
00089                         
00090                         WaitWhileWritingFlash();
00091                         
00092                         SetAddressUnsafe(address);
00093                         
00094                         EEDR = data;
00095                         
00096                         WriteOperation();
00097 
00098                 } // Write 2
00099 
00100                 
00101                 namespace Internal
00102                 {
00103                         
00104                         bool SavingProcess(uint16_t lastByteAddr, uint8_t *uint8Data)
00105                         {
00106                                 // Enough space ?
00107                                 if (lastByteAddr >= EEPROM_SIZE)
00108                                         return false;
00109                                 
00110                                 // Write byte by byte
00111                                 while (true)
00112                                 {
00113                                         Write(*uint8Data);
00114                                         
00115                                         uint8Data++;
00116                                         
00117                                         // Done ?
00118                                         if (EEAR == lastByteAddr)
00119                                                 break;
00120                                         
00121                                         WaitWhileWriting();
00122                                         EEAR++;
00123                                 }
00124                                 
00125                                 MoveNext();
00126                                 
00127                                 return true;
00128                                 
00129                         } // SavingProcess
00130                         
00131                         
00132                         bool LoadingProcess(uint16_t lastByteAddr, uint8_t *uint8Data)
00133                         {
00134                                 // Enough space ?
00135                                 if (lastByteAddr >= EEPROM_SIZE)
00136                                         return false;
00137                                 
00138                                 // Read byte by byte
00139                                 while (true)
00140                                 {
00141                                         *uint8Data = Read();
00142                                         
00143                                         uint8Data++;
00144                                         
00145                                         // Done ?
00146                                         if (EEAR == lastByteAddr)
00147                                                 break;
00148                                         
00149                                         WaitWhileWriting();
00150                                         EEAR++;
00151                                 }
00152                                 
00153                                 MoveNext();
00154                                 
00155                                 return true;
00156                                 
00157                         } // LoadingProcess
00158                         
00159                 } // namespace Internal
00160                 
00161 #if __EEPROM_PROPERTIES__ & __EEPROM_ERASEBLE__
00162                 
00163                 static inline bool ErasingProcess(uint16_t lastByteAddr)
00164                 {
00165                         // Enough space ?
00166                         if (lastByteAddr >= EEPROM_SIZE)
00167                                 return false;
00168                         
00169                         // Erase byte by byte
00170                         while (true)
00171                         {
00172                                 
00173                                 WaitWhileWriting();
00174                                 
00175                                 WaitWhileWritingFlash();
00176                                 
00177                                 WriteOperation();
00178                                 
00179                                 // Done ?
00180                                 if (EEAR == lastByteAddr)
00181                                         break;
00182                                 
00183                                 WaitWhileWriting();
00184                                 
00185                                 EEAR++;
00186                         }
00187                         
00188                         MoveNext();
00189                         
00190                         return true;
00191                         
00192                 } // ErasingProcess
00193                 
00194 
00195                 static inline bool EraseOperation(uint16_t numberOfBytes)
00196                 {
00197                         // Is there anything to read or write ?
00198                         if (numberOfBytes == 0)
00199                                 return true;
00200                         
00201                         {
00202                                 uint16_t lastByteAddr = EEAR + numberOfBytes - 1;
00203                                 
00204                                 return ErasingProcess(lastByteAddr);
00205                         }
00206                         
00207                 } // EraseOperation
00208                 
00209 
00210                 bool Erase(uint16_t numberOfBytes)
00211                 {
00212                         uint8_t savedEECR = EECR;
00213                         
00214                         SetMode(EraseOnly);
00215                         
00216                         {
00217                                 bool result = EraseOperation(numberOfBytes);
00218                                 
00219                                 ChangeBits<_EECR>(_EEPM1 | _EEPM0, savedEECR);
00220                                 
00221                                 return result;
00222                         }
00223 
00224                 } // Erase
00225                 
00226 #endif // if __EEPROM_PROPERTIES__ & __EEPROM_ERASEBLE__
00227                 
00228         } // namespace EEPROM
00229 
00230 } // namespace AVRCpp

Generated on Sat Sep 15 23:41:05 2007 for AVR C++ Lib for ATmega64 by  doxygen 1.5.2
SourceForge.net Logo MTÜ TTÜ Robotiklubi