MakingThings
  • Main Page
  • Related Pages
  • Modules
  • Data Structures
  • Files
  • File List
  • Globals

eeprom.c

Go to the documentation of this file.
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.