Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
eeprom.c
00001 // This file has been prepared for Doxygen automatic documentation generation. 00002 /*! \file ******************************************************************** 00003 * 00004 * Atmel Corporation 00005 * 00006 * \li File: eeprom.c 00007 * \li Compiler: IAR EWAAVR 3.10c 00008 * \li Support mail: avr@atmel.com 00009 * 00010 * \li Supported devices: All devices with split EEPROM erase/write 00011 * capabilities can be used. 00012 * The example is written for ATmega48. 00013 * 00014 * \li AppNote: AVR103 - Using the EEPROM Programming Modes. 00015 * 00016 * \li Description: Example on how to use the split EEPROM erase/write 00017 * capabilities in e.g. ATmega48. All EEPROM 00018 * programming modes are tested, i.e. Erase+Write, 00019 * Erase-only and Write-only. 00020 * 00021 * $Revision: 1.6 $ 00022 * $Date: Friday, February 11, 2005 07:16:44 UTC $ 00023 ****************************************************************************/ 00024 #include "grbl.h" 00025 #ifdef AVRTARGET 00026 #include <avr/io.h> 00027 #include <avr/interrupt.h> 00028 /* These EEPROM bits have different names on different devices. */ 00029 #ifndef EEPE 00030 #define EEPE EEWE //!< EEPROM program/write enable. 00031 #define EEMPE EEMWE //!< EEPROM master program/write enable. 00032 #endif 00033 00034 /* These two are unfortunately not defined in the device include files. */ 00035 #define EEPM1 5 //!< EEPROM Programming Mode Bit 1. 00036 #define EEPM0 4 //!< EEPROM Programming Mode Bit 0. 00037 00038 /* Define to reduce code size. */ 00039 #define EEPROM_IGNORE_SELFPROG //!< Remove SPM flag polling. 00040 #endif 00041 #ifdef WIN32 00042 #include <stdio.h> 00043 #include <string.h> 00044 #endif 00045 #ifdef STM32F103C8 00046 #include <string.h> 00047 #include "stm32eeprom.h" 00048 #include "settings.h" 00049 #endif 00050 #if defined(WIN32) || defined (STM32F103C8) 00051 unsigned char EE_Buffer[0x400]; 00052 #endif 00053 #if defined(WIN32) 00054 #ifndef NOEEPROMSUPPORT 00055 void eeprom_flush() 00056 { 00057 FILE *out = fopen("eeprom.bin", "wb"); 00058 fwrite(EE_Buffer, 1, 0x400, out); 00059 fclose(out); 00060 } 00061 #endif 00062 void eeprom_init() 00063 { 00064 #ifndef NOEEPROMSUPPORT 00065 FILE *in = fopen("eeprom.bin", "rb"); 00066 if (in != NULL) 00067 { 00068 fread(EE_Buffer, 1, 0x400, in); 00069 fclose(in); 00070 } 00071 else 00072 { 00073 memset(EE_Buffer, 0xff, 0x400); 00074 } 00075 #else 00076 memset(EE_Buffer, 0x0, 0x400); 00077 #endif 00078 } 00079 #endif 00080 00081 #ifdef STM32F103C8 00082 #ifndef NOEEPROMSUPPORT 00083 void eeprom_flush() 00084 { 00085 uint32_t nAddress = EEPROM_START_ADDRESS; 00086 uint16_t *pBuffer = (uint16_t *)EE_Buffer; 00087 uint16_t nSize = PAGE_SIZE; 00088 00089 FLASH_Status FlashStatus = FLASH_COMPLETE; 00090 00091 /* Erase Page0 */ 00092 FlashStatus = FLASH_ErasePage(EEPROM_START_ADDRESS); 00093 00094 /* If erase operation was failed, a Flash error code is returned */ 00095 if (FlashStatus != FLASH_COMPLETE) 00096 { 00097 return; 00098 } 00099 00100 while (nSize > 0) 00101 { 00102 if (*pBuffer != 0xffff) 00103 { 00104 FLASH_ProgramHalfWord(nAddress, *pBuffer++); 00105 } 00106 else 00107 { 00108 pBuffer++; 00109 } 00110 if (*pBuffer != 0xffff) 00111 { 00112 FLASH_ProgramHalfWord(nAddress + 2, *pBuffer++); 00113 } 00114 else 00115 { 00116 pBuffer++; 00117 } 00118 nSize -= 4; 00119 nAddress += 4; 00120 } 00121 } 00122 void eeprom_init() 00123 { 00124 uint16_t VarIdx = 0; 00125 uint8_t *pTmp = EE_Buffer; 00126 00127 for (VarIdx = 0; VarIdx < PAGE_SIZE; VarIdx++) 00128 { 00129 *pTmp++ = (*(__IO uint8_t*)(EEPROM_START_ADDRESS + VarIdx)); 00130 } 00131 00132 if (EE_Buffer[0] != SETTINGS_VERSION) 00133 { 00134 pTmp = EE_Buffer; 00135 00136 for (VarIdx = 0; VarIdx < PAGE_SIZE; VarIdx++) 00137 { 00138 *pTmp++ = 0xFF; 00139 } 00140 } 00141 } 00142 #endif 00143 #endif 00144 00145 /*! \brief Read byte from EEPROM. 00146 * 00147 * This function reads one byte from a given EEPROM address. 00148 * 00149 * \note The CPU is halted for 4 clock cycles during EEPROM read. 00150 * 00151 * \param addr EEPROM address to read from. 00152 * \return The byte read from the EEPROM address. 00153 */ 00154 unsigned char eeprom_get_char( unsigned int addr ) 00155 { 00156 #ifdef AVRTARGET 00157 do {} while( EECR & (1<<EEPE) ); // Wait for completion of previous write. 00158 EEAR = addr; // Set EEPROM address register. 00159 EECR = (1<<EERE); // Start EEPROM read operation. 00160 return EEDR; // Return the byte read from EEPROM. 00161 #endif 00162 #if defined(WIN32) || defined(STM32F103C8) 00163 return EE_Buffer[addr]; 00164 #endif 00165 } 00166 00167 /*! \brief Write byte to EEPROM. 00168 * 00169 * This function writes one byte to a given EEPROM address. 00170 * The differences between the existing byte and the new value is used 00171 * to select the most efficient EEPROM programming mode. 00172 * 00173 * \note The CPU is halted for 2 clock cycles during EEPROM programming. 00174 * 00175 * \note When this function returns, the new EEPROM value is not available 00176 * until the EEPROM programming time has passed. The EEPE bit in EECR 00177 * should be polled to check whether the programming is finished. 00178 * 00179 * \note The EEPROM_GetChar() function checks the EEPE bit automatically. 00180 * 00181 * \param addr EEPROM address to write to. 00182 * \param new_value New EEPROM value. 00183 */ 00184 void eeprom_put_char( unsigned int addr, unsigned char new_value ) 00185 { 00186 #ifdef AVRTARGET 00187 char old_value; // Old EEPROM value. 00188 char diff_mask; // Difference mask, i.e. old value XOR new value. 00189 00190 cli(); // Ensure atomic operation for the write operation. 00191 00192 do {} while( EECR & (1<<EEPE) ); // Wait for completion of previous write. 00193 #ifndef EEPROM_IGNORE_SELFPROG 00194 do {} while( SPMCSR & (1<<SELFPRGEN) ); // Wait for completion of SPM. 00195 #endif 00196 00197 EEAR = addr; // Set EEPROM address register. 00198 EECR = (1<<EERE); // Start EEPROM read operation. 00199 old_value = EEDR; // Get old EEPROM value. 00200 diff_mask = old_value ^ new_value; // Get bit differences. 00201 00202 // Check if any bits are changed to '1' in the new value. 00203 if( diff_mask & new_value ) { 00204 // Now we know that _some_ bits need to be erased to '1'. 00205 00206 // Check if any bits in the new value are '0'. 00207 if( new_value != 0xff ) { 00208 // Now we know that some bits need to be programmed to '0' also. 00209 00210 EEDR = new_value; // Set EEPROM data register. 00211 EECR = (1<<EEMPE) | // Set Master Write Enable bit... 00212 (0<<EEPM1) | (0<<EEPM0); // ...and Erase+Write mode. 00213 EECR |= (1<<EEPE); // Start Erase+Write operation. 00214 } else { 00215 // Now we know that all bits should be erased. 00216 00217 EECR = (1<<EEMPE) | // Set Master Write Enable bit... 00218 (1<<EEPM0); // ...and Erase-only mode. 00219 EECR |= (1<<EEPE); // Start Erase-only operation. 00220 } 00221 } else { 00222 // Now we know that _no_ bits need to be erased to '1'. 00223 00224 // Check if any bits are changed from '1' in the old value. 00225 if( diff_mask ) { 00226 // Now we know that _some_ bits need to the programmed to '0'. 00227 00228 EEDR = new_value; // Set EEPROM data register. 00229 EECR = (1<<EEMPE) | // Set Master Write Enable bit... 00230 (1<<EEPM1); // ...and Write-only mode. 00231 EECR |= (1<<EEPE); // Start Write-only operation. 00232 } 00233 } 00234 00235 sei(); // Restore interrupt flag state. 00236 #endif 00237 #if defined(WIN32) || defined(STM32F103C8) 00238 EE_Buffer[addr] = new_value; 00239 #endif 00240 } 00241 00242 // Extensions added as part of Grbl 00243 00244 00245 void memcpy_to_eeprom_with_checksum(unsigned int destination, char *source, unsigned int size) { 00246 unsigned char checksum = 0; 00247 for(; size > 0; size--) { 00248 checksum = (checksum << 1) || (checksum >> 7); 00249 checksum += *source; 00250 eeprom_put_char(destination++, *(source++)); 00251 } 00252 eeprom_put_char(destination, checksum); 00253 #if defined(WIN32) || defined(STM32F103C8) 00254 #ifndef NOEEPROMSUPPORT 00255 eeprom_flush(); 00256 #endif 00257 #endif 00258 } 00259 00260 int memcpy_from_eeprom_with_checksum(char *destination, unsigned int source, unsigned int size) { 00261 unsigned char data, checksum = 0; 00262 for(; size > 0; size--) { 00263 data = eeprom_get_char(source++); 00264 checksum = (checksum << 1) || (checksum >> 7); 00265 checksum += data; 00266 *(destination++) = data; 00267 } 00268 return(checksum == eeprom_get_char(source)); 00269 } 00270 00271 // end of file
Generated on Tue Jul 12 2022 20:45:31 by
1.7.2