00001 /********************************************************************************* 00002 00003 Copyright 2006-2008 MakingThings 00004 00005 Licensed under the Apache License, 00006 Version 2.0 (the "License"); you may not use this file except in compliance 00007 with the License. You may obtain a copy of the License at 00008 00009 http://www.apache.org/licenses/LICENSE-2.0 00010 00011 Unless required by applicable law or agreed to in writing, software distributed 00012 under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 00013 CONDITIONS OF ANY KIND, either express or implied. See the License for 00014 the specific language governing permissions and limitations under the License. 00015 00016 *********************************************************************************/ 00017 00018 /** \file eeprom.c 00019 EEPROM. 00020 Functions for working with the EEPROM on the Make Controller Board. 00021 */ 00022 00023 /* Library includes. */ 00024 #include <string.h> 00025 #include <stdio.h> 00026 00027 /* Scheduler includes. */ 00028 #include "FreeRTOS.h" 00029 #include "task.h" 00030 00031 /* Hardware specific headers. */ 00032 #include "Board.h" 00033 #include "AT91SAM7X256.h" 00034 00035 #include "eeprom.h" 00036 #include "spi.h" 00037 00038 #include "config.h" 00039 #include "io.h" 00040 00041 #define EEPROM_INSTRUCTION_WREN 0x06 00042 #define EEPROM_INSTRUCTION_WRDI 0x04 00043 #define EEPROM_INSTRUCTION_RDSR 0x05 00044 #define EEPROM_INSTRUCTION_WRSR 0x01 00045 #define EEPROM_INSTRUCTION_READ 0x03 00046 #define EEPROM_INSTRUCTION_WRITE 0x02 00047 00048 #define EEPROM_DEVICE 0x03 00049 //#define EEPROM_NOTCS 0x0B 00050 00051 static int Eeprom_Start( void ); 00052 static int Eeprom_Stop( void ); 00053 00054 static void Eeprom_WriteEnable( void ); 00055 //static void Eeprom_WriteDisable( void ); 00056 00057 static void Eeprom_Ready( void ); 00058 00059 static int Eeprom_users; 00060 00061 /** \defgroup Eeprom EEPROM 00062 Eeprom allows for the persistent storage of 32k bytes data. 00063 The last 1k (1024) bytes of this space are reserved for Make Controller system 00064 use, storing things like the board's IP address, serial number, build version, etc. 00065 00066 The symbol \b EEPROM_SYSTEM_BASE provides the last available address before the reserved section. 00067 Use it to locate your own locations in EEPROM by subracting from it as appropriate for your data. 00068 For example, if you're storing integers, you can use code like 00069 \code 00070 #define MY_FIRST_VALUE (EEPROM_SYSTEM_BASE - 4) 00071 #define MY_SECOND_VALUE (MY_FIRST_VALUE - 8) 00072 \endcode 00073 00074 You can then use those values as the addresses to read and write from, like 00075 \code 00076 00077 \endcode 00078 00079 Use Eeprom_Write() and Eeprom_Read() to store and retrieve characters. These both internally set 00080 the EEPROM system to active automatically. 00081 00082 Internally, Eeprom relies on \ref Spi, so activating Eeprom also activates \ref Spi. 00083 00084 \ingroup Core 00085 @{ 00086 */ 00087 00088 /** 00089 Set the active state of the EEPROM subsystem. This is automatically set to 00090 true by any call to Eeprom_Write or Eeprom_Read. 00091 @param state An integer specifying the active state - 1 (on) or 0 (off). 00092 @return CONTROLLER_OK (=0) on success. 00093 */ 00094 int Eeprom_SetActive( int state ) 00095 { 00096 if ( state ) 00097 return Eeprom_Start(); 00098 else 00099 return Eeprom_Stop(); 00100 } 00101 00102 /** 00103 Read the active state of the EEPROM. 00104 @return State - 1/non-zero (on) or 0 (off). 00105 */ 00106 int Eeprom_GetActive( ) 00107 { 00108 return Eeprom_users > 0; 00109 } 00110 00111 /** 00112 Write data to the EEPROM. 00113 @param address An integer specifying the address. 00114 @param buffer A pointer to the buffer to write from. 00115 @param count An integer specifying the number of bytes to write. 00116 @return Status: 0 on success, < 0 on failure. 00117 00118 \par Example 00119 \code 00120 #define MY_STORED_VALUE (EEPROM_SYSTEM_BASE - 4) 00121 int my_number_to_store = 1234; 00122 int size = 4; // ints are 4 00123 if(Eeprom_Write( MY_STORED_VALUE, (uchar*)&my_number_to_store, size ); < 0) 00124 { 00125 // then there was an error... 00126 } 00127 else 00128 { 00129 // my_stored_number now has the stored value 00130 } 00131 \endcode 00132 */ 00133 int Eeprom_Write( int address, uchar* buffer, int count ) 00134 { 00135 if ( address < 0 || address >= EEPROM_SIZE ) 00136 return CONTROLLER_ERROR_BAD_ADDRESS; 00137 00138 if ( Eeprom_users == 0 ) 00139 { 00140 int status = Eeprom_Start(); 00141 if ( status != CONTROLLER_OK ) 00142 return status; 00143 } 00144 00145 Spi_Lock(); 00146 00147 Eeprom_Ready( ); 00148 00149 Eeprom_WriteEnable(); 00150 00151 uchar c[ count + 4 ]; 00152 00153 c[ 0 ] = EEPROM_INSTRUCTION_WRITE; 00154 c[ 1 ] = (unsigned char)( address >> 8 ); 00155 c[ 2 ] = (unsigned char)( address & 0xFF ); 00156 c[ 3 ] = 0; 00157 00158 int i; 00159 for ( i = 0; i < count; i++ ) 00160 { 00161 c[ i + 3 ] = buffer[ i ]; 00162 } 00163 00164 Spi_ReadWriteBlock( EEPROM_DEVICE, c, 3 + count ); 00165 00166 Spi_Unlock(); 00167 00168 return CONTROLLER_OK; 00169 } 00170 00171 /** 00172 Read data from the EEPROM. 00173 @param address An integer specifying the address to read from. 00174 @param buffer A pointer to the buffer to read into. 00175 @param count An integer specifying the number of bytes to read. 00176 @return Status: 0 on success, < 0 on failure. 00177 00178 \par Example 00179 \code 00180 #define MY_STORED_VALUE (EEPROM_SYSTEM_BASE - 4) 00181 int my_stored_number; 00182 int size = 4; // ints are 4 00183 if(Eeprom_Read( MY_STORED_VALUE, (uchar*)&my_stored_number, size ) < 0) 00184 { 00185 // then there was an error... 00186 } 00187 else 00188 { 00189 // my_stored_number now has the stored value 00190 } 00191 \endcode 00192 */ 00193 int Eeprom_Read( int address, uchar* buffer, int count ) 00194 { 00195 if ( address < 0 || address > EEPROM_SIZE ) 00196 return CONTROLLER_ERROR_BAD_ADDRESS; 00197 00198 if ( Eeprom_users == 0 ) 00199 { 00200 int status = Eeprom_Start(); 00201 if ( status != CONTROLLER_OK ) 00202 return status; 00203 } 00204 00205 Spi_Lock(); 00206 00207 Eeprom_Ready( ); 00208 00209 unsigned char c[ count + 4 ]; 00210 00211 c[ 0 ] = EEPROM_INSTRUCTION_READ; 00212 c[ 1 ] = (unsigned char)( address >> 8 ); 00213 c[ 2 ] = (unsigned char)( address & 0xFF ); 00214 c[ 3 ] = 0; 00215 00216 Spi_ReadWriteBlock( EEPROM_DEVICE, c, count + 3 ); 00217 00218 int i; 00219 for ( i = 0; i < count; i++ ) 00220 { 00221 buffer[ i ] = c[ i + 3 ]; 00222 } 00223 00224 Spi_Unlock(); 00225 00226 return CONTROLLER_OK; 00227 } 00228 00229 /** @} 00230 */ 00231 00232 int Eeprom_Start() 00233 { 00234 int status; 00235 00236 if ( Eeprom_users++ == 0 ) 00237 { 00238 // Attempt to open the SPI device 00239 status = Spi_Start( EEPROM_DEVICE ); 00240 if ( status != CONTROLLER_OK ) 00241 { 00242 Eeprom_users--; 00243 return status; 00244 } 00245 00246 // We're here means that we got the Spi open, now set it up 00247 status = Spi_Configure( EEPROM_DEVICE, 8, 4, 0, 1 ); 00248 if ( status != CONTROLLER_OK ) 00249 { 00250 // Undo all the setup. Sigh. 00251 Eeprom_Stop(); 00252 return status; 00253 } 00254 } 00255 00256 return CONTROLLER_OK; 00257 } 00258 00259 int Eeprom_Stop() 00260 { 00261 if ( Eeprom_users <= 0 ) 00262 return CONTROLLER_ERROR_NOT_LOCKED; 00263 00264 if ( --Eeprom_users == 0 ) 00265 Spi_Stop( EEPROM_DEVICE ); 00266 00267 return CONTROLLER_OK; 00268 } 00269 00270 /** 00271 Eeprom_WriteEnable. 00272 Enable writing from the EEPROM on the Make Controller Board. 00273 This function should be called before making calls to Eeprom_Write(). 00274 @param none. 00275 @return none. 00276 */ 00277 void Eeprom_WriteEnable() 00278 { 00279 uchar c; 00280 c = EEPROM_INSTRUCTION_WREN; 00281 00282 Spi_ReadWriteBlock( EEPROM_DEVICE, &c, 1 ); 00283 } 00284 00285 /* 00286 Disable writing from the EEPROM on the Make Controller Board. 00287 @param none. 00288 @return none. 00289 */ 00290 /* commented out to avoid 'defined but not used' error 00291 void Eeprom_WriteDisable() 00292 { 00293 uchar c; 00294 c = EEPROM_INSTRUCTION_WRDI; 00295 00296 Spi_ReadWriteBlock( EEPROM_DEVICE, &c, 1 ); 00297 } 00298 */ 00299 00300 void Eeprom_Ready( void ) 00301 { 00302 int status; 00303 do 00304 { 00305 unsigned char c[ 2 ]; 00306 00307 c[ 0 ] = EEPROM_INSTRUCTION_RDSR; 00308 c[ 1 ] = 0; 00309 00310 Spi_ReadWriteBlock( EEPROM_DEVICE, c, 2 ); 00311 00312 status = c[ 1 ] != 0xFF; 00313 00314 } while ( !status ); 00315 } 00316
The Make Controller Kit is an open source project maintained by MakingThings.
MakingThings code is released under the Apache 2.0 license.
Bug tracker, development wiki and status can be found at http://dev.makingthings.com.
This document was last updated on 18 May 2009.