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)
|