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