/[H8]/trunk/docs/MCHPStack2.20/Source/xeeprom.c
ViewVC logotype

Contents of /trunk/docs/MCHPStack2.20/Source/xeeprom.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (show annotations) (download)
Tue May 1 08:17:39 2007 UTC (17 years, 2 months ago) by hedin
File MIME type: text/plain
File size: 16899 byte(s)
Removed tcpip stack 4.02 and added tcpip stack 2.20.
1 /*********************************************************************
2 *
3 * Data EEPROM Access Routines
4 *
5 *********************************************************************
6 * FileName: xeeprom.c
7 * Dependencies: compiler.h
8 * xeeprom.h
9 * Processor: PIC18
10 * Complier: MCC18 v1.00.50 or higher
11 * HITECH PICC-18 V8.10PL1 or higher
12 * Company: Microchip Technology, Inc.
13 *
14 * Software License Agreement
15 *
16 * The software supplied herewith by Microchip Technology Incorporated
17 * (the “Company”) for its PICmicro® Microcontroller is intended and
18 * supplied to you, the Company’s customer, for use solely and
19 * exclusively on Microchip PICmicro Microcontroller products. The
20 * software is owned by the Company and/or its supplier, and is
21 * protected under applicable copyright laws. All rights are reserved.
22 * Any use in violation of the foregoing restrictions may subject the
23 * user to criminal sanctions under applicable laws, as well as to
24 * civil liability for the breach of the terms and conditions of this
25 * license.
26 *
27 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
28 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
29 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
30 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
31 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
32 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
33 *
34 * This is a modified version of C18 library functions.
35 * This version supports data EEPROM with two bytes of address.
36 * It still uses some of the routines from C18 library.
37 *
38 *
39 * HiTech PICC18 Compiler Options excluding device selection:
40 * -FAKELOCAL -G -O -Zg -E -C
41 *
42 *
43 * Author Date Comment
44 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45 * Nilesh Rajbharti 5/20/02 Original (Rev. 1.0)
46 ********************************************************************/
47 #include "compiler.h"
48 #include "xeeprom.h"
49
50 #define IdleI2C() while ( ( SSPCON2 & 0x1F ) | ( SSPSTAT_R_W ) );
51 #define StartI2C() SSPCON2_SEN=1
52 #define RestartI2C() SSPCON2_RSEN=1
53 #define StopI2C() SSPCON2_PEN=1
54 #define NotAckI2C() SSPCON2_ACKDT=1, SSPCON2_ACKEN=1
55
56 static unsigned char getcI2C( void );
57 static unsigned char WriteI2C( unsigned char data_out );
58 XEE_RESULT XEEClose(void);
59
60
61
62 /*********************************************************************
63 * Function: void XEEInit(unsigned char baud)
64 *
65 * PreCondition: None
66 *
67 * Input: baud - SSPADD value for bit rate.
68 *
69 * Output: None
70 *
71 * Side Effects: None
72 *
73 * Overview: Initialize I2C module to communicate to serial
74 * EEPROM.
75 *
76 * Note: None
77 ********************************************************************/
78 #define MASTER 8 /* I2C Master mode */
79 /* SSPSTAT REGISTER */
80 #define SLEW_OFF 0xC0 /* Slew rate disabled for 100kHz mode */
81 #define SLEW_ON 0x00 /* Slew rate enabled for 400kHz mode */
82 #define SSPENB 0x20 /* Enable serial port and configures
83 SCK, SDO, SDI */
84 void XEEInit(unsigned char baud)
85 {
86 SSPSTAT &= 0x3F; // power on state
87 SSPCON1 = 0x00; // power on state
88 SSPCON2 = 0x00; // power on state
89 SSPCON1 |= MASTER; // select serial mode
90 SSPSTAT |= SLEW_ON; // slew rate on/off
91
92 TRISC_RC3 = 1; // Set SCL (PORTC,3) pin to input
93 TRISC_RC4 = 1; // Set SDA (PORTC,4) pin to input
94
95 SSPCON1 |= SSPENB; // enable synchronous serial port
96
97 SSPADD = baud;
98 }
99
100
101 /*********************************************************************
102 * Function: XEE_RESULT XEESetAddr(unsigned char control,
103 * XEE_ADDR address)
104 *
105 * PreCondition: XEEInit() is already called.
106 *
107 * Input: control - data EEPROM control code
108 * address - address to be set
109 *
110 * Output: XEE_SUCCESS if successful
111 * other value if failed.
112 *
113 * Side Effects: None
114 *
115 * Overview: Modifies internal address counter of EEPROM.
116 *
117 * Note: This function does not release the I2C bus.
118 * User must close XEEClose() after this function
119 * is called.
120 ********************************************************************/
121 XEE_RESULT XEESetAddr(unsigned char control, XEE_ADDR address)
122 {
123 union
124 {
125 unsigned short int Val;
126 struct
127 {
128 unsigned char LSB;
129 unsigned char MSB;
130 } bytes;
131 } tempAddress;
132
133 tempAddress.Val = address;
134
135 IdleI2C(); // ensure module is idle
136 StartI2C(); // initiate START condition
137 while ( SSPCON2_SEN ); // wait until start condition is over
138 if ( PIR2_BCLIF ) // test for bus collision
139 return XEE_BUS_COLLISION; // return with Bus Collision error
140
141 if ( WriteI2C( control ) ) // write 1 byte
142 return XEE_BUS_COLLISION; // set error for write collision
143
144 IdleI2C(); // ensure module is idle
145 if ( !SSPCON2_ACKSTAT ) // test for ACK condition, if received
146 {
147 if ( WriteI2C( tempAddress.bytes.MSB ) ) // WRITE word address to EEPROM
148 return XEE_BUS_COLLISION; // return with write collision error
149
150 IdleI2C(); // ensure module is idle
151
152 if ( WriteI2C( tempAddress.bytes.LSB ) ) // WRITE word address to EEPROM
153 return XEE_BUS_COLLISION; // return with write collision error
154
155 IdleI2C(); // ensure module is idle
156 if ( !SSPCON2_ACKSTAT ) // test for ACK condition received
157 return XEE_SUCCESS;
158 else
159 return XEE_NAK; // return with Not Ack error
160 }
161 else
162 return XEE_NAK; // return with Not Ack error
163 }
164
165 /*********************************************************************
166 * Function: XEE_RESULT XEEBeginRead(unsigned char control,
167 * XEE_ADDR address)
168 *
169 * PreCondition: XEEInit() is already called.
170 *
171 * Input: control - EEPROM control and address code.
172 * address - Address at which read is to be performed.
173 *
174 * Output: XEE_SUCCESS if successful
175 * other value if failed.
176 *
177 * Side Effects: None
178 *
179 * Overview: Sets internal address counter to given address.
180 * Puts EEPROM in sequential read mode.
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 XEE_RESULT XEEBeginRead(unsigned char control, XEE_ADDR address )
188 {
189 unsigned char r;
190
191 r = XEESetAddr(control, address);
192 if ( r != XEE_SUCCESS )
193 return r;
194
195 r = XEEClose();
196 if ( r != XEE_SUCCESS )
197 return r;
198
199
200 IdleI2C();
201 StartI2C();
202 while( SSPCON2_SEN );
203 if ( PIR2_BCLIF )
204 return XEE_BUS_COLLISION;
205
206 if ( WriteI2C(control+1) )
207 return XEE_BUS_COLLISION;
208
209 IdleI2C();
210 if ( !SSPCON2_ACKSTAT )
211 return XEE_SUCCESS;
212 return XEE_NAK;
213 }
214
215
216 XEE_RESULT XEEWrite(unsigned char val)
217 {
218 IdleI2C(); // ensure module is idle
219
220 if ( WriteI2C( val ) ) // data byte for EEPROM
221 return XEE_BUS_COLLISION; // set error for write collision
222
223 IdleI2C();
224 if ( !SSPCON2_ACKSTAT )
225 return XEE_SUCCESS;
226 return XEE_NAK;
227 }
228
229 /*********************************************************************
230 * Function: XEE_RESULT XEEEndWrite(void)
231 *
232 * PreCondition: XEEInit() && XEEBeginWrite() are already called.
233 *
234 * Input: None
235 *
236 * Output: XEE_SUCCESS if successful
237 * other value if failed.
238 *
239 * Side Effects: None
240 *
241 * Overview: Instructs EEPROM to begin write cycle.
242 *
243 * Note: Call this function after either page full of bytes
244 * written or no more bytes are left to load.
245 * This function initiates the write cycle.
246 * User must call for XEEWait() to ensure that write
247 * cycle is finished before calling any other
248 * routine.
249 ********************************************************************/
250 XEE_RESULT XEEEndWrite(void)
251 {
252 IdleI2C();
253 StopI2C();
254 while(SSPCON2_PEN);
255 return XEE_SUCCESS;
256 }
257
258
259
260 /*********************************************************************
261 * Function: XEE_RESULT XEERead(void)
262 *
263 * PreCondition: XEEInit() && XEEBeginRead() are already called.
264 *
265 * Input: None
266 *
267 * Output: XEE_SUCCESS if successful
268 * other value if failed.
269 *
270 * Side Effects: None
271 *
272 * Overview: Reads next byte from EEPROM; internal address
273 * is incremented by one.
274 *
275 * Note: This function does not release I2C bus.
276 * User must call XEEEndRead() when read is not longer
277 * needed; I2C bus will released after XEEEndRead()
278 * is called.
279 ********************************************************************/
280 unsigned char XEERead(void)
281 {
282 getcI2C();
283 while( SSPCON2_RCEN ); // check that receive sequence is over.
284
285 SSPCON2_ACKDT = 0; // Set ack bit
286 SSPCON2_ACKEN = 1;
287 while( SSPCON2_ACKEN );
288
289 return SSPBUF;
290 }
291
292 /*********************************************************************
293 * Function: XEE_RESULT XEEEndRead(void)
294 *
295 * PreCondition: XEEInit() && XEEBeginRead() are already called.
296 *
297 * Input: None
298 *
299 * Output: XEE_SUCCESS if successful
300 * other value if failed.
301 *
302 * Side Effects: None
303 *
304 * Overview: Ends sequential read cycle.
305 *
306 * Note: This function ends seuential cycle that was in
307 * progress. It releases I2C bus.
308 ********************************************************************/
309 XEE_RESULT XEEEndRead(void)
310 {
311 getcI2C();
312 while( SSPCON2_RCEN ); // check that receive sequence is over.
313
314 NotAckI2C();
315 while( SSPCON2_ACKEN );
316
317 StopI2C();
318 while( SSPCON2_PEN );
319
320 return XEE_SUCCESS;
321 }
322
323
324 /*********************************************************************
325 * Function: XEE_RESULT XEEReadArray(unsigned char control,
326 * XEE_ADDR address,
327 * unsigned char *buffer,
328 * unsigned char length)
329 *
330 * PreCondition: XEEInit() is already called.
331 *
332 * Input: control - EEPROM control and address code.
333 * address - Address from where array is to be read
334 * buffer - Caller supplied buffer to hold the data
335 * length - Number of bytes to read.
336 *
337 * Output: XEE_SUCCESS if successful
338 * other value if failed.
339 *
340 * Side Effects: None
341 *
342 * Overview: Reads desired number of bytes in sequential mode.
343 * This function performs all necessary steps
344 * and releases the bus when finished.
345 *
346 * Note: None
347 ********************************************************************/
348 XEE_RESULT XEEReadArray(unsigned char control,
349 XEE_ADDR address,
350 unsigned char *buffer,
351 unsigned char length)
352 {
353 XEE_RESULT r;
354
355 r = XEEBeginRead(control, address);
356 if ( r != XEE_SUCCESS )
357 return r;
358
359 while( length-- )
360 *buffer++ = XEERead();
361
362 r = XEEEndRead();
363
364 return r;
365 }
366
367
368
369
370 XEE_RESULT XEEClose(void)
371 {
372 IdleI2C();
373 StopI2C();
374 while( SSPCON2_PEN ); // wait until stop condition is over.
375 if ( PIR2_BCLIF )
376 return XEE_BUS_COLLISION;
377 return XEE_SUCCESS;
378 }
379
380
381
382 /*********************************************************************
383 * Function: XEE_RESULT XEEIsBusy(unsigned char control)
384 *
385 * PreCondition: XEEInit() is already called.
386 *
387 * Input: control - EEPROM control and address code.
388 *
389 * Output: XEE_READY if EEPROM is not busy
390 * XEE_BUSY if EEPROM is busy
391 * other value if failed.
392 *
393 * Side Effects: None
394 *
395 * Overview: Requests ack from EEPROM.
396 *
397 * Note: None
398 ********************************************************************/
399 XEE_RESULT XEEIsBusy(unsigned char control)
400 {
401 XEE_RESULT r;
402
403 IdleI2C(); // ensure module is idle
404 StartI2C(); // initiate START condition
405 while ( SSPCON2_SEN ); // wait until start condition is over
406 if ( PIR2_BCLIF ) // test for bus collision
407 {
408 return XEE_BUS_COLLISION; // return with Bus Collision error
409 }
410
411 else
412 {
413 if ( WriteI2C( control ) ) // write byte - R/W bit should be 0
414 return XEE_BUS_COLLISION; // set error for write collision
415
416 IdleI2C(); // ensure module is idle
417 if ( PIR2_BCLIF ) // test for bus collision
418 return XEE_BUS_COLLISION; // return with Bus Collision error
419
420 if ( !SSPCON2_ACKSTAT )
421 r = XEE_READY;
422 else
423 r = XEE_BUSY;
424
425 #if 0
426 while ( SSPCON2_ACKSTAT ) // test for ACK condition received
427 {
428 RestartI2C(); // initiate Restart condition
429 while ( SSPCON2_RSEN ); // wait until re-start condition is over
430 if ( PIR2_BCLIF ) // test for bus collision
431 return XEE_BUS_COLLISION; // return with Bus Collision error
432
433 if ( WriteI2C( control ) ) // write byte - R/W bit should be 0
434 return XEE_BUS_COLLISION; // set error for write collision
435
436 IdleI2C(); // ensure module is idle
437 }
438 #endif
439 }
440
441
442 StopI2C(); // send STOP condition
443 while ( SSPCON2_PEN ); // wait until stop condition is over
444 if ( PIR2_BCLIF ) // test for bus collision
445 return XEE_BUS_COLLISION; // return with Bus Collision error
446
447 return r;
448 //return XEE_READY; // return with no error
449 }
450
451
452 /********************************************************************
453 * Function Name: WriteI2C *
454 * Return Value: Status byte for WCOL detection. *
455 * Parameters: Single data byte for I2C bus. *
456 * Description: This routine writes a single byte to the *
457 * I2C bus. *
458 ********************************************************************/
459 static unsigned char WriteI2C( unsigned char data_out )
460 {
461 SSPBUF = data_out; // write single byte to SSPBUF
462 if ( SSPCON1_WCOL ) // test if write collision occurred
463 return ( -1 ); // if WCOL bit is set return negative #
464 else
465 {
466 while( SSPSTAT_BF ); // wait until write cycle is complete
467 return ( 0 ); // if WCOL bit is not set return non-negative #
468 }
469 }
470
471
472
473 /********************************************************************
474 * Function Name: ReadI2C *
475 * Return Value: contents of SSPBUF register *
476 * Parameters: void *
477 * Description: Read single byte from I2C bus. *
478 ********************************************************************/
479 static unsigned char getcI2C( void )
480 {
481 SSPCON2_RCEN = 1; // enable master for 1 byte reception
482 while ( !SSPSTAT_BF ); // wait until byte received
483 return ( SSPBUF ); // return with read byte
484 }

  ViewVC Help
Powered by ViewVC 1.1.20