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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 62 - (hide 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 hedin 62 /*********************************************************************
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