slime@2
|
1 |
/*
|
slime@2
|
2 |
* Project Frontplatte
|
slime@2
|
3 |
*
|
slime@2
|
4 |
* myi2c.c - I2C-Bus Commands
|
slime@2
|
5 |
*
|
slime@2
|
6 |
* This file is released under the GNU General Public License. Refer
|
slime@2
|
7 |
* to the COPYING file distributed with this package.
|
slime@2
|
8 |
*
|
slime@2
|
9 |
* (c) 2007 Carsten Presser cpresser AT fsing.uni-sb.de
|
slime@2
|
10 |
* most parts are taken from AN991 by microchip
|
slime@2
|
11 |
*/
|
slime@2
|
12 |
|
slime@2
|
13 |
#include <p18cxxx.h>
|
slime@2
|
14 |
#include "myi2c.h"
|
slime@2
|
15 |
#include <i2c.h>
|
slime@2
|
16 |
|
slime@2
|
17 |
|
slime@2
|
18 |
unsigned int PageSize;
|
slime@2
|
19 |
|
slime@2
|
20 |
|
slime@2
|
21 |
unsigned char LDByteWriteI2C( unsigned char ControlByte, unsigned char LowAdd, unsigned char data )
|
slime@2
|
22 |
{
|
slime@2
|
23 |
IdleI2C(); // ensure module is idle
|
slime@2
|
24 |
StartI2C(); // initiate START condition
|
slime@2
|
25 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
26 |
WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
|
slime@2
|
27 |
IdleI2C(); // ensure module is idle
|
slime@2
|
28 |
WriteI2C( LowAdd ); // write address byte to EEPROM
|
slime@2
|
29 |
IdleI2C(); // ensure module is idle
|
slime@2
|
30 |
WriteI2C ( data ); // Write data byte to EEPROM
|
slime@2
|
31 |
IdleI2C(); // ensure module is idle
|
slime@2
|
32 |
StopI2C(); // send STOP condition
|
slime@2
|
33 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
34 |
while (EEAckPolling(ControlByte)); //Wait for write cycle to complete
|
slime@2
|
35 |
return ( 0 ); // return with no error
|
slime@2
|
36 |
}
|
slime@2
|
37 |
|
slime@2
|
38 |
|
slime@2
|
39 |
unsigned char LDByteReadI2C(unsigned char ControlByte)
|
slime@2
|
40 |
{
|
slime@2
|
41 |
unsigned char data;
|
slime@2
|
42 |
IdleI2C(); // ensure module is idle
|
slime@2
|
43 |
StartI2C(); // initiate START condition
|
slime@2
|
44 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
45 |
WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
|
slime@2
|
46 |
IdleI2C(); // ensure module is idle
|
slime@2
|
47 |
data = ReadI2C();
|
slime@2
|
48 |
IdleI2C(); // ensure module is idle
|
slime@2
|
49 |
NotAckI2C(); // send not ACK condition
|
slime@2
|
50 |
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
|
slime@2
|
51 |
StopI2C(); // send STOP condition
|
slime@2
|
52 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
53 |
return ( data ); // return with no error
|
slime@2
|
54 |
}
|
slime@2
|
55 |
|
slime@2
|
56 |
|
slime@2
|
57 |
|
slime@2
|
58 |
unsigned char LDPageReadI2C( unsigned char ControlByte, unsigned char address, unsigned char *data, unsigned char length )
|
slime@2
|
59 |
{
|
slime@2
|
60 |
IdleI2C(); // ensure module is idle
|
slime@2
|
61 |
StartI2C(); // initiate START condition
|
slime@2
|
62 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
63 |
WriteI2C( ControlByte ); // write 1 byte
|
slime@2
|
64 |
IdleI2C(); // ensure module is idle
|
slime@2
|
65 |
WriteI2C( address ); // WRITE word address to EEPROM
|
slime@2
|
66 |
IdleI2C(); // ensure module is idle
|
slime@2
|
67 |
RestartI2C(); // generate I2C bus restart condition
|
slime@2
|
68 |
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
|
slime@2
|
69 |
WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
|
slime@2
|
70 |
IdleI2C(); // ensure module is idle
|
slime@2
|
71 |
getsI2C( data, length ); // read in multiple bytes
|
slime@2
|
72 |
NotAckI2C(); // send not ACK condition
|
slime@2
|
73 |
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
|
slime@2
|
74 |
StopI2C(); // send STOP condition
|
slime@2
|
75 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
76 |
return ( 0 ); // return with no error
|
slime@2
|
77 |
|
slime@2
|
78 |
}
|
slime@2
|
79 |
|
slime@2
|
80 |
unsigned char LDPageWriteI2C( unsigned char ControlByte, unsigned char LowAdd, unsigned char *wrptr, unsigned char length)
|
slime@2
|
81 |
{
|
slime@2
|
82 |
PageSize = (int)length;
|
slime@2
|
83 |
|
slime@2
|
84 |
IdleI2C(); // ensure module is idle
|
slime@2
|
85 |
StartI2C(); // initiate START condition
|
slime@2
|
86 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
87 |
WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
|
slime@2
|
88 |
IdleI2C(); // ensure module is idle
|
slime@2
|
89 |
WriteI2C( LowAdd ); // write LowAdd byte to EEPROM
|
slime@2
|
90 |
IdleI2C(); // ensure module is idle
|
slime@2
|
91 |
putstringI2C ( wrptr ); // pointer to data for page write
|
slime@2
|
92 |
IdleI2C(); // ensure module is idle
|
slime@2
|
93 |
StopI2C(); // send STOP condition
|
slime@2
|
94 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
95 |
return ( 0 ); // return with no error
|
slime@2
|
96 |
}
|
slime@2
|
97 |
|
slime@2
|
98 |
|
slime@2
|
99 |
|
slime@2
|
100 |
/*
|
slime@2
|
101 |
unsigned char HDByteWriteI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char data )
|
slime@2
|
102 |
{
|
slime@2
|
103 |
IdleI2C(); // ensure module is idle
|
slime@2
|
104 |
StartI2C(); // initiate START condition
|
slime@2
|
105 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
106 |
WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
|
slime@2
|
107 |
IdleI2C(); // ensure module is idle
|
slime@2
|
108 |
WriteI2C( HighAdd ); // write address byte to EEPROM
|
slime@2
|
109 |
IdleI2C(); // ensure module is idle
|
slime@2
|
110 |
WriteI2C( LowAdd ); // write address byte to EEPROM
|
slime@2
|
111 |
IdleI2C(); // ensure module is idle
|
slime@2
|
112 |
WriteI2C ( data ); // Write data byte to EEPROM
|
slime@2
|
113 |
IdleI2C(); // ensure module is idle
|
slime@2
|
114 |
StopI2C(); // send STOP condition
|
slime@2
|
115 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
116 |
while (EEAckPolling(ControlByte)); //Wait for write cycle to complete
|
slime@2
|
117 |
return ( 0 ); // return with no error
|
slime@2
|
118 |
}
|
slime@2
|
119 |
unsigned char HDByteReadI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *data, unsigned char length )
|
slime@2
|
120 |
{
|
slime@2
|
121 |
IdleI2C(); // ensure module is idle
|
slime@2
|
122 |
StartI2C(); // initiate START condition
|
slime@2
|
123 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
124 |
WriteI2C( ControlByte ); // write 1 byte
|
slime@2
|
125 |
IdleI2C(); // ensure module is idle
|
slime@2
|
126 |
WriteI2C( HighAdd ); // WRITE word address to EEPROM
|
slime@2
|
127 |
IdleI2C(); // ensure module is idle
|
slime@2
|
128 |
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
|
slime@2
|
129 |
WriteI2C( LowAdd ); // WRITE word address to EEPROM
|
slime@2
|
130 |
IdleI2C(); // ensure module is idle
|
slime@2
|
131 |
RestartI2C(); // generate I2C bus restart condition
|
slime@2
|
132 |
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
|
slime@2
|
133 |
WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
|
slime@2
|
134 |
IdleI2C(); // ensure module is idle
|
slime@2
|
135 |
getsI2C( data, length ); // read in multiple bytes
|
slime@2
|
136 |
NotAckI2C(); // send not ACK condition
|
slime@2
|
137 |
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
|
slime@2
|
138 |
StopI2C(); // send STOP condition
|
slime@2
|
139 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
140 |
return ( 0 ); // return with no error
|
slime@2
|
141 |
}
|
slime@2
|
142 |
unsigned char HDPageWriteI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *wrptr )
|
slime@2
|
143 |
{
|
slime@2
|
144 |
IdleI2C(); // ensure module is idle
|
slime@2
|
145 |
StartI2C(); // initiate START condition
|
slime@2
|
146 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
147 |
WriteI2C( ControlByte ); // write 1 byte - R/W bit should be 0
|
slime@2
|
148 |
IdleI2C(); // ensure module is idle
|
slime@2
|
149 |
WriteI2C( HighAdd ); // write HighAdd byte to EEPROM
|
slime@2
|
150 |
IdleI2C(); // ensure module is idle
|
slime@2
|
151 |
WriteI2C( LowAdd ); // write LowAdd byte to EEPROM
|
slime@2
|
152 |
IdleI2C(); // ensure module is idle
|
slime@2
|
153 |
putstringI2C ( wrptr ); // pointer to data for page write
|
slime@2
|
154 |
IdleI2C(); // ensure module is idle
|
slime@2
|
155 |
StopI2C(); // send STOP condition
|
slime@2
|
156 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
157 |
return ( 0 ); // return with no error
|
slime@2
|
158 |
}
|
slime@2
|
159 |
unsigned char HDSequentialReadI2C( unsigned char ControlByte, unsigned char HighAdd, unsigned char LowAdd, unsigned char *rdptr, unsigned char length )
|
slime@2
|
160 |
{
|
slime@2
|
161 |
IdleI2C(); // ensure module is idle
|
slime@2
|
162 |
StartI2C(); // initiate START condition
|
slime@2
|
163 |
while ( SSPCON2bits.SEN ); // wait until start condition is over
|
slime@2
|
164 |
WriteI2C( ControlByte ); // write 1 byte
|
slime@2
|
165 |
IdleI2C(); // ensure module is idle
|
slime@2
|
166 |
WriteI2C( HighAdd ); // WRITE word address to EEPROM
|
slime@2
|
167 |
IdleI2C(); // ensure module is idle
|
slime@2
|
168 |
WriteI2C( LowAdd ); // write HighAdd byte to EEPROM
|
slime@2
|
169 |
IdleI2C(); // ensure module is idle
|
slime@2
|
170 |
RestartI2C(); // generate I2C bus restart condition
|
slime@2
|
171 |
while ( SSPCON2bits.RSEN ); // wait until re-start condition is over
|
slime@2
|
172 |
WriteI2C( ControlByte | 0x01 ); // WRITE 1 byte - R/W bit should be 1 for read
|
slime@2
|
173 |
IdleI2C(); // ensure module is idle
|
slime@2
|
174 |
getsI2C( rdptr, length ); // read in multiple bytes
|
slime@2
|
175 |
NotAckI2C(); // send not ACK condition
|
slime@2
|
176 |
while ( SSPCON2bits.ACKEN ); // wait until ACK sequence is over
|
slime@2
|
177 |
StopI2C(); // send STOP condition
|
slime@2
|
178 |
while ( SSPCON2bits.PEN ); // wait until stop condition is over
|
slime@2
|
179 |
return ( 0 ); // return with no error
|
slime@2
|
180 |
}
|
slime@2
|
181 |
*/
|
slime@2
|
182 |
|
slime@2
|
183 |
|
slime@2
|
184 |
/********************************************************************
|
slime@2
|
185 |
* Function Name: putstringI2C *
|
slime@2
|
186 |
* Return Value: error condition status *
|
slime@2
|
187 |
* Parameters: address of write string storage location *
|
slime@2
|
188 |
* Description: This routine writes a string to the I2C bus,*
|
slime@2
|
189 |
* until a null character is reached. If Master*
|
slime@2
|
190 |
* function putcI2C is called. When trans- *
|
slime@2
|
191 |
* mission is complete then test for ack- *
|
slime@2
|
192 |
* nowledge bit. If Slave transmitter wait for *
|
slime@2
|
193 |
* null character or not ACK received from bus *
|
slime@2
|
194 |
* device. *
|
slime@2
|
195 |
********************************************************************/
|
slime@2
|
196 |
|
slime@2
|
197 |
unsigned char putstringI2C( unsigned char *wrptr )
|
slime@2
|
198 |
{
|
slime@2
|
199 |
|
slime@2
|
200 |
unsigned char x;
|
slime@2
|
201 |
for (x = 0; x < PageSize; x++ ) // transmit data until PageSize
|
slime@2
|
202 |
{
|
slime@2
|
203 |
if ( SSPCON1bits.SSPM3 ) // if Master transmitter then execute the following
|
slime@2
|
204 |
{
|
slime@2
|
205 |
if ( putcI2C ( *wrptr ) ) // write 1 byte
|
slime@2
|
206 |
{
|
slime@2
|
207 |
return ( -3 ); // return with write collision error
|
slime@2
|
208 |
}
|
slime@2
|
209 |
IdleI2C(); // test for idle condition
|
slime@2
|
210 |
if ( SSPCON2bits.ACKSTAT ) // test received ack bit state
|
slime@2
|
211 |
{
|
slime@2
|
212 |
return ( -2 ); // bus device responded with NOT ACK
|
slime@2
|
213 |
} // terminateputstringI2C() function
|
slime@2
|
214 |
}
|
slime@2
|
215 |
else // else Slave transmitter
|
slime@2
|
216 |
{
|
slime@2
|
217 |
PIR1bits.SSPIF = 0; // reset SSPIF bit
|
slime@2
|
218 |
SSPBUF = *wrptr; // load SSPBUF with new data
|
slime@2
|
219 |
SSPCON1bits.CKP = 1; // release clock line
|
slime@2
|
220 |
while ( !PIR1bits.SSPIF ); // wait until ninth clock pulse received
|
slime@2
|
221 |
|
slime@2
|
222 |
if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF ) )// if R/W=0 and BF=0, NOT ACK was received
|
slime@2
|
223 |
{
|
slime@2
|
224 |
return ( -2 ); // terminateputstringI2C() function
|
slime@2
|
225 |
}
|
slime@2
|
226 |
}
|
slime@2
|
227 |
wrptr ++; // increment pointer
|
slime@2
|
228 |
} // continue data writes until null character
|
slime@2
|
229 |
return ( 0 );
|
slime@2
|
230 |
}
|
slime@2
|
231 |
|
slime@2
|
232 |
|
slime@2
|
233 |
|
slime@2
|
234 |
|