/[H8]/trunk/docs/Microchip TCP_IP stack/TCPIP Stack/SPIEEPROM.c
ViewVC logotype

Annotation of /trunk/docs/Microchip TCP_IP stack/TCPIP Stack/SPIEEPROM.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 15 - (hide annotations) (download)
Thu Apr 19 09:01:15 2007 UTC (17 years, 2 months ago) by hedin
File MIME type: text/plain
File size: 16259 byte(s)
added the TCP/IP stack, source code.
1 hedin 15 /*********************************************************************
2     *
3     * Data SPI EEPROM Access Routines
4     *
5     *********************************************************************
6     * FileName: SPIEEPROM.c
7     * Dependencies: Compiler.h
8     * XEEPROM.h
9     * Processor: PIC18, PIC24F, PIC24H, dsPIC30F, dsPIC33F
10     * Complier: Microchip C18 v3.02 or higher
11     * Microchip C30 v2.01 or higher
12     * Company: Microchip Technology, Inc.
13     *
14     * Software License Agreement
15     *
16     * Copyright © 2002-2007 Microchip Technology Inc. All rights
17     * reserved.
18     *
19     * Microchip licenses to you the right to use, modify, copy, and
20     * distribute:
21     * (i) the Software when embedded on a Microchip microcontroller or
22     * digital signal controller product (“Device”) which is
23     * integrated into Licensee’s product; or
24     * (ii) ONLY the Software driver source files ENC28J60.c and
25     * ENC28J60.h ported to a non-Microchip device used in
26     * conjunction with a Microchip ethernet controller for the
27     * sole purpose of interfacing with the ethernet controller.
28     *
29     * You should refer to the license agreement accompanying this
30     * Software for additional information regarding your rights and
31     * obligations.
32     *
33     * THE SOFTWARE AND DOCUMENTATION ARE PROVIDED “AS IS” WITHOUT
34     * WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT
35     * LIMITATION, ANY WARRANTY OF MERCHANTABILITY, FITNESS FOR A
36     * PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT SHALL
37     * MICROCHIP BE LIABLE FOR ANY INCIDENTAL, SPECIAL, INDIRECT OR
38     * CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF
39     * PROCUREMENT OF SUBSTITUTE GOODS, TECHNOLOGY OR SERVICES, ANY CLAIMS
40     * BY THIRD PARTIES (INCLUDING BUT NOT LIMITED TO ANY DEFENSE
41     * THEREOF), ANY CLAIMS FOR INDEMNITY OR CONTRIBUTION, OR OTHER
42     * SIMILAR COSTS, WHETHER ASSERTED ON THE BASIS OF CONTRACT, TORT
43     * (INCLUDING NEGLIGENCE), BREACH OF WARRANTY, OR OTHERWISE.
44     *
45     *
46     * Author Date Comment
47     *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
48     * Nilesh Rajbharti 5/20/02 Original (Rev. 1.0)
49     * Howard Schlunder 9/01/04 Rewritten for SPI EEPROMs
50     * Howard Schlunder 8/10/06 Modified to control SPI module
51     * frequency whenever EEPROM accessed
52     * to allow bus sharing with different
53     * frequencies.
54     ********************************************************************/
55     #define __SPIEEPROM_C
56    
57     #include "TCPIP Stack/TCPIP.h"
58    
59     #if defined(MPFS_USE_EEPROM) && defined(EEPROM_CS_TRIS) && defined(STACK_USE_MPFS)
60    
61     // IMPORTANT SPI NOTE: The code in this file expects that the SPI interrupt
62     // flag (EEPROM_SPI_IF) be clear at all times. If the SPI is shared with
63     // other hardware, the other code should clear the EEPROM_SPI_IF when it is
64     // done using the SPI.
65    
66     // SPI Serial EEPROM buffer size. To enhance performance while
67     // cooperatively sharing the SPI bus with other peripherals, bytes
68     // read and written to the memory are locally buffered. Legal
69     // sizes are 1 to the EEPROM page size.
70     #define EEPROM_BUFFER_SIZE (32)
71    
72     // EEPROM SPI opcodes
73     #define READ 0x03 // Read data from memory array beginning at selected address
74     #define WRITE 0x02 // Write data to memory array beginning at selected address
75     #define WRDI 0x04 // Reset the write enable latch (disable write operations)
76     #define WREN 0x06 // Set the write enable latch (enable write operations)
77     #define RDSR 0x05 // Read Status register
78     #define WRSR 0x01 // Write Status register
79    
80     static void DoWrite(void);
81    
82     static WORD EEPROMAddress;
83     static BYTE EEPROMBuffer[EEPROM_BUFFER_SIZE];
84     static BYTE *EEPROMBufferPtr;
85    
86     /*********************************************************************
87     * Function: void XEEInit(unsigned char speed)
88     *
89     * PreCondition: None
90     *
91     * Input: speed - not used (included for compatibility only)
92     *
93     * Output: None
94     *
95     * Side Effects: None
96     *
97     * Overview: Initialize SPI module to communicate to serial
98     * EEPROM.
99     *
100     * Note: Code sets SPI clock to Fosc/16.
101     ********************************************************************/
102     #if defined(HPC_EXPLORER) && !defined(__18F87J10)
103     #define PROPER_SPICON1 (0x20) /* SSPEN bit is set, SPI in master mode, FOSC/4, IDLE state is low level */
104     #elif defined(__PIC24F__)
105     #define PROPER_SPICON1 (0x0013 | 0x0120) /* 1:1 primary prescale, 4:1 secondary prescale, CKE=1, MASTER mode */
106     #elif defined(__dsPIC30F__)
107     #define PROPER_SPICON1 (0x0017 | 0x0120) /* 1:1 primary prescale, 3:1 secondary prescale, CKE=1, MASTER mode */
108     #elif defined(__dsPIC33F__) || defined(__PIC24H__)
109     #define PROPER_SPICON1 (0x0003 | 0x0120) /* 1:1 primary prescale, 8:1 secondary prescale, CKE=1, MASTER mode */
110     #else
111     #define PROPER_SPICON1 (0x21) /* SSPEN bit is set, SPI in master mode, FOSC/16, IDLE state is low level */
112     #endif
113    
114     void XEEInit(void)
115     {
116     EEPROM_CS_IO = 1;
117     EEPROM_CS_TRIS = 0; // Drive SPI EEPROM chip select pin
118    
119     EEPROM_SCK_TRIS = 0; // Set SCK pin as an output
120     EEPROM_SDI_TRIS = 1; // Make sure SDI pin is an input
121     EEPROM_SDO_TRIS = 0; // Set SDO pin as an output
122    
123     EEPROM_SPICON1 = PROPER_SPICON1; // See PROPER_SPICON1 definition above
124     #if defined(__C30__)
125     EEPROM_SPICON2 = 0;
126     EEPROM_SPISTAT = 0; // clear SPI
127     EEPROM_SPISTATbits.SPIEN = 1;
128     #elif defined(__18CXX)
129     EEPROM_SPI_IF = 0;
130     EEPROM_SPISTATbits.CKE = 1; // Transmit data on rising edge of clock
131     EEPROM_SPISTATbits.SMP = 0; // Input sampled at middle of data output time
132     #endif
133     }
134    
135    
136     /*********************************************************************
137     * Function: XEE_RESULT XEEBeginRead(unsigned char control,
138     * XEE_ADDR address)
139     *
140     * PreCondition: XEEInit() is already called.
141     *
142     * Input: control - EEPROM control and address code.
143     * address - Address at which read is to be performed.
144     *
145     * Output: XEE_SUCCESS if successful
146     * other value if failed.
147     *
148     * Side Effects: None
149     *
150     * Overview: Sets internal address counter to given address.
151     * Puts EEPROM in sequential read mode.
152     *
153     * Note: This function does not release I2C bus.
154     * User must call XEEEndRead() when read is not longer
155     * needed; I2C bus will released after XEEEndRead()
156     * is called.
157     ********************************************************************/
158     XEE_RESULT XEEBeginRead(XEE_ADDR address)
159     {
160     // Save the address and emptry the contents of our local buffer
161     EEPROMAddress = address;
162     EEPROMBufferPtr = EEPROMBuffer + EEPROM_BUFFER_SIZE;
163     return XEE_SUCCESS;
164     }
165    
166    
167     /*********************************************************************
168     * Function: XEE_RESULT XEERead(void)
169     *
170     * PreCondition: XEEInit() && XEEBeginRead() are already called.
171     *
172     * Input: None
173     *
174     * Output: XEE_SUCCESS if successful
175     * other value if failed.
176     *
177     * Side Effects: None
178     *
179     * Overview: Reads next byte from EEPROM; internal address
180     * is incremented by one.
181     *
182     * Note: This function does not release I2C bus.
183     * User must call XEEEndRead() when read is not longer
184     * needed; I2C bus will released after XEEEndRead()
185     * is called.
186     ********************************************************************/
187     unsigned char XEERead(void)
188     {
189     // Check if no more bytes are left in our local buffer
190     if( EEPROMBufferPtr == EEPROMBuffer + EEPROM_BUFFER_SIZE )
191     {
192     // Get a new set of bytes
193     XEEReadArray(EEPROMAddress, EEPROMBuffer, EEPROM_BUFFER_SIZE);
194     EEPROMAddress += EEPROM_BUFFER_SIZE;
195     EEPROMBufferPtr = EEPROMBuffer;
196     }
197    
198     // Return a byte from our local buffer
199     return *EEPROMBufferPtr++;
200     }
201    
202     /*********************************************************************
203     * Function: XEE_RESULT XEEEndRead(void)
204     *
205     * PreCondition: XEEInit() && XEEBeginRead() are already called.
206     *
207     * Input: None
208     *
209     * Output: XEE_SUCCESS if successful
210     * other value if failed.
211     *
212     * Side Effects: None
213     *
214     * Overview: Ends sequential read cycle.
215     *
216     * Note: This function ends sequential cycle that was in
217     * progress. It releases I2C bus.
218     ********************************************************************/
219     XEE_RESULT XEEEndRead(void)
220     {
221     return XEE_SUCCESS;
222     }
223    
224    
225     /*********************************************************************
226     * Function: XEE_RESULT XEEReadArray(unsigned char control,
227     * XEE_ADDR address,
228     * unsigned char *buffer,
229     * unsigned char length)
230     *
231     * PreCondition: XEEInit() is already called.
232     *
233     * Input: control - Unused
234     * address - Address from where array is to be read
235     * buffer - Caller supplied buffer to hold the data
236     * length - Number of bytes to read.
237     *
238     * Output: XEE_SUCCESS if successful
239     * other value if failed.
240     *
241     * Side Effects: None
242     *
243     * Overview: Reads desired number of bytes in sequential mode.
244     * This function performs all necessary steps
245     * and releases the bus when finished.
246     *
247     * Note: None
248     ********************************************************************/
249     XEE_RESULT XEEReadArray(XEE_ADDR address,
250     unsigned char *buffer,
251     unsigned char length)
252     {
253     BYTE Dummy;
254     #if defined(__18CXX)
255     BYTE SPICON1Save;
256     #else
257     WORD SPICON1Save;
258     #endif
259    
260     // Save SPI state (clock speed)
261     SPICON1Save = EEPROM_SPICON1;
262     EEPROM_SPICON1 = PROPER_SPICON1;
263    
264     EEPROM_CS_IO = 0;
265    
266     // Send READ opcode
267     EEPROM_SSPBUF = READ;
268     while(!EEPROM_SPI_IF);
269     Dummy = EEPROM_SSPBUF;
270     EEPROM_SPI_IF = 0;
271    
272     // Send address
273     EEPROM_SSPBUF = ((WORD_VAL*)&address)->v[1];
274     while(!EEPROM_SPI_IF);
275     Dummy = EEPROM_SSPBUF;
276     EEPROM_SPI_IF = 0;
277     EEPROM_SSPBUF = ((WORD_VAL*)&address)->v[0];
278     while(!EEPROM_SPI_IF);
279     Dummy = EEPROM_SSPBUF;
280     EEPROM_SPI_IF = 0;
281    
282     while(length--)
283     {
284     EEPROM_SSPBUF = 0;
285     while(!EEPROM_SPI_IF);
286     *buffer++ = EEPROM_SSPBUF;
287     EEPROM_SPI_IF = 0;
288     };
289    
290     EEPROM_CS_IO = 1;
291    
292     // Restore SPI state
293     EEPROM_SPICON1 = SPICON1Save;
294    
295     return XEE_SUCCESS;
296     }
297    
298    
299     /*********************************************************************
300     * Function: XEE_RESULT XEESetAddr(unsigned char control,
301     * XEE_ADDR address)
302     *
303     * PreCondition: XEEInit() is already called.
304     *
305     * Input: control - data EEPROM control code
306     * address - address to be set for writing
307     *
308     * Output: XEE_SUCCESS if successful
309     * other value if failed.
310     *
311     * Side Effects: None
312     *
313     * Overview: Modifies internal address counter of EEPROM.
314     *
315     * Note: Unlike XEESetAddr() in xeeprom.c for I2C EEPROM
316     * memories, this function is used only for writing
317     * to the EEPROM. Reads must use XEEBeginRead(),
318     * XEERead(), and XEEEndRead().
319     * This function does not release the SPI bus.
320     ********************************************************************/
321     XEE_RESULT XEEBeginWrite(XEE_ADDR address)
322     {
323     EEPROMAddress = address;
324     EEPROMBufferPtr = EEPROMBuffer;
325     return XEE_SUCCESS;
326     }
327    
328    
329     /*********************************************************************
330     * Function: XEE_RESULT XEEWrite(unsigned char val)
331     *
332     * PreCondition: XEEInit() && XEEBeginWrite() are already called.
333     *
334     * Input: val - Byte to be written
335     *
336     * Output: XEE_SUCCESS
337     *
338     * Side Effects: None
339     *
340     * Overview: Adds a byte to the current page to be writen when
341     * XEEEndWrite() is called.
342     *
343     * Note: Page boundary cannot be exceeded or the byte
344     * to be written will be looped back to the
345     * beginning of the page.
346     ********************************************************************/
347     XEE_RESULT XEEWrite(unsigned char val)
348     {
349     *EEPROMBufferPtr++ = val;
350     if( EEPROMBufferPtr == EEPROMBuffer + EEPROM_BUFFER_SIZE )
351     {
352     DoWrite();
353     }
354    
355     return XEE_SUCCESS;
356     }
357    
358    
359     /*********************************************************************
360     * Function: XEE_RESULT XEEEndWrite(void)
361     *
362     * PreCondition: XEEInit() && XEEBeginWrite() are already called.
363     *
364     * Input: None
365     *
366     * Output: XEE_SUCCESS if successful
367     * other value if failed.
368     *
369     * Side Effects: None
370     *
371     * Overview: Instructs EEPROM to begin write cycle.
372     *
373     * Note: Call this function after either page full of bytes
374     * written or no more bytes are left to load.
375     * This function initiates the write cycle.
376     * User must call for XEEIsBusy() to ensure that write
377     * cycle is finished before calling any other
378     * routine.
379     ********************************************************************/
380     XEE_RESULT XEEEndWrite(void)
381     {
382     if( EEPROMBufferPtr != EEPROMBuffer )
383     {
384     DoWrite();
385     }
386    
387     return XEE_SUCCESS;
388     }
389    
390     static void DoWrite(void)
391     {
392     BYTE Dummy;
393     BYTE BytesToWrite;
394     #if defined(__18CXX)
395     BYTE SPICON1Save;
396     #else
397     WORD SPICON1Save;
398     #endif
399    
400     // Save SPI state (clock speed)
401     SPICON1Save = EEPROM_SPICON1;
402     EEPROM_SPICON1 = PROPER_SPICON1;
403    
404     // Set the Write Enable latch
405     EEPROM_CS_IO = 0;
406     EEPROM_SSPBUF = WREN;
407     while(!EEPROM_SPI_IF);
408     Dummy = EEPROM_SSPBUF;
409     EEPROM_SPI_IF = 0;
410     EEPROM_CS_IO = 1;
411    
412     // Send WRITE opcode
413     EEPROM_CS_IO = 0;
414     EEPROM_SSPBUF = WRITE;
415     while(!EEPROM_SPI_IF);
416     Dummy = EEPROM_SSPBUF;
417     EEPROM_SPI_IF = 0;
418    
419     // Send address
420     EEPROM_SSPBUF = ((WORD_VAL*)&EEPROMAddress)->v[1];
421     while(!EEPROM_SPI_IF);
422     Dummy = EEPROM_SSPBUF;
423     EEPROM_SPI_IF = 0;
424     EEPROM_SSPBUF = ((WORD_VAL*)&EEPROMAddress)->v[0];
425     while(!EEPROM_SPI_IF);
426     Dummy = EEPROM_SSPBUF;
427     EEPROM_SPI_IF = 0;
428    
429     BytesToWrite = (BYTE)(EEPROMBufferPtr - EEPROMBuffer);
430    
431     EEPROMAddress += BytesToWrite;
432     EEPROMBufferPtr = EEPROMBuffer;
433    
434     while(BytesToWrite--)
435     {
436     // Send the byte to write
437     EEPROM_SSPBUF = *EEPROMBufferPtr++;
438     while(!EEPROM_SPI_IF);
439     Dummy = EEPROM_SSPBUF;
440     EEPROM_SPI_IF = 0;
441     }
442    
443     // Begin the write
444     EEPROM_CS_IO = 1;
445    
446     EEPROMBufferPtr = EEPROMBuffer;
447    
448     // Restore SPI State
449     EEPROM_SPICON1 = SPICON1Save;
450    
451     // Wait for write to complete
452     while( XEEIsBusy() );
453     }
454    
455    
456     /*********************************************************************
457     * Function: BOOL XEEIsBusy(void)
458     *
459     * PreCondition: XEEInit() is already called.
460     *
461     * Input: None
462     *
463     * Output: FALSE if EEPROM is not busy
464     * TRUE if EEPROM is busy
465     *
466     * Side Effects: None
467     *
468     * Overview: Reads the status register
469     *
470     * Note: None
471     ********************************************************************/
472     BOOL XEEIsBusy(void)
473     {
474     BYTE_VAL result;
475     #if defined(__18CXX)
476     BYTE SPICON1Save;
477     #else
478     WORD SPICON1Save;
479     #endif
480    
481     // Save SPI state (clock speed)
482     SPICON1Save = EEPROM_SPICON1;
483     EEPROM_SPICON1 = PROPER_SPICON1;
484    
485     EEPROM_CS_IO = 0;
486     // Send RDSR - Read Status Register opcode
487     EEPROM_SSPBUF = RDSR;
488     while(!EEPROM_SPI_IF);
489     result.Val = EEPROM_SSPBUF;
490     EEPROM_SPI_IF = 0;
491    
492     // Get register contents
493     EEPROM_SSPBUF = 0;
494     while(!EEPROM_SPI_IF);
495     result.Val = EEPROM_SSPBUF;
496     EEPROM_SPI_IF = 0;
497     EEPROM_CS_IO = 1;
498    
499     // Restore SPI State
500     EEPROM_SPICON1 = SPICON1Save;
501    
502     return result.bits.b0;
503     }
504    
505    
506     #endif //#if defined(MPFS_USE_EEPROM) && defined(EEPROM_CS_TRIS) && defined(STACK_USE_MPFS)

  ViewVC Help
Powered by ViewVC 1.1.20