LTlib LaurTec Library  4.0.1
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 
136 //************************************************************
137 // I2C1_start_bit function implementation
138 //************************************************************
139 void I2C1_start_bit (void){
140 
141  SSPCON2bits.SEN=1;
142  //Waits util start bit is in idle
143  while(SSPCON2bits.SEN);
144 }
145 
146 
147 #ifdef I2C_MODULE_TYPE_2
148 void I2C2_start_bit (void){
149  SSP2CON2bits.SEN=1;
150  //Waits util start bit is in idle
151  while(SSP2CON2bits.SEN);
152 }
153 #endif
154 
155 
156 //************************************************************
157 // I2C1_stop_bit function implementation
158 //************************************************************
159 
160 void I2C1_stop_bit (void){
161  SSPCON2bits.PEN=1;
162  while(SSPCON2bits.PEN);
163 }
164 
165 
166 #ifdef I2C_MODULE_TYPE_2
167 void I2C2_stop_bit (void){
168 
169  SSP2CON2bits.PEN=1;
170  while(SSP2CON2bits.PEN);
171 }
172 #endif
173 
174 //************************************************************
175 // I2C1_write_byte function implementation
176 //************************************************************
177 signed char I2C1_write_byte (unsigned char byte_to_send){
178 
179  //Writes the data to the output buffer
180  SSPBUF = byte_to_send;
181 
182  //Check for collision errors
183  if ( SSPCON1bits.WCOL )
184  return ( -1 );
185  else {
186 
187  //slave mode only
188  if( ((SSPCON1&0x0F)!=0x08) && ((SSPCON1&0x0F)!=0x0B) ) {
189 
190  // release clock line
191  SSPCON1bits.CKP = 1;
192 
193  // wait until ninth clock pulse received
194  while ( !PIR1bits.SSPIF );
195 
196  // if R/W=0 and BF=0, NOT ACK was received
197  if ( ( !SSPSTATbits.R_W ) && ( !SSPSTATbits.BF )){
198  return ( -2 );
199  }
200  else
201  return(0);
202 
203  }
204  else
205 
206  //master mode only
207  if( ((SSPCON1&0x0F)==0x08) || ((SSPCON1&0x0F)==0x0B) ) {
208 
209  // wait until write cycle is complete
210  while( SSPSTATbits.BF );
211 
213 
214  // test for ACK condition received
215  if (SSPCON2bits.ACKSTAT )
216  return ( -2 );
217  else
218  return ( 0 );
219  }
220  }
221 
222  //Unknown Error
223  return ( -3 );
224 }
225 
226 #ifdef I2C_MODULE_TYPE_2
227 signed char I2C2_write_byte (unsigned char byte_to_send){
228 
229  //Writes the data to the output buffer
230  SSP2BUF = byte_to_send;
231 
232  //Check for collision errors
233  if ( SSP2CON1bits.WCOL )
234  return ( -1 );
235  else {
236 
237  //slave mode only
238  if( ((SSP2CON1&0x0F)!=0x08) && ((SSP2CON1&0x0F)!=0x0B) ) {
239  // release clock line
240  SSP2CON1bits.CKP = 1;
241 
242  // wait until ninth clock pulse received
243  while ( !PIR3bits.SSP2IF );
244 
245  // if R/W=0 and BF=0, NOT ACK was received
246  if ( ( !SSP2STATbits.R_W ) && ( !SSP2STATbits.BF )){
247  return ( -2 );
248  }
249  else
250  return(0);
251 
252  }
253  else
254 
255  //master mode only
256  if( ((SSP2CON1&0x0F)==0x08) || ((SSP2CON1&0x0F)==0x0B) ) {
257 
258  // wait until write cycle is complete
259  while( SSP2STATbits.BF );
260 
261  I2C2_wait_bus_IDLE();
262 
263  // test for ACK condition received
264  if ( SSP2CON2bits.ACKSTAT )
265  return ( -2 );
266  else
267  return ( 0 );
268  }
269  }
270 
271  //Unknown Error
272  return ( -3 );
273 }
274 #endif
275 
276 
277 //************************************************************
278 // I2C1_reset_write_collision_flag function implementation
279 //************************************************************
281  SSPCON1bits.WCOL=0;
282 }
283 
284 #ifdef I2C_MODULE_TYPE_2
285 void I2C2_reset_write_collision_flag (void){
286  SSP2CON1bits.WCOL=0;
287 }
288 #endif
289 
290 
291 //************************************************************
292 // I2C1_write_byte_to_external_device function implementation
293 //************************************************************
294 signed char I2C1_write_byte_to_external_device (unsigned char control_byte, unsigned char register_address, unsigned char data){
295 
297  I2C1_start_bit();
298 
299  // test for bus collision
300  if ( PIR2bits.BCLIF ){
301  return ( -1 );
302  }
303  else {
304  // write byte - R/W bit should be 0
305  if ( I2C1_write_byte(control_byte)){
306  I2C1_stop_bit();
307  return (-3);
308  }
309 
310  // test for ACK condition received
311  if ( !SSPCON2bits.ACKSTAT )
312  {
313  if (I2C1_write_byte(register_address)) {
314  I2C1_stop_bit();
315  return ( -3 );
316  }
317  // test for ACK condition received
318  if ( !SSPCON2bits.ACKSTAT ){
319  if (I2C1_write_byte(data)) {
320  I2C1_stop_bit();
321  return ( -3 );
322  }
323  }else {
324  I2C1_stop_bit();
325  return ( -2 );
326  }
327  } else {
328  I2C1_stop_bit();
329  return ( -2 );
330  }
331  }
332 
333  I2C1_stop_bit();
334 
335  // test for bus collision
336  if ( PIR2bits.BCLIF ){
337  return ( -1 );
338  }
339 
340  return ( 0 );
341 }
342 
343 #ifdef I2C_MODULE_TYPE_2
344 signed char I2C2_write_byte_to_external_device (unsigned char control_byte, unsigned char register_address, unsigned char data){
345 
346  I2C2_wait_bus_IDLE();
347  I2C2_start_bit();
348 
349  // test for bus collision
350  if (PIR3bits.BCL2IF){
351  return (-1);
352  }
353  else {
354  // write byte - R/W bit should be 0
355  if ( I2C2_write_byte(control_byte)){
356  I2C2_stop_bit();
357  return (-3);
358  }
359 
360  // test for ACK condition received
361  if (!SSP2CON2bits.ACKSTAT){
362 
363  if (I2C2_write_byte(register_address)) {
364  I2C2_stop_bit();
365  return (-3);
366  }
367 
368  // test for ACK condition received
369  if ( !SSP2CON2bits.ACKSTAT ){
370  if (I2C2_write_byte(data)) {
371  I2C2_stop_bit();
372  return (-3);
373  }
374  }else {
375  I2C2_stop_bit();
376  return (-2);
377  }
378  } else {
379  I2C2_stop_bit();
380  return (-2);
381  }
382  }
383 
384  I2C2_stop_bit();
385 
386  // test for bus collision
387  if (PIR3bits.BCL2IF){
388  return (-1);
389  }
390 
391  return (0);
392 }
393 #endif
394 
395 //************************************************************
396 // I2C1_read_byte_from_external_device function implementation
397 //************************************************************
398 
399 signed char I2C1_read_byte_from_external_device (unsigned char control_byte, unsigned char register_address){
400 
402  I2C1_start_bit();
403 
404  // test for bus collision
405  if (PIR2bits.BCLIF){
406  return (-1);
407  } else {
408  if (I2C1_write_byte(control_byte)) {
409  I2C1_stop_bit();
410  return (-3);
411  }
412 
413  // Check for ACK condition
414  if (!SSPCON2bits.ACKSTAT){
415  // WRITE word address for EEPROM
416  if (I2C1_write_byte(register_address)){
417  I2C1_stop_bit();
418  return (-3);
419  }
420 
421  // Check for ACK condition
422  if (!SSPCON2bits.ACKSTAT) {
423 
425 
426  // test for bus collision
427  if ( PIR2bits.BCLIF ){
428  return (-1);
429  }
430 
431  // write 1 byte - R/W bit should be 1
432  if (I2C1_write_byte(control_byte+1)){
433  I2C1_stop_bit();
434  return (-3);
435  }
436 
437  // Check for ACK condition
438  if (!SSPCON2bits.ACKSTAT ){
439  // enable master for 1 byte reception
440  SSPCON2bits.RCEN = 1;
441  // check that receive sequence is over
442  while ( SSPCON2bits.RCEN );
443 
444  // send ACK condition
446 
447  // send STOP condition
448  I2C1_stop_bit();
449 
450  // test for bus collision
451  if (PIR2bits.BCLIF) {
452  return (-1);
453  }
454  } else {
455  I2C1_stop_bit();
456  return (-2);
457  }
458  } else {
459  I2C1_stop_bit();
460  return (-2);
461  }
462  }
463  else
464  {
465  I2C1_stop_bit();
466  return (-2);
467  }
468  }
469 
470  //If no error occured, the data is returned
471  return ((unsigned char) SSPBUF);
472 }
473 
474 #ifdef I2C_MODULE_TYPE_2
475 signed char I2C2_read_byte_from_external_device (unsigned char control_byte, unsigned char register_address){
476  I2C2_wait_bus_IDLE();
477  I2C2_start_bit();
478 
479  // test for bus collision
480  if (PIR3bits.BCL2IF){
481  return (-1);
482  } else {
483  if (I2C2_write_byte(control_byte)) {
484  I2C2_stop_bit();
485  return (-3);
486  }
487 
488  // Check for ACK condition
489  if (!SSP2CON2bits.ACKSTAT){
490  // WRITE word address for EEPROM
491  if (I2C2_write_byte(register_address)){
492  I2C2_stop_bit();
493  return (-3);
494  }
495 
496  // Check for ACK condition
497  if (!SSP2CON2bits.ACKSTAT) {
498 
499  I2C2_restart_communication();
500 
501  // test for bus collision
502  if (PIR3bits.BCL2IF){
503  return (-1);
504  }
505 
506  // write 1 byte - R/W bit should be 1
507  if (I2C2_write_byte(control_byte+1)){
508  I2C1_stop_bit();
509  return (-3);
510  }
511 
512  // Check for ACK condition
513  if (!SSP2CON2bits.ACKSTAT){
514  // enable master for 1 byte reception
515  SSP2CON2bits.RCEN = 1;
516  // check that receive sequence is over
517  while (SSP2CON2bits.RCEN);
518 
519  // send ACK condition
520  I2C2_negative_ACK();
521 
522  // send STOP condition
523  I2C2_stop_bit();
524 
525  // test for bus collision
526  if (PIR3bits.BCL2IF) {
527  return (-1);
528  }
529  } else {
530  I2C2_stop_bit();
531  return (-2);
532  }
533  } else {
534  I2C2_stop_bit();
535  return (-2);
536  }
537  }
538  else {
539  I2C2_stop_bit();
540  return (-2);
541  }
542  }
543 
544  //If no error occured, the data is returned
545  return ((unsigned char) SSP2BUF);
546 }
547 #endif