LTlib LaurTec Library  4.0.0 Beta
Open Source C Library for Microchip Microcontrollers based on XC8 Compiler
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
module_I2C.c
Go to the documentation of this file.
1 /*******************************************************************************
2 
3 Autore : Mauro Laurenti
4 Versione : 1.1
5 
6 Created on Date : 02/10/2010
7 Last update : 22/11/2015
8 
9 CopyRight 2006-2015 all rights are reserved
10 
11 ********************************************************
12 SOFTWARE LICENSE AGREEMENT
13 ********************************************************
14 
15 The usage of the supplied software imply the acceptance of the following license.
16 
17 The software supplied herewith by Mauro Laurenti (the Author) is intended for
18 use solely and exclusively on Microchip PIC Microcontroller (registered mark).
19 The software is owned by the Author, and is protected under applicable
20 copyright laws. All rights are reserved.
21 Any use in violation of the foregoing restrictions may subject the
22 user to criminal sanctions under applicable laws, as well as to civil liability
23 for the breach of the terms and conditions of this license.
24 Commercial use is forbidden without a written acknowledgement with the Author.
25 Personal or educational use is allowed if the application containing the
26 following software doesn't aim to commercial use or monetary earning of any kind.
27 
28 THIS SOFTWARE IS PROVIDED IN AN "AS IS" CONDITION. NO WARRANTIES,
29 WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
30 TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
31 PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE AUTHOR SHALL NOT,
32 IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
33 CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
34 
35 *******************************************************************************/
36 
37 #ifdef __XC8
38 #include <xc.h>
39 #endif
40 
41 #include "module_I2C.h"
42 
43 //************************************************************
44 // I2C1_open function implementation
45 //************************************************************
46 
47 void I2C1_open (unsigned char device_type){
48 
49  unsigned char dummy_read;
50 
51  //IO pin initialization
52  I2C1_SDA_LINE_TRIS = PIN_AS_INPUT;
53  I2C1_SCL_LINE_TRIS = PIN_AS_INPUT;
54 
55  //Register initialization (Starting known value)
56  SSPSTAT &= 0x3F;
57  SSPCON1 = 0x00;
58  SSPCON2 = 0x00;
59 
60  //Device definition Master or Slave
61  SSPCON1 |= device_type;
62 
63  //Slew Rate Control set to ON by default
64  SSPSTAT |= I2C_SLEW_ON;
65 
66  //Enable the I2C Module
67  SSPCON1 |= 0b00100000;
68 
69  //clear input buffer
70  dummy_read = I2C1_read_byte ();
71 
72 }
73 
74 #ifdef I2C_MODULE_TYPE_2
75 
76 void I2C2_open (unsigned char device_type){
77 
78  unsigned char dummy_read;
79 
80  //IO pin initialization
81  I2C2_SDA_LINE_TRIS = PIN_AS_INPUT;
82  I2C2_SCL_LINE_TRIS = PIN_AS_INPUT;
83 
84  //Register initialization (Starting known value)
85  SSP2STAT &= 0x3F;
86  SSP2CON1 = 0x00;
87  SSP2CON2 = 0x00;
88 
89  //Device definition Master or Slave
90  SSP2CON1 |= device_type;
91 
92  //Slew Rate Control set to ON by default
93  SSP2STAT |= I2C_SLEW_ON;
94 
95  //Enable the I2C Module
96  SSP2CON1 |= 0b00100000;
97 
98  //clear input buffer
99  dummy_read = I2C2_read_byte ();
100 
101 }
102 #endif
103 
104 //************************************************************
105 // I2C1_baud_rate function implementation
106 //************************************************************
107 void I2C1_baud_rate (unsigned int bus_baud_rate_KHZ){
108 
109  SSPADD = ((I2C_CLOCK /1000)/(4 *bus_baud_rate_KHZ))-1;
110 }
111 
112 #ifdef I2C_MODULE_TYPE_2
113 void I2C2_baud_rate (unsigned int bus_baud_rate_KHZ){
114  SSP2ADD = ((I2C_CLOCK /1000)/(4 *bus_baud_rate_KHZ))-1;
115 }
116 #endif
117 
118 //************************************************************
119 // I2C1_set_slave_address function implementation
120 //************************************************************
121 void I2C1_set_slave_address (unsigned int device_address){
122 
123  //Only one byte address is supported
124  SSPADD = (unsigned char) device_address;
125 }
126 
127 #ifdef I2C_MODULE_TYPE_2
128 void I2C2_set_slave_address (unsigned int device_address){
129  SSP2ADD = (unsigned char) device_address;
130 }
131 #endif
132 
133 
134 //************************************************************
135 // I2C1_wait_bus_IDLE function implementation
136 //************************************************************
137 void I2C1_wait_bus_IDLE (void){
138  while ((SSPCON2 & 0x1F) | (SSPSTATbits.R_W));
139 }
140 
141 
142 #ifdef I2C_MODULE_TYPE_2
143 void I2C2_wait_bus_IDLE (void){
144  while ((SSP2CON2 & 0x1F) | (SSP2STATbits.R_W));
145 }
146 #endif
147 
148 
149 //************************************************************
150 // I2C1_is_bus_IDLE function implementation
151 //************************************************************
152 void I2C1_start_bit (void){
153 
154  SSPCON2bits.SEN=1;
155  //Waits util start bit is in idle
156  while(SSPCON2bits.SEN);
157 }
158 
159 
160 #ifdef I2C_MODULE_TYPE_2
161 void I2C2_start_bit (void){
162  SSP2CON2bits.SEN=1;
163  //Waits util start bit is in idle
164  while(SSP2CON2bits.SEN);
165 }
166 #endif
167 
168 
169 //************************************************************
170 // I2C1_stop_bit function implementation
171 //************************************************************
172 
173 void I2C1_stop_bit (void){
174  SSPCON2bits.PEN=1;
175  while(SSPCON2bits.PEN);
176 }
177 
178 
179 #ifdef I2C_MODULE_TYPE_2
180 void I2C2_stop_bit (void){
181 
182  SSP2CON2bits.PEN=1;
183  while(SSP2CON2bits.PEN);
184 }
185 #endif
186 
187 //************************************************************
188 // I2C1_write_byte function implementation
189 //************************************************************
190 signed char I2C1_write_byte (unsigned char byte_to_send){
191 
192  //Writes the data to the output buffer
193  SSPBUF = byte_to_send;
194 
195  //Check for collision errors
196  if ( SSPCON1bits.WCOL )
197  return ( -1 );
198  else {
199 
200  //slave mode only
201  if( ((SSPCON1&0x0F)!=0x08) && ((SSPCON1&0x0F)!=0x0B) ) {
202 
203  // release clock line
204  SSPCON1bits.CKP = 1;
205 
206  // wait until ninth clock pulse received
207  while ( !PIR1bits.SSPIF );
208 
209  // if R/W=0 and BF=0, NOT ACK was received
210  if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF )){
211  return ( -2 );
212  }
213  else
214  return(0);
215 
216  }
217  else
218 
219  //master mode only
220  if( ((SSPCON1&0x0F)==0x08) || ((SSPCON1&0x0F)==0x0B) ) {
221 
222  // wait until write cycle is complete
223  while( SSPSTATbits.BF );
224 
226 
227  // test for ACK condition received
228  if (SSPCON2bits.ACKSTAT )
229  return ( -2 );
230  else
231  return ( 0 );
232  }
233  }
234 
235  //Unknown Error
236  return ( -3 );
237 }
238 
239 #ifdef I2C_MODULE_TYPE_2
240 signed char I2C2_write_byte (unsigned char byte_to_send){
241 
242  //Writes the data to the output buffer
243  SSP2BUF = byte_to_send;
244 
245  //Check for collision errors
246  if ( SSP2CON1bits.WCOL )
247  return ( -1 );
248  else {
249 
250  //slave mode only
251  if( ((SSP2CON1&0x0F)!=0x08) && ((SSP2CON1&0x0F)!=0x0B) ) {
252  // release clock line
253  SSP2CON1bits.CKP = 1;
254 
255  // wait until ninth clock pulse received
256  while ( !PIR3bits.SSP2IF );
257 
258  // if R/W=0 and BF=0, NOT ACK was received
259  if ( ( !SSP2STATbits.R_W ) && ( !SSP2STATbits.BF )){
260  return ( -2 );
261  }
262  else
263  return(0);
264 
265  }
266  else
267 
268  //master mode only
269  if( ((SSP2CON1&0x0F)==0x08) || ((SSP2CON1&0x0F)==0x0B) ) {
270 
271  // wait until write cycle is complete
272  while( SSP2STATbits.BF );
273 
274  I2C2_wait_bus_IDLE();
275 
276  // test for ACK condition received
277  if ( SSP2CON2bits.ACKSTAT )
278  return ( -2 );
279  else
280  return ( 0 );
281  }
282  }
283 
284  //Unknown Error
285  return ( -3 );
286 }
287 #endif
288 
289 
290 //************************************************************
291 // I2C1_reset_write_collision_flag function implementation
292 //************************************************************
294  SSPCON1bits.WCOL=0;
295 }
296 
297 #ifdef I2C_MODULE_TYPE_2
298 void I2C2_reset_write_collision_flag (void){
299  SSP2CON1bits.WCOL=0;
300 }
301 #endif
302 
303 
304 //************************************************************
305 // I2C1_write_byte_to_external_device function implementation
306 //************************************************************
307 signed char I2C1_write_byte_to_external_device (unsigned char control_byte, unsigned char register_address, unsigned char data){
308 
310  I2C1_start_bit();
311 
312  // test for bus collision
313  if ( PIR2bits.BCLIF ){
314  return ( -1 );
315  }
316  else {
317  // write byte - R/W bit should be 0
318  if ( I2C1_write_byte(control_byte)){
319  I2C1_stop_bit();
320  return (-3);
321  }
322 
323  // test for ACK condition received
324  if ( !SSPCON2bits.ACKSTAT )
325  {
326  if (I2C1_write_byte(register_address)) {
327  I2C1_stop_bit();
328  return ( -3 );
329  }
330  // test for ACK condition received
331  if ( !SSPCON2bits.ACKSTAT ){
332  if (I2C1_write_byte(data)) {
333  I2C1_stop_bit();
334  return ( -3 );
335  }
336  }else {
337  I2C1_stop_bit();
338  return ( -2 );
339  }
340  } else {
341  I2C1_stop_bit();
342  return ( -2 );
343  }
344  }
345 
346  I2C1_stop_bit();
347 
348  // test for bus collision
349  if ( PIR2bits.BCLIF ){
350  return ( -1 );
351  }
352 
353  return ( 0 );
354 }
355 
356 #ifdef I2C_MODULE_TYPE_2
357 signed char I2C2_write_byte_to_external_device (unsigned char control_byte, unsigned char register_address, unsigned char data){
358 
359  I2C2_wait_bus_IDLE();
360  I2C2_start_bit();
361 
362  // test for bus collision
363  if (PIR3bits.BCL2IF){
364  return (-1);
365  }
366  else {
367  // write byte - R/W bit should be 0
368  if ( I2C2_write_byte(control_byte)){
369  I2C2_stop_bit();
370  return (-3);
371  }
372 
373  // test for ACK condition received
374  if (!SSP2CON2bits.ACKSTAT){
375 
376  if (I2C2_write_byte(register_address)) {
377  I2C2_stop_bit();
378  return (-3);
379  }
380 
381  // test for ACK condition received
382  if ( !SSP2CON2bits.ACKSTAT ){
383  if (I2C2_write_byte(data)) {
384  I2C2_stop_bit();
385  return (-3);
386  }
387  }else {
388  I2C2_stop_bit();
389  return (-2);
390  }
391  } else {
392  I2C2_stop_bit();
393  return (-2);
394  }
395  }
396 
397  I2C2_stop_bit();
398 
399  // test for bus collision
400  if (PIR3bits.BCL2IF){
401  return (-1);
402  }
403 
404  return (0);
405 }
406 #endif
407 
408 //************************************************************
409 // I2C1_read_byte_from_external_device function implementation
410 //************************************************************
411 
412 signed char I2C1_read_byte_from_external_device (unsigned char control_byte, unsigned char register_address){
413 
415  I2C1_start_bit();
416 
417  // test for bus collision
418  if (PIR2bits.BCLIF){
419  return (-1);
420  } else {
421  if (I2C1_write_byte(control_byte)) {
422  I2C1_stop_bit();
423  return (-3);
424  }
425 
426  // Check for ACK condition
427  if (!SSPCON2bits.ACKSTAT){
428  // WRITE word address for EEPROM
429  if (I2C1_write_byte(register_address)){
430  I2C1_stop_bit();
431  return (-3);
432  }
433 
434  // Check for ACK condition
435  if (!SSPCON2bits.ACKSTAT) {
436 
438 
439  // test for bus collision
440  if ( PIR2bits.BCLIF ){
441  return (-1);
442  }
443 
444  // write 1 byte - R/W bit should be 1
445  if (I2C1_write_byte(control_byte+1)){
446  I2C1_stop_bit();
447  return (-3);
448  }
449 
450  // Check for ACK condition
451  if (!SSPCON2bits.ACKSTAT ){
452  // enable master for 1 byte reception
453  SSPCON2bits.RCEN = 1;
454  // check that receive sequence is over
455  while ( SSPCON2bits.RCEN );
456 
457  // send ACK condition
459 
460  // send STOP condition
461  I2C1_stop_bit();
462 
463  // test for bus collision
464  if (PIR2bits.BCLIF) {
465  return (-1);
466  }
467  } else {
468  I2C1_stop_bit();
469  return (-2);
470  }
471  } else {
472  I2C1_stop_bit();
473  return (-2);
474  }
475  }
476  else
477  {
478  I2C1_stop_bit();
479  return (-2);
480  }
481  }
482 
483  //If no error occured, the data is returned
484  return ((unsigned char) SSPBUF);
485 }
486 
487 #ifdef I2C_MODULE_TYPE_2
488 signed char I2C2_read_byte_from_external_device (unsigned char control_byte, unsigned char register_address){
489  I2C2_wait_bus_IDLE();
490  I2C2_start_bit();
491 
492  // test for bus collision
493  if (PIR3bits.BCL2IF){
494  return (-1);
495  } else {
496  if (I2C2_write_byte(control_byte)) {
497  I2C2_stop_bit();
498  return (-3);
499  }
500 
501  // Check for ACK condition
502  if (!SSP2CON2bits.ACKSTAT){
503  // WRITE word address for EEPROM
504  if (I2C2_write_byte(register_address)){
505  I2C2_stop_bit();
506  return (-3);
507  }
508 
509  // Check for ACK condition
510  if (!SSP2CON2bits.ACKSTAT) {
511 
512  I2C2_restart_communication();
513 
514  // test for bus collision
515  if (PIR3bits.BCL2IF){
516  return (-1);
517  }
518 
519  // write 1 byte - R/W bit should be 1
520  if (I2C2_write_byte(control_byte+1)){
521  I2C1_stop_bit();
522  return (-3);
523  }
524 
525  // Check for ACK condition
526  if (!SSP2CON2bits.ACKSTAT){
527  // enable master for 1 byte reception
528  SSP2CON2bits.RCEN = 1;
529  // check that receive sequence is over
530  while (SSP2CON2bits.RCEN);
531 
532  // send ACK condition
533  I2C2_negative_ACK();
534 
535  // send STOP condition
536  I2C2_stop_bit();
537 
538  // test for bus collision
539  if (PIR3bits.BCL2IF) {
540  return (-1);
541  }
542  } else {
543  I2C2_stop_bit();
544  return (-2);
545  }
546  } else {
547  I2C2_stop_bit();
548  return (-2);
549  }
550  }
551  else {
552  I2C2_stop_bit();
553  return (-2);
554  }
555  }
556 
557  //If no error occured, the data is returned
558  return ((unsigned char) SSP2BUF);
559 }
560 #endif