SPIEEPROM.c

Go to the documentation of this file.
00001 
00002 
00003 
00015 /*********************************************************************
00016  * Software License Agreement
00017  *
00018  * Copyright (C) 2002-2008 Microchip Technology Inc.  All rights 
00019  * reserved.
00020  *
00021  * Microchip licenses to you the right to use, modify, copy, and 
00022  * distribute: 
00023  * (i)  the Software when embedded on a Microchip microcontroller or 
00024  *      digital signal controller product ("Device") which is 
00025  *      integrated into Licensee's product; or
00026  * (ii) ONLY the Software driver source files ENC28J60.c and 
00027  *      ENC28J60.h ported to a non-Microchip device used in 
00028  *      conjunction with a Microchip ethernet controller for the 
00029  *      sole purpose of interfacing with the ethernet controller. 
00030  *
00031  * You should refer to the license agreement accompanying this 
00032  * Software for additional information regarding your rights and 
00033  * obligations.
00034  *
00035  * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT 
00036  * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT 
00037  * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A 
00038  * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL 
00039  * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR 
00040  * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF 
00041  * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS 
00042  * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE 
00043  * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER 
00044  * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT 
00045  * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
00046  *
00047  *
00048  * Author               Date        Comment
00049  *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00050  * Nilesh Rajbharti     5/20/02     Original (Rev. 1.0)
00051  * Howard Schlunder     9/01/04     Rewritten for SPI EEPROMs
00052  * Howard Schlunder     8/10/06     Modified to control SPI module 
00053  *                                  frequency whenever EEPROM accessed 
00054  *                                  to allow bus sharing with different 
00055  *                                  frequencies.
00056 ********************************************************************/
00057 #define __SPIEEPROM_C
00058 
00059 #include "TCPIP.h"
00060 
00062 // Local Defines
00064 
00065 // SPI Serial EEPROM buffer size.  To enhance performance while
00066 // cooperatively sharing the SPI bus with other peripherals, bytes 
00067 // read and written to the memory are locally buffered. Legal 
00068 // sizes are 1 to the EEPROM page size.
00069 #define EEPROM_BUFFER_SIZE              (32)
00070 
00071 // EEPROM SPI opcodes
00072 #define READ    0x03    // Read data from memory array beginning at selected address
00073 #define WRITE   0x02    // Write data to memory array beginning at selected address
00074 #define WRDI    0x04    // Reset the write enable latch (disable write operations)
00075 #define WREN    0x06    // Set the write enable latch (enable write operations)
00076 #define RDSR    0x05    // Read Status register
00077 #define WRSR    0x01    // Write Status register
00078 
00079 #define EEPROM_CS_IO    (LATFbits.LATF5)
00080 
00081 
00083 // Local function prototypes
00085 
00086 static void DoWrite(void);
00087 // MODIFIX: Moved the following prototypes from the header file to this 
00088 // location and made them static.
00089 static XEE_RESULT XEEBeginWrite(XEE_ADDR address);
00090 static XEE_RESULT XEEWrite(unsigned char val);
00091 static XEE_RESULT XEEEndWrite(void);
00092 static BOOL XEEIsBusy(void);
00093 
00094 
00096 // Local Variables
00098 
00099 static XEE_ADDR EEPROMAddress;
00100 static BYTE EEPROMBuffer[EEPROM_BUFFER_SIZE];
00101 static BYTE EEPROMBytesToWrite;
00102 static BYTE EEPROMPageSpace;
00103 
00104 
00105 // MODIFIX: Removed the functions XEEInit, XEEBeginRead, XEERead and 
00106 // XEEEndRead.
00107 
00108 /*********************************************************************
00109  * Function:        XEE_RESULT XEEReadArray(XEE_ADDR address,
00110  *                                          BYTE *buffer,
00111  *                                          BYTE length)
00112  *
00113  * PreCondition:    None.
00114  *
00115  * Input:           address     - Address from where array is to be read
00116  *                  buffer      - Caller supplied buffer to hold the data
00117  *                  length      - Number of bytes to read.
00118  *
00119  * Output:          XEE_SUCCESS
00120  *
00121  * Side Effects:    None
00122  *
00123  * Overview:        Reads desired number of bytes in sequential mode.
00124  *                  This function performs all necessary steps
00125  *                  and releases the bus when finished.
00126  *
00127  * Note:            None
00128  ********************************************************************/
00129 
00130 void _startReading(XEE_ADDR Address)
00131 {
00132     BYTE tmp;
00133 
00134     // SPI-Configuration for EEPROM:
00135     // SPI Master / Clock = Fosc/16 / Enable / Clock idle state is low  
00136     SSP1CON1 = 0x21;
00137     SSP1STAT = 0x40;    // CKE = 1
00138 
00139     // Send READ opcode
00140     PIR1bits.SSP1IF = 0;
00141     EEPROM_CS_IO = 0;
00142     SSPBUF = READ;
00143     while(PIR1bits.SSP1IF == 0);
00144     tmp = SSPBUF;
00145     
00146     // Send address (WORD)
00147     PIR1bits.SSP1IF = 0;
00148     SSPBUF = ((WORD_VAL*)&Address)->v[1];
00149     while( PIR1bits.SSP1IF == 0 );
00150     tmp = SSPBUF;
00151     PIR1bits.SSP1IF = 0;
00152     SSPBUF = ((WORD_VAL*)&Address)->v[0];
00153     while( PIR1bits.SSP1IF == 0 );
00154     tmp = SSPBUF;
00155 }
00156 
00159 
00160 
00161 XEE_RESULT XEEReadArray(XEE_ADDR address, BYTE *buffer, BYTE length)
00162 {
00163     BYTE Dummy;
00164     BYTE len = length;
00165     BYTE * pBuf = buffer;
00166 
00167     _startReading(address);
00168     
00169     while(len--)
00170     {
00171         PIR1bits.SSP1IF = 0;
00172         SSPBUF = 0;
00173         while(PIR1bits.SSP1IF == 0);
00174         *pBuf++ = SSPBUF;
00175     }
00176     
00177     EEPROM_CS_IO = 1;
00178 
00179     return XEE_SUCCESS;
00180 }
00181 
00182 
00183 /*********************************************************************
00184  * Function:        XEE_RESULT XEEBeginWrite(XEE_ADDR address)
00185  *
00186  * PreCondition:    None (MODIFIX)
00187  *
00188  * Input:           address     - address to be set for writing
00189  *
00190  * Output:          XEE_SUCCESS
00191  *
00192  * Side Effects:    None
00193  *
00194  * Overview:        Starts the writing of content to EEPROM to the 
00195  *                  given address.
00196  *
00197  ********************************************************************/
00198 XEE_RESULT XEEBeginWrite(XEE_ADDR address)
00199 {
00200     EEPROMAddress = address;
00201     EEPROMBytesToWrite = 0;
00202     EEPROMPageSpace = EEPROM_BUFFER_SIZE-(address % EEPROM_BUFFER_SIZE);
00203     return XEE_SUCCESS;
00204 }
00205 
00206 
00207 /*********************************************************************
00208  * Function:        XEE_RESULT XEEWrite(BYTE val)
00209  *
00210  * PreCondition:    XEEBeginWrite() are already called.
00211  *
00212  * Input:           val - Byte to be written
00213  *
00214  * Output:          XEE_SUCCESS
00215  *
00216  * Side Effects:    None
00217  *
00218  * Overview:        Adds a byte to the current page to be writen when
00219  *                  XEEEndWrite() is called.
00220  *
00221  * Note:            Page boundary cannot be exceeded or the byte 
00222  *                  to be written will be looped back to the 
00223  *                  beginning of the page.
00224  ********************************************************************/
00225 XEE_RESULT XEEWrite(BYTE val)
00226 {
00227     EEPROMBuffer[EEPROMBytesToWrite++] = val;
00228     EEPROMPageSpace--;
00229 
00230     if(EEPROMPageSpace==0)
00231         DoWrite();
00232 
00233     return XEE_SUCCESS;
00234 }
00235 
00236 
00237 /*********************************************************************
00238  * Function:        XEE_RESULT XEEEndWrite(void)
00239  *
00240  * PreCondition:    XEEBeginWrite() is already called.
00241  *
00242  * Input:           None
00243  *
00244  * Output:          XEE_SUCCESS if successful
00245  *                  other value if failed.
00246  *
00247  * Side Effects:    None
00248  *
00249  * Overview:        Instructs EEPROM to begin write cycle.
00250  *
00251  * Note:            Call this function after either page full of bytes
00252  *                  written or no more bytes are left to load.
00253  *                  This function initiates the write cycle.
00254  *                  User must call for XEEIsBusy() to ensure that write
00255  *                  cycle is finished before calling any other
00256  *                  routine.
00257  ********************************************************************/
00258 XEE_RESULT XEEEndWrite(void)
00259 {
00260     if(EEPROMBytesToWrite)
00261         DoWrite();
00262 
00263     return XEE_SUCCESS;
00264 }
00265 
00266 static void DoWrite(void)
00267 {
00268     BYTE Dummy;
00269     BYTE i;
00270 
00271     // SPI-Configuration for EEPROM:
00272     // SPI Master / Clock = Fosc/16 / Enable / Clock idle state is low (CKP=0)  
00273     SSP1CON1 = 0x21;
00274     SSP1STAT = 0x40;    // CKE = 1
00275     
00276     // Set the Write Enable latch
00277     PIR1bits.SSP1IF = 0;
00278     EEPROM_CS_IO = 0;
00279     SSPBUF = WREN;
00280     while( PIR1bits.SSP1IF == 0 );
00281     Dummy = SSPBUF;
00282     EEPROM_CS_IO = 1;
00283     
00284     // Send WRITE opcode
00285     EEPROM_CS_IO = 0;
00286     PIR1bits.SSP1IF = 0;
00287     SSPBUF = WRITE;
00288     while(PIR1bits.SSP1IF == 0);
00289     Dummy = SSPBUF;
00290     
00291     // Send address (WORD)
00292     PIR1bits.SSP1IF = 0;
00293     SSPBUF = ((WORD_VAL*)&EEPROMAddress)->v[1];
00294     while(PIR1bits.SSP1IF == 0);
00295     Dummy = SSPBUF;
00296     PIR1bits.SSP1IF = 0;
00297     SSPBUF = ((WORD_VAL*)&EEPROMAddress)->v[0];
00298     while(PIR1bits.SSP1IF == 0);
00299     Dummy = SSPBUF;
00300     
00301     EEPROMAddress += EEPROMBytesToWrite;
00302 
00303     for (i=0; i<EEPROMBytesToWrite;i++)
00304     {
00305         // Send the byte to write
00306         PIR1bits.SSP1IF = 0;
00307         SSPBUF = EEPROMBuffer[i];
00308         while(PIR1bits.SSP1IF == 0);
00309         Dummy = SSPBUF;
00310     }
00311 
00312     // Begin the write
00313     EEPROM_CS_IO = 1;
00314 
00315     EEPROMBytesToWrite = 0;
00316     EEPROMPageSpace = EEPROM_BUFFER_SIZE;
00317     
00318 
00319     // Wait for write to complete
00320     while( XEEIsBusy() );
00321 }
00322 
00323 
00324 /*********************************************************************
00325  * Function:        BOOL XEEIsBusy(void)
00326  *
00327  * PreCondition:    None.
00328  *
00329  * Input:           None
00330  *
00331  * Output:          FALSE if EEPROM is not busy
00332  *                  TRUE if EEPROM is busy
00333  *
00334  * Side Effects:    None
00335  *
00336  * Overview:        Reads the status register
00337  *
00338  * Note:            None
00339  ********************************************************************/
00340 static BOOL XEEIsBusy(void)
00341 {
00342     BYTE_VAL result;
00343 
00344     // SPI-Configuration for EEPROM:
00345     // SPI Master / Clock = Fosc/16 / Enable / Clock idle state is low  
00346     SSP1CON1 = 0x21;
00347     SSP1STAT = 0x40;    // CKE = 1
00348 
00349     PIR1bits.SSP1IF = 0;
00350     EEPROM_CS_IO = 0;
00351     // Send RDSR - Read Status Register opcode
00352     SSPBUF = RDSR;
00353     while(PIR1bits.SSP1IF == 0);
00354     result.Val = SSPBUF;
00355 
00356     // Get register contents
00357     PIR1bits.SSP1IF = 0;
00358     SSPBUF = 0;
00359     while(PIR1bits.SSP1IF == 0);
00360     result.Val = SSPBUF;
00361     EEPROM_CS_IO = 1;
00362 
00363     return result.bits.b0;
00364 }
00365 
00368 
00369 void XEEEraseEEPROM(void)
00370 {
00371     int i = 0;
00372     XEEBeginWrite(0);
00373 
00374     for (; i < EEPROM_SIZE; i++)
00375     {
00376         XEEWrite(0xFF);
00377     }
00378 
00379     XEEEndWrite();
00380 }
00381 
00384 
00385 void XEEWriteArray(WORD address, BYTE * pData, BYTE len)
00386 {
00387     BYTE i;
00388 
00389     XEEBeginWrite(address);
00390 
00391     for (i = 0; i < len; i++)
00392         XEEWrite(pData[i]); 
00393 
00394     XEEEndWrite();
00395 }
00396 

Generated on Sun Nov 27 20:02:38 2011 for eWicht by  doxygen 1.5.5